How do I implement charts in WPF?

Solution
Using the template on this web site - stackoverflow.com/questions/33756255/create-a-math-plot-in-c-sharp-xam

.xaml

C#:
<Canvas x:Name="gCanvasPlot0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,0,0,0"
Width="500"
Height="150" />

.cs

C#:
//------------------------------
private void AddPlot()
{
double dPI = Math.PI;

Polyline poXY = new Polyline {
Stroke = Brushes.Red
};
int iNumOfCycles = 3;
double dDeltaX = 0.01;
int iNumOfPoints0 = (int)(iNumOfCycles / dDeltaX);
for (int ii = 0; ii < iNumOfPoints0; ii++) {
double dX = ii * dDeltaX;
double dY = Math.Sin(2 * dPI * dX);
poXY.Points.Add(CorrespondingPoint(new Point(dX, dY), iNumOfCycles));
}
gCanvasPlot0.Children.Add(poXY);
}//AddPlot...
That demo results in

C#:
pathFigure2    {M10,100L50,100 50,150Q200,200,300,100}  
polyLinePointArray    {System.Windows.Point[2]}
    [0]    {50,100}    System.Windows.Point
    [1]    {50,150}    System.Windows.Point
myPolyLineSegment.Points    {50,100 50,150}    System.Windows.Media.PointCollection
myPathGeometry    {M10,100L50,100 50,150Q200,200,300,100}

Which does not provide enough info to me to have a sequence of xy numbers. Am I missing some details?
 
Last edited by a moderator:
That is the stream example. See the non-stream example above that.
 
Or read the documentation of the PolyLineSegment.
 
Specifically PolyLineSegment.Points:
Definition
Gets or sets the collection of Point structures that defines this PolyLineSegment object.
:
Remarks
A line is drawn from the end point of the previous segment or, if this is the first segment, from the StartPoint of the PathFigure to the first point in this collection. Lines are then drawn between each subsequent point specified in this collection.
 
Every example I view is a predefined image. Is there an example that uses C# code (not xaml code) to create an xy plot?
 
I suspect that the reason why you are finding just a predefined image is because you are just skimming through instead of actually reading and trying to understand the samples. No, there is not an example that exactly does what you want, but as I pointed out there is an example that will get you 80% of what you need.

Here's the sample code from that link I provided in post #8:
PathGeometry example:
PathGeometry myPathGeometry = new PathGeometry();

// Create a figure.
PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(10,50);
pathFigure1.Segments.Add(
    new BezierSegment(
        new Point(100,0),
        new Point(200,200),
        new Point(300,100),
        true /* IsStroked */ ));
pathFigure1.Segments.Add(
    new LineSegment(
        new Point(400,100),
        true /* IsStroked */ ));
