Обычно, если вы решили написать код, чтобы сделать это самостоятельно, вам нужно создать три графических элемента:
- Фон, например темно-синюю область, которая может быть просто холстом или сеткой.сама по себе
- линия искры (то, что вы называете кривой), представляющая собой набор отрезков, построенных из набора точек
- многоугольник, состоящий из идентичного набора точекэто линия искры, плюс отрезок линии, проведенный из последних координат X2, координаты Y2 к нижней части графика, еще один отрезок линии назад от нижнего правого угла к левому нижнему углу и последний отрезок от нижнего левого до самогопервые координаты X1, Y1.Этот многоугольник будет добавлен к холсту перед линией искры и получит заливку, отличную от фона.
Обновив его с помощью некоторого примера кода.Предполагая, что у вас есть список необработанных значений Y (и я извиняюсь за то, что не успел опубликовать более полный пример):
// Declare a Polyline for the spark line
Polyline sparkLine = new Polyline();
// Get style from the XAML user control resources
sparkLine.Style = (Style)TryFindResource("graphLine");
// Declare a polygon for the background
Polygon backgroundPolygon = new Polygon();
// Get its style
backgroundPolygon.Style = (Style)TryFindResource("graphBackground");
// PointCollection for the graph
PointCollection graphPointsCollection = new PointCollection();
// The X value for each point just gets advanced by a uniform amount for each
// Y value on the graph, in this case by an int called gridUnit, which was defined elsewhere
int currentX = 0;
// Get the range covering the min and max graph bounds
decimal graphValRange = maxGraphVal - minGraphVal;
// Traverse the numeric values in a list, create points and add them to the PointCollection
foreach (decimal graphVal in graphValues)
{
// Calculate the Y2 value as a percentage
decimal graphY2Val = (graphVal - minGraphVal) / graphValRange;
// Then apply that percentage to the overall graph height and that will be our Y2 value.
// NOTE: Since Y values are inverse, we subtract it from the graph height to render it correctly
double graphY2ValDouble = Convert.ToDouble(graphHeight - (graphY2Val * graphHeight));
// Create a point from the X and Y values
Point currentPoint = new Point(currentX, graphY2ValDouble);
// Add it to the collection
graphPointsCollection.Add(currentPoint);
// Advance the X value each time (as a multiple of the grid unit)
currentX += gridUnit;
}
// For the background we'll use all the same points but need to clone. Otherwise,
// when some additional points are added they would also end up in the spark line
PointCollection backgroundPointsCollection = graphPointsCollection.Clone();
// Now add additional points to collection to create background polygon.
// These will allow the polygon to be drawn to bottom right
// and back to bottom left, completing the polygon.
Point bottomRightPoint = new Point(currentX - gridUnit, graphHeight);
Point bottomLeftPoint = new Point(0, graphHeight);
backgroundPointsCollection.Add(bottomRightPoint);
backgroundPointsCollection.Add(bottomLeftPoint);
// Now assign the points to the background polygon
backgroundPolygon.Points = backgroundPointsCollection;
// Add the background to the graph first so it doesn't cover the spark line
Graph.Children.Add(backgroundPolygon);
// Finally, assign the graph points to the spark line
sparkLine.Points = graphPointsCollection;
// Add the spark line to the graph
Graph.Children.Add(sparkLine);
Вот XAML для стилей:
<Style TargetType="Polyline" x:Key="graphLine">
<Setter Property="Stroke" Value="#96EF4223" />
<Setter Property="StrokeThickness" Value="2" />
</Style>
<Style TargetType="Polygon" x:Key="graphBackground">
<Setter Property="Fill">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,0.003" StartPoint="0.5,0.994">
<GradientStop Color="#24FAF8CA" Offset="0"/>
<GradientStop Color="#246EBDE9" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
Я использовал такой код для генерации таких графиков:
![sample graph](https://i.stack.imgur.com/pJjxc.png)