How to plot MULTIPLE LineSeries on an OxyPlot chart? - c#

I apologize for asking so many OxyPlot questions, but I seem to be really struggling with using the OxyPlot chart control.
My project is in WPF format so I was originally using a hosted WINFORMS chart and that worked like a charm and did absolutely everything I needed it to until I needed to overlay a WPF element on top of the hosted winform chart. Due to the "AirSpace" issue, I was not able to see the WPF element that I put on top of the hosted chart no matter what I did. That is when I decided to go with OxyPlot, which is giving me quite a few headaches so far.
Here is my origional question! that I asked over at CodePlex. I don't seem to be getting much help over there so I am trying again here.
My question is:
Does anyone know how to plot MULTIPLE LineSeries onto a Plot??
My approach so far:
I am taking a c# List array and adding a new copy of the LineSeries that holds new data to be plotted. My code:
// Function to plot data
private void plotData(double numWeeks, double startingSS)
{
// Initialize new Salt Split class for acess to data variables
Salt_Split_Builder calcSS = new Salt_Split_Builder();
calcSS.compute(numWeeks, startingSS, maxDegSS);
// Create the OxyPlot graph for Salt Split
OxyPlot.Wpf.PlotView plot = new OxyPlot.Wpf.PlotView();
var model = new PlotModel();
// Add Chart Title
model.Title = "Salt Split Degradation";
// Create new Line Series
LineSeries linePoints = new LineSeries() { StrokeThickness = 1, MarkerSize = 1, Title = numWeeks.ToString() + " weeks" };
// Add each point to the new series
foreach (var point in calcSS.saltSplitCurve)
{
DataPoint XYpoint = new DataPoint();
XYpoint = new DataPoint(point.Key, point.Value * 100);
linePoints.Format("%", XYpoint.Y);
linePoints.Points.Add(XYpoint);
}
listPointAray.Add(linePoints);
// Define X-Axis
var Xaxis = new OxyPlot.Axes.LinearAxis();
Xaxis.Maximum = numWeeks;
Xaxis.Minimum = 0;
Xaxis.Position = OxyPlot.Axes.AxisPosition.Bottom;
Xaxis.Title = "Number of Weeks";
model.Axes.Add(Xaxis);
//Define Y-Axis
var Yaxis = new OxyPlot.Axes.LinearAxis();
Yaxis.MajorStep = 15;
Yaxis.Maximum = calcSS.saltSplitCurve.Last().Value * 100;
Yaxis.MaximumPadding = 0;
Yaxis.Minimum = 0;
Yaxis.MinimumPadding = 0;
Yaxis.MinorStep = 5;
Yaxis.Title = "Percent Degradation";
model.Axes.Add(Yaxis);
// Add Each series to the
foreach (var series in listPointAray)
{
LineSeries newpoints = new LineSeries();
newpoints = linePoints;
model.Series.Add(newpoints);
}
// Add the plot to the window
plot.Model = model;
SaltSplitChartGrid.Children.Add(plot);
}
My code works the first time I press my "Graph Data" button, but fails on consecutive attempts with the following error:
The element cannot be added, it already belongs to a Plot Model
The following plot is the type of plot I would like to produce (it worked fine using WinForms Chart control):
I would like a new line with a new color to be plotted each time I run the method.

This is how I've created multi lines on an OxyPlot chart before, the key is creating a set of DataPoints for each series - called circlePoints & linePoints in the following example code, these are then bound to the CircleSeries and LineSeries:
var xAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
StringFormat = Constants.MarketData.DisplayDateFormat,
Title = "End of Day",
IntervalLength = 75,
MinorIntervalType = DateTimeIntervalType.Days,
IntervalType = DateTimeIntervalType.Days,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.None,
};
var yAxis = new LinearAxis
{
Position = AxisPosition.Left,
Title = "Value",
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.None
};
var plot = new PlotModel();
plot.Axes.Add(xAxis);
plot.Axes.Add(yAxis);
var circlePoints = new[]
{
new ScatterPoint(DateTimeAxis.ToDouble(date1), value1),
new ScatterPoint(DateTimeAxis.ToDouble(date2), value2),
};
var circleSeries = new ScatterSeries
{
MarkerSize = 7,
MarkerType = MarkerType.Circle,
ItemsSource = circlePoints
};
var linePoints = new[]
{
new DataPoint(DateTimeAxis.ToDouble(date1), value1),
new DataPoint(DateTimeAxis.ToDouble(date2), value2),
};
var lineSeries = new LineSeries
{
StrokeThickness = 2,
Color = LineDataPointColor,
ItemsSource = linePoints
};
plot.Series.Add(circleSeries);
plot.Series.Add(lineSeries);