pathFigure1.Segments.Add(
    new ArcSegment(
        new Point(200,100),
        new Size(50,50),
        45,
        true, /* IsLargeArc */
        SweepDirection.Clockwise,
        true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure1);

// Create another figure.
PathFigure pathFigure2 = new PathFigure();
pathFigure2.StartPoint = new Point(10,100);
Point[] polyLinePointArray =
    new Point[]{ new Point(50, 100), new Point(50, 150)};
PolyLineSegment myPolyLineSegment = new PolyLineSegment();
myPolyLineSegment.Points =
    new PointCollection(polyLinePointArray);
pathFigure2.Segments.Add(myPolyLineSegment);
pathFigure2.Segments.Add(
    new QuadraticBezierSegment(
        new Point(200,200),
        new Point(300,100),
        true /* IsStroked */ ));
myPathGeometry.Figures.Add(pathFigure2);

// Display the PathGeometry.
Path myPath = new Path();
myPath.Stroke = Brushes.Black;
myPath.StrokeThickness = 1;
myPath.Data = myPathGeometry;

Notice how a PolyLineSegment is created, populated with points on lines 27-34.

To make the code above work for you. Replace the array on line 30 with an array of your XY points. Delete lines 3-24 and 35-39.
 
Last edited:
The .xaml code (above that .cs code) creates the images. The .cs code does not appear to change anything.

For the .cs code you provided, what is the .xaml code? Thanks!
 
The the .cs code is the programmatic way of build the image. You said you want C# code. Why are you now asking for XAML?
 
Or try looking at the sample code for using StreamGeometry where they draw a triangle, or the sample after it where they compute the points for a regular polygon. In your case, instead of using 3 hard code points, or computed points, you can iterate over your X,Y points.

 
The the .cs code is the programmatic way of build the image. You said you want C# code. Why are you now asking for XAML?
WPF requires .cs code and .xaml code. The initial post was, "Charts" are in the Toolbox in the C# tutorial that uses Forms => www.youtube.com/watch?v=DqQlNoQW00w. I do not see "Charts" in the WPF Toolbox."

To clarify further: Visual Studio 2019 --- Windows Forms App (.NET Framework) C# ... Toolbox => Data => Charts provides the ability to create xy plots.

This does not exist in WPF APP (.NET Framework).

I've found multiple sites that demo a variety of shapes using .xaml and .cs. But none that demo a combo of both for an xy plot (not predefined shapes), where the .xaml defines the location, and the .cs provides the data.

How do I create xy plots with WPF APP (.NET Framework)?
 
Last edited:
WPF requires .cs code and .xaml code.
Actually this is not quite true. It's not a requirement, but it does make things easier to delineate between UI and core logic behavior. The original intent when WPF was designed was that the XAML could be shipped off to a visual designer and they can tweak all they want (including special effects and animations) while the developers could independently work on supplying the logic that feeds the UI. You could write a WPF app that is purely C#.

Building a WPF Application​

A WPF application can be compiled in the following ways:

  • Command-line. The application must contain only code (no XAML) and an application definition file.
from Compile a WPF Application
 
Actually this is not quite true. It's not a requirement, but it does make things easier to delineate between UI and core logic behavior. The original intent when WPF was designed was that the XAML could be shipped off to a visual designer and they can tweak all they want (including special effects and animations) while the developers could independently work on supplying the logic that feeds the UI. You could write a WPF app that is purely C#.


from Compile a WPF Application
Interesting. I'm curious. Do you have code that does this? Not just a snippet, but everything including the .sln?
 
Why would it need a .SLN if it just needs to be compiled with csc.exe?

Anyway, see here:
 
Using the template on this web site - Create a math plot in c# xaml - I created my relevant code

--------------------------------
When I insert code, Preview blocks the display => Security error occurred. Please press back, refresh the page, and try again.
--------------------------------
 
Using the template on this web site - stackoverflow.com/questions/33756255/create-a-math-plot-in-c-sharp-xam

.xaml

C#:
<Canvas x:Name="gCanvasPlot0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,0,0,0"
Width="500"
Height="150" />

.cs

C#:
//------------------------------
private void AddPlot()
{
double dPI = Math.PI;

Polyline poXY = new Polyline {
Stroke = Brushes.Red
};
int iNumOfCycles = 3;
double dDeltaX = 0.01;
int iNumOfPoints0 = (int)(iNumOfCycles / dDeltaX);
for (int ii = 0; ii < iNumOfPoints0; ii++) {
double dX = ii * dDeltaX;
double dY = Math.Sin(2 * dPI * dX);
poXY.Points.Add(CorrespondingPoint(new Point(dX, dY), iNumOfCycles));
}
gCanvasPlot0.Children.Add(poXY);
}//AddPlot
//------------------------------
//------------------------------
private Point CorrespondingPoint(Point pt, int iNumOfCycles)
{
double dXmin = 0;
double dXmax = iNumOfCycles;
double dYmin = -1.1;
double dYmax = 1.1;
double dPlotWidth = dXmax - dXmin;
double dPlotHeight = dYmax - dYmin;

var poResult = new Point {
X = (pt.X - dXmin) * gCanvasPlot0.Width / (dPlotWidth),
Y = gCanvasPlot0.Height - (pt.Y - dYmin) * gCanvasPlot0.Height / (dPlotHeight)
};
return poResult;
}//CorrespondingPoint
//------------------------------

This works.
 
Last edited:
Solution
Back
Top Bottom