更新20260613
This commit is contained in:
@@ -22,6 +22,7 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
private const double SensorMaxTorque = 100;
|
||||
private const double MinimumTorqueRange = 0.1;
|
||||
private const double MinimumSpeedRange = 1;
|
||||
private const double TorqueTrendBinSize = 0.1;
|
||||
|
||||
private bool _isManualView;
|
||||
private double _viewMinTorque = SensorMinTorque;
|
||||
@@ -135,10 +136,15 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
var points = samples
|
||||
.Select(sample => ToPlotPoint(sample, plot, minTorque, maxTorque, minSpeed, maxSpeed))
|
||||
.ToList();
|
||||
List<TorqueTrendPoint> trendPoints = BuildTrendPoints(samples);
|
||||
|
||||
drawingContext.PushClip(new RectangleGeometry(plot));
|
||||
DrawTrajectory(drawingContext, points);
|
||||
DrawSamplePoints(drawingContext, points);
|
||||
DrawTrendLine(
|
||||
drawingContext,
|
||||
trendPoints
|
||||
.Select(point => ToPlotPoint(point.Torque, point.Speed, plot, minTorque, maxTorque, minSpeed, maxSpeed))
|
||||
.ToList());
|
||||
DrawCurrentPoint(drawingContext, points[^1]);
|
||||
drawingContext.Pop();
|
||||
|
||||
@@ -149,6 +155,16 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
12,
|
||||
Color.FromRgb(15, 118, 110),
|
||||
new Point(plot.Left + 6, plot.Top + 5));
|
||||
DrawLegend(drawingContext, plot, trendPoints.Count >= 2);
|
||||
if (trendPoints.Count < 2)
|
||||
{
|
||||
DrawText(
|
||||
drawingContext,
|
||||
"扭矩变化小于传感器精度,暂无有效趋势线",
|
||||
11,
|
||||
Color.FromRgb(180, 83, 9),
|
||||
new Point(plot.Left + 6, plot.Bottom - 38));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnMouseWheel(MouseWheelEventArgs e)
|
||||
@@ -297,27 +313,58 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
private static void DrawTrajectory(DrawingContext drawingContext, IReadOnlyList<Point> points)
|
||||
private static Point ToPlotPoint(
|
||||
double torque,
|
||||
double speed,
|
||||
Rect plot,
|
||||
double minTorque,
|
||||
double maxTorque,
|
||||
double minSpeed,
|
||||
double maxSpeed)
|
||||
{
|
||||
double x = plot.Left + plot.Width * (torque - minTorque) / (maxTorque - minTorque);
|
||||
double y = plot.Bottom - (speed - minSpeed) / (maxSpeed - minSpeed) * plot.Height;
|
||||
return new Point(x, y);
|
||||
}
|
||||
|
||||
private static List<TorqueTrendPoint> BuildTrendPoints(IReadOnlyList<TorqueSamplePayload> samples)
|
||||
{
|
||||
return samples
|
||||
.Where(sample => sample.TorqueMilliNewtonMeters >= SensorMinTorque
|
||||
&& sample.TorqueMilliNewtonMeters <= SensorMaxTorque)
|
||||
.GroupBy(sample => Math.Floor(sample.TorqueMilliNewtonMeters / TorqueTrendBinSize))
|
||||
.Select(group => new TorqueTrendPoint(
|
||||
group.Average(sample => sample.TorqueMilliNewtonMeters),
|
||||
group.Average(sample => sample.SpeedRpm)))
|
||||
.OrderBy(point => point.Torque)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
private static void DrawTrendLine(DrawingContext drawingContext, IReadOnlyList<Point> points)
|
||||
{
|
||||
if (points.Count < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var geometry = new StreamGeometry();
|
||||
using (StreamGeometryContext context = geometry.Open())
|
||||
{
|
||||
for (int i = 0; i < points.Count; i++)
|
||||
context.BeginFigure(points[0], false, false);
|
||||
for (int i = 1; i < points.Count; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
context.BeginFigure(points[i], false, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.LineTo(points[i], true, false);
|
||||
}
|
||||
Point previous = points[i - 1];
|
||||
Point current = points[i];
|
||||
double deltaX = current.X - previous.X;
|
||||
var control1 = new Point(previous.X + deltaX / 3, previous.Y);
|
||||
var control2 = new Point(current.X - deltaX / 3, current.Y);
|
||||
context.BezierTo(control1, control2, current, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
geometry.Freeze();
|
||||
var lineBrush = new SolidColorBrush(Color.FromArgb(85, 29, 78, 216));
|
||||
drawingContext.DrawGeometry(null, new Pen(lineBrush, 1.2), geometry);
|
||||
var lineBrush = new SolidColorBrush(Color.FromRgb(15, 118, 110));
|
||||
drawingContext.DrawGeometry(null, new Pen(lineBrush, 2.4), geometry);
|
||||
}
|
||||
|
||||
private static void DrawSamplePoints(DrawingContext drawingContext, IReadOnlyList<Point> points)
|
||||
@@ -344,6 +391,23 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
drawingContext.DrawEllipse(brush, new Pen(Brushes.White, 1.5), point, 5, 5);
|
||||
}
|
||||
|
||||
private void DrawLegend(DrawingContext drawingContext, Rect plot, bool hasTrend)
|
||||
{
|
||||
double y = plot.Bottom + 5;
|
||||
var sampleBrush = new SolidColorBrush(Color.FromArgb(175, 29, 78, 216));
|
||||
drawingContext.DrawEllipse(sampleBrush, null, new Point(plot.Left + 116, y + 7), 2.5, 2.5);
|
||||
DrawText(drawingContext, "原始采样点", 10, Color.FromRgb(82, 97, 111), new Point(plot.Left + 122, y));
|
||||
|
||||
if (!hasTrend)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var trendPen = new Pen(new SolidColorBrush(Color.FromRgb(15, 118, 110)), 2.4);
|
||||
drawingContext.DrawLine(trendPen, new Point(plot.Left + 194, y + 7), new Point(plot.Left + 214, y + 7));
|
||||
DrawText(drawingContext, "显示趋势线", 10, Color.FromRgb(82, 97, 111), new Point(plot.Left + 220, y));
|
||||
}
|
||||
|
||||
private void DrawAxisLabels(
|
||||
DrawingContext drawingContext,
|
||||
Rect plot,
|
||||
@@ -485,4 +549,6 @@ public sealed class TorqueTrendControl : FrameworkElement
|
||||
|
||||
drawingContext.DrawText(formattedText, origin);
|
||||
}
|
||||
|
||||
private readonly record struct TorqueTrendPoint(double Torque, double Speed);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user