Sucess!!!!
AwkwardCoder, thank you for the help, but I realized my mistake was just me having overlooked some things!
Here is the version of the code that works:
// Make a new plotmodel
private PlotModel model = new PlotModel();
// Create the OxyPlot graph for Salt Split
private OxyPlot.Wpf.PlotView plot = new OxyPlot.Wpf.PlotView();
// Function to plot data
private void plotData(double numWeeks, double startingSS)
{
List<LineSeries> listPointAray = new List<LineSeries>();
// Initialize new Salt Split class for acess to data variables
Salt_Split_Builder calcSS = new Salt_Split_Builder();
calcSS.compute(numWeeks, startingSS, maxDegSS);
// Create new Line Series
LineSeries linePoints = new LineSeries()
{ StrokeThickness = 1, MarkerSize = 1, Title = numWeeks.ToString() + " weeks" };
// Add each point to the new series
foreach (var point in calcSS.saltSplitCurve)
{
DataPoint XYpoint = new DataPoint();
XYpoint = new DataPoint(point.Key, point.Value * 100);
linePoints.Format("%", XYpoint.Y);
linePoints.Points.Add(XYpoint);
}
listPointAray.Add(linePoints);
// Add Chart Title
model.Title = "Salt Split Degradation";
// Add Each series to the
foreach (var series in listPointAray)
{
// Define X-Axis
OxyPlot.Axes.LinearAxis Xaxis = new OxyPlot.Axes.LinearAxis();
Xaxis.Maximum = numWeeks;
Xaxis.Minimum = 0;
Xaxis.Position = OxyPlot.Axes.AxisPosition.Bottom;
Xaxis.Title = "Number of Weeks";
model.Axes.Add(Xaxis);
//Define Y-Axis
OxyPlot.Axes.LinearAxis Yaxis = new OxyPlot.Axes.LinearAxis();
Yaxis.MajorStep = 15;
Yaxis.Maximum = calcSS.saltSplitCurve.Last().Value * 100;
Yaxis.MaximumPadding = 0;
Yaxis.Minimum = 0;
Yaxis.MinimumPadding = 0;
Yaxis.MinorStep = 5;
Yaxis.Title = "Percent Degradation";
//Yaxis.StringFormat = "{0.00} %";
model.Axes.Add(Yaxis);
model.Series.Add(series);
}
// Add the plot to the window
plot.Model = model;
plot.InvalidatePlot(true);
SaltSplitChartGrid.Children.Clear();
SaltSplitChartGrid.Children.Add(plot);
}
Here are the multiple things I did wrong:
In my foreach var series loop, I was adding the original series which had already been added and NOT the next var series in the list! (dumb!)
I was creating a new model each time I ran the method. This means that each time the code ran, I was adding a series that already existed in the previous model. (also dumb!)
I was creating a new plot every time and trying to add a model in the new plot that already belonged to a previous plot. (getting dummer..)
The plot was being added to the grid each time I ran the method, so I had to CLEAR the grid's children first before re-adding the same plot.
I was not refreshing the plot.
That was a lot of mistakes, but I worked through it. Hopefully this helps someone in the future. Also, I know I am not using ordinary data binding techniques, but this, at-least, works.
Final result:

Here is how you can achieve a similar result in XAML especially if you are using the MVVM approach.
ViewModel:
public ObservableCollection<DataPoint> DataPointList1 {get;set;}
public ObservableCollection<DataPoint> DataPointList2 {get;set;}
public ObservableCollection<DataPoint> DataPointList3 {get;set;}
public ObservableCollection<DataPoint> DataPointList4 {get;set;}
Using a for loop like below populates DataPointList1 to DataPointList4 with the appropriate datasets.
for (int i = 0; i < dataList.Count; i++)
{
DataPointList1 .Add(new DataPoint{dataList[i].XValue,dataList[i].YValue });
}
XAML:
xmlns:oxy="http://oxyplot.org/wpf"
<oxy:Plot LegendPlacement="Outside" LegendPosition="RightMiddle" Title="Your Chart Title" >
<oxy:Plot.Axes>
<oxy:LinearAxis Title="Your X-axis Title" Position="Bottom" IsZoomEnabled="True" />
<oxy:LinearAxis Title="Your Y-axis Title" Position="Left" IsZoomEnabled="True" />
</oxy:Plot.Axes>
<oxy:Plot.Series>
<oxy:LineSeries Title="Plot1" Color="Black" ItemsSource="{Binding DataPointList1 }"/>
<oxy:LineSeries Title="Plot2" Color="Green" ItemsSource="{Binding DataPointList2 }"/>
<oxy:LineSeries Title="Plot3" Color="Blue" ItemsSource="{Binding DataPointList3 }"/>
<oxy:LineSeries Title="Plot4" Color="Red" ItemsSource="{Binding DataPointList4 }"/>
</oxy:Plot.Series>
</oxy:Plot>

Related

OxyPlot Refresh Issue

I am using a OxyPlot to Real time changing data.
I do this using a Dispatcher Timer in a WPF C# app.
plotTimer.Interval = TimeSpan.FromMilliseconds(1000);
plotTimer.Tick += PlotTimer_Tick;
plotTimer.Start();
SensorPlotModel is a class of primarily the OxyPlot plotmodel with some properties to help keep track of which sensors it is for.
<oxy:PlotView Grid.Row="2" Grid.RowSpan="5" Grid.Column="1" Grid.ColumnSpan="4" Model="{Binding graphPlotModel}" MinHeight="250" MinWidth="1200"/>
The plotModel is then bound in this way to the xaml, where graphPlotModel is a property of the dataContext.
The graph works well when the sensor value is changing. When the value is not changing, the graph seems to be updated with the values, however, the zoom is not changing meaning that the past values can be seen but not the new ones.
I suspect Oxyplot is optimising by not zooming to the new values.
Please let me know if there a problem in the code.
FYI, the graphs are initialised as so:
DateTimeAxis dateAxis = new DateTimeAxis();
dateAxis.Position = AxisPosition.Bottom;
dateAxis.StringFormat = "mm:ss";
dateAxis.MajorGridlineStyle = LineStyle.Solid;
dateAxis.MinorGridlineStyle = LineStyle.Dot;
dateAxis.MinimumMajorStep = 1;
dateAxis.IntervalType = DateTimeIntervalType.Minutes;
//dateAxis.MaximumRange = 10;
//dateAxis.IntervalLength = 5;
plotModel.Axes.Add(dateAxis);
LinearAxis valueAxis = new LinearAxis();
valueAxis.Position = AxisPosition.Left;
valueAxis.StartPosition = 0;
valueAxis.MajorGridlineStyle = LineStyle.Solid;
valueAxis.MinorGridlineStyle = LineStyle.Dot;
valueAxis.Maximum = max;
valueAxis.Minimum = min;
plotModel.Axes.Add(valueAxis);
I hope I understand your question here correctly. You could re-adjust the Axis.Minimum and Axis.Maximum as the new data comes in. For example,
var series = SensorPlotModel.Series.OfType<LineSeries>().First();
var dateTimeAxis = SensorPlotModel.Axes.OfType<DateTimeAxis>().First();
// set Initial axis Range
if (!series.Points.Any())
{
dateTimeAxis.Minimum = DateTimeAxis.ToDouble(DateTime.Now);
dateTimeAxis.Maximum = DateTimeAxis.ToDouble(DateTime.Now.AddSeconds(MaxSecondsToShow));
}
foreach (var newItem in newItems)
{
if(newItem is SensorData sensorData)
{
series.Points.Add(new DataPoint(DateTimeAxis.ToDouble(sensorData.TimeStamp), sensorData.Data));
}
}
// Reset the axis range when axis is out of range
if (DateTimeAxis.ToDouble(DateTime.Now) > dateTimeAxis.Maximum)
{
dateTimeAxis.Minimum = DateTimeAxis.ToDouble(DateTime.Now.AddSeconds(-1 * MaxSecondsToShow));
dateTimeAxis.Maximum = DateTimeAxis.ToDouble(DateTime.Now);
dateTimeAxis.Reset();
}
SensorPlotModel.InvalidatePlot(true);
NotifyOfPropertyChange(nameof(SensorPlotModel));

How can I remove line shadows on Live Chart line chart?

I created a line chart using a live chart. But I cannot eliminate the shadows (shaded areas in the image) under these lines.
LineSeries yeni = new LineSeries();
yeni.PointGeometrySize = 20;
yeni.LineSmoothness = 0;
// yeni.BitmapEffect.
// yeni.PointForeground = System.Windows.Media.Brushes.Transparent;
yeni.Title = kisiler[i].ToString();
yeni.Values = new ChartValues<double>(allValues);
cartesianChart1.Series.Add(yeni);
This way I solved the problem:
yeni.Fill = System.Windows.Media.Brushes.Transparent;

How Do I Get The Scale of The Secondary Axis to be Based on My Series Values?

I'm using System.Web.UI.DataVisualization. Charting to create charts in MVC.
I have a chart displaying values in a StackedColumn100 SeriesChartType with the corresponding y-axis values on the primary y-axis on the left side.
Since it is a 100% stacked column series, the primary y-axis is scaled from 0 to 100.
I have then added a secondary series in the form of a Line SeriesChartType tied to a secondary axis (on the right side). I would like this axis to adjust its scale based on the values in the series but it doesn't. No matter what the highest value of this series is, the secondary y-axis also has a scale between 0 to 100.
If I manually set the maximum value for the secondary y-axis the following way:
chart.ChartAreas[0].AxisY2.Maximum = 20;. It works but I don't want to do that since the maximum value can differ greatly based on the search criteria used.
I have really tried to find a solution for this but I can't. According to the documentation and samples it seems that the scale should be based on the series values but I don't get it to work that way. Any help would be greatly appreciated!
Below is a stand alone test function that recreates the problem. I call the function from my view with the following line:
<p><img src="#Url.Action("CreateChart_TestSecondaryAxis")" /> </p>
public FileResult CreateChart_TestSecondaryAxis()
{
System.Web.UI.DataVisualization.Charting.Chart chart = new System.Web.UI.DataVisualization.Charting.Chart();
chart.Width = 800;
chart.Height = 400;
chart.BackColor = Color.FromArgb(211, 223, 240);
chart.BorderlineDashStyle = ChartDashStyle.Solid;
chart.BackSecondaryColor = Color.White;
chart.BackGradientStyle = GradientStyle.TopBottom;
chart.BorderlineWidth = 1;
chart.Palette = ChartColorPalette.BrightPastel;
chart.BorderlineColor = Color.FromArgb(26, 59, 105);
chart.RenderType = RenderType.BinaryStreaming;
chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
chart.AntiAliasing = AntiAliasingStyles.All;
chart.TextAntiAliasingQuality = TextAntiAliasingQuality.Normal;
ChartArea chartArea = new ChartArea();
chartArea.Name = "TestSecondaryAxis";
chartArea.BackColor = Color.Transparent;
chartArea.AxisX.IsLabelAutoFit = false;
chartArea.AxisY.IsLabelAutoFit = false;
chartArea.AxisX.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.Title = "Airport";
chartArea.AxisY.Title = "LandingConf";
chartArea.AxisY.TextOrientation = TextOrientation.Rotated270;
chartArea.AxisX.LabelStyle.IsEndLabelVisible = true;
chart.ChartAreas.Add(chartArea);
Series seriesPrimaryAxisConf3 = new Series();
seriesPrimaryAxisConf3.Name = "Conf 3";
seriesPrimaryAxisConf3.IsValueShownAsLabel = false;
seriesPrimaryAxisConf3.Color = Color.Blue;
seriesPrimaryAxisConf3.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConf3.BorderWidth = 2;
seriesPrimaryAxisConf3.ChartArea = "TestSecondaryAxis";
DataPoint point;
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesPrimaryAxisConf3.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConf3);
Series seriesPrimaryAxisConfFull = new Series();
seriesPrimaryAxisConfFull.Name = "Conf Full";
seriesPrimaryAxisConfFull.IsValueShownAsLabel = false;
seriesPrimaryAxisConfFull.Color = Color.Red;
seriesPrimaryAxisConfFull.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConfFull.BorderWidth = 2;
seriesPrimaryAxisConfFull.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { 11-i };
seriesPrimaryAxisConfFull.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConfFull);
Series seriesSecondaryAxisNoOfFlights = new Series();
seriesSecondaryAxisNoOfFlights.Name = "NoOfFLights";
seriesSecondaryAxisNoOfFlights.IsValueShownAsLabel = false;
seriesSecondaryAxisNoOfFlights.Color = Color.Red;
seriesSecondaryAxisNoOfFlights.ChartType = SeriesChartType.Line;
seriesSecondaryAxisNoOfFlights.BorderWidth = 2;
seriesSecondaryAxisNoOfFlights.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesSecondaryAxisNoOfFlights.Points.Add(point);
}
chart.Series.Add(seriesSecondaryAxisNoOfFlights);
chart.Series["NoOfFLights"].YAxisType = AxisType.Secondary;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.LineColor = Color.Transparent;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorGrid.Enabled = false;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorTickMark.Enabled = false;
MemoryStream ms = new MemoryStream();
chart.SaveImage(ms);
return File(ms.GetBuffer(), #"image/png");
}
MSChart is a nice control but unfortunately Microsoft has always failed to properly document it.
And with the latest changes at MSDN things have gone from bad to worse, so I can't actually point to the rules that go for the various ChartTypes.
In your case I deduct this (rather wacky) rule:
To attach a non 100%-series to an indepently scaled secondary y-axis
it must be the first series but the stacked series still must be added
first.
So, if you want to get a result like this:
..you need to adapt the code. Here are the changes and additions needed..:
First we have to insert the line series at the front but do that after the stack100 series have beeen added..:
chart.Series.Insert(0, seriesSecondaryAxisNoOfFlights); // instead of adding it
Next we need to owner-draw the line as it would get burried under the columns otherwise.
Code the PostPaint event like this:
private void Chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Chart chart = sender as Chart; //*
Series s = chart.Series[0]; // make sure to pick the right one!
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY2; // !!
var pts = s.Points.Select(x =>
new PointF((float)ax.ValueToPixelPosition(x.XValue),
(float)ay.ValueToPixelPosition(x.YValues[0])));
using (Pen pen = new Pen(s.Color, s.BorderWidth))
e.ChartGraphics.Graphics.DrawLines(pen, pts.ToArray());
}
For this to work the series need valid x-values. So add this line:
point.XValue = i; // set both x and y-values!
I also added a few nudges to the axis positioning:
ChartArea ca = chart.ChartAreas["TestSecondaryAxis"];
ca.AxisY.Maximum = 100;
ca.AxisX.Minimum = 0.5;
ca.AxisX.IntervalOffset = 0.5;

Dynamically creating charts

I am trying to dynamically create a chart for each drive in the computer, inside a form.
Each chart should be a pie chart that contains the amount of free space (colored green) and used space(colored red) in GBs.
But when I run the following code the only thing I see is blank rectangles with the titles of "C:\", "D:\" and so on.
Here is the code :
public static void DrawCharts()
{
Chart[] charts = new Chart[DriveInfo.GetDrives().Length];
DriveInfo[] drives = DriveInfo.GetDrives();
for (int i = 0; i < drives.Length; i++)
{
charts[i] = new Chart();
charts[i].Palette = ChartColorPalette.BrightPastel;
charts[i].Titles.Add(drives[i].Name);
charts[i].Series.Add("Storage");
charts[i].Series[0].ChartType = SeriesChartType.Pie;
charts[i].Location = new System.Drawing.Point(20 + i * 231, 30);
charts[i].Size = new System.Drawing.Size(230, 300);
DataPoint d = new DataPoint();
d.XValue = 1;
double[] p = { (double)drives[i].TotalFreeSpace / 1000000000 };
d.YValues = p;
d.Color = System.Drawing.Color.YellowGreen;
d.Label = "Free Space";
charts[i].Series[0].Points.Add(d);
d.Label = "Used Space";
d.XValue = 2;
double[] a = { (double)((drives[i].TotalSize - drives[i].TotalFreeSpace) / 1000000000) };
d.YValues = a;
d.Color = System.Drawing.Color.Red;
charts[i].Series[0].Points.Add(d);
Form1.tabs.TabPages[1].Controls.Add(charts[i]);
charts[i].Invalidate();
}
}
Thanks.
You are almost there.
But the most basic thing you need to add to a dynamically created chart..:
charts[i] = new Chart();
..is a ChartArea:
charts[i].ChartAreas.Add("CA1"); // pick your name!
Without it no Series can display..
Use it to style the axis with TickMarks, GridLines or Labels or to set Minima and Maxima and Intervals. Well, at least for most other ChartTypes; Pies don't need any of this anyway..
Note that you can have several ChartAreas in one Chart.
Also note that it still will display nothing until at least one Series has at least one DataPoint..

Separate Legends for Multiple ChartAreas in Single Chart

I cannot seem to get my individual subcharts (contained within my single chart object) to host individual legends for their respective data series. I would like to know if this is possible and, if so, what I can adjust in my code to achieve this effect.
Thanks for your help
Code is as follows:
chart_MyChart.Legends.Clear();
ChartArea chartArea_MyData = new ChartArea("My Data");
ChartArea chartArea_YourData = new ChartArea("Your Data");
ChartArea chartArea_OtherData = new ChartArea("Other Data");
chart_MyChart.ChartAreas.Clear();
chart_MyChart.ChartAreas.Add(chartArea_MyData);
chart_MyChart.ChartAreas.Add(chartArea_YourData);
chart_MyChart.ChartAreas.Add(chartArea_OtherData);
/* Chart Area: My Data */
Series series01 = this.chart_MyChart.Series.Add("My first series");
series01.ChartArea = chartArea_MyData.Name;
Series series02 = this.chart_MyChart.Series.Add("My second series");
series02.ChartArea = chartArea_MyData.Name;
Legend legend01 = new Legend(series01.Name);
Legend legend02 = new Legend(series02.Name);
legend01.DockedToChartArea = chartArea_MyData.Name;
legend02.DockedToChartArea = chartArea_MyData.Name;
chart_MyChart.Legends.Add(legend01);
chart_MyChart.Legends.Add(legend02);
/* Chart Area: Your Data */
Series series03 = this.chart_MyChart.Series.Add("Your first series");
series03.ChartArea = chartArea_YourData.Name;
Series series04 = this.chart_MyChart.Series.Add("Your second series");
series04.ChartArea = chartArea_YourData.Name;
Legend legend03 = new Legend(series03.Name);
Legend legend04 = new Legend(series04.Name);
legend03.DockedToChartArea = chartArea_YourData.Name;
legend04.DockedToChartArea = chartArea_YourData.Name;
chart_MyChart.Legends.Add(legend03);
chart_MyChart.Legends.Add(legend04);
/* Chart Area: Other Data */
Series series05 = this.chart_MyChart.Series.Add("Other series");
series05.ChartArea = chartArea_OtherData.Name;
Legend legend05 = new Legend(series05.Name);
legend05.DockedToChartArea = chartArea_OtherData.Name;
chart_MyChart.Legends.Add(legend05);
foreach(Legend legend in chart_MyChart.Legends)
{
legend.IsDockedInsideChartArea = true;
}
foreach(widget myWidget in some.widget)
{
series01.Points.AddXY(widget.timeStamp, widget.data1);
series02.Points.AddXY(widget.timeStamp, widget.data2);
series03.Points.AddXY(widget.timeStamp, widget.data3);
series04.Points.AddXY(widget.timeStamp, widget.data4);
series05.Points.AddXY(widget.timeStamp, widget.data5);
}
At first glance you seem to be missing the association between the series and the Legend this is from the WebSamples project that you can download here, it really helps to see a full source examples.
In the MultiLegends section, the code looks like this:
// Add a second legend
Legend secondLegend = new Legend("Second");
secondLegend.BackColor = Color.FromArgb(((System.Byte)(220)), ((System.Byte)(255)), ((System.Byte)(255)), ((System.Byte)(255)));
secondLegend.BorderColor = Color.Gray;
secondLegend.Font = this.Chart1.Legends["Default"].Font;
this.Chart1.Legends.Add(secondLegend);
// Associate Series 2 with the second legend
this.Chart1.Series["Series 2"].Legend = "Second";
The only thing that I didn't see in your code is that last line of association.

Categories

Resources