Hi,
I want to create a Line Chart having a single line with Y axis data points plotted on that line.
I have attached the image also. Please let me know how to create such a chart (what properties to set) using Ultrachart.
Thanks.
None of our charts will support this out of the box. Scatter chart will be the closest, if you set the x coordinate to be the same for all the points. Or, you can plot a single zero value using a column or a line chart and add the points in manually as custom graphics via the FillSceneGraph event.
Hi Max Rivlin,
Thanks for the quick response.
I tried the Scatter line approach and could achieve the desired chart to some level. But still 2 things remain: 1. On X axis I need a single Date/string label 2. The central connecting line should be full i.e. start from X axis and continue till the top of the chart.
I am also attaching the chart image for the code below:
myInfraChart.ChartType = ChartType.ScatterChart;
XYSeries xySeries = new XYSeries();xySeries.Points.Add(new XYDataPoint(Convert.ToDouble(1), Convert.ToDouble(1), "A", false));xySeries.Points.Add(new XYDataPoint(Convert.ToDouble(1), Convert.ToDouble(2), "A", false));xySeries.Points.Add(new XYDataPoint(Convert.ToDouble(1), Convert.ToDouble(4), "A", false));
myInfraChart.Series.Add(xySeries);myInfraChart.Axis.Y.RangeType = AxisRangeType.Custom;myInfraChart.Axis.Y.RangeMin = 0;myInfraChart.Axis.Y.RangeMax = 5;myInfraChart.Axis.Y.TickmarkStyle = AxisTickStyle.DataInterval;myInfraChart.Axis.Y.TickmarkInterval = 1;myInfraChart.Axis.Y.Visible = true;
myInfraChart.ScatterChart.ConnectWithLines = true;myInfraChart.ScatterChart.Icon = SymbolIcon.Circle;
Please let me know how to proceed further.
What kind of legend would you display with your chart? If you want just one item in the legend, you can simply enable the default legend. It will display one item, because you have one item in your column chart (for the single zero value you initialized the chart with). If you want something different, I'm afraid you will have to either draw a custom legend inside FillSceneGraph or use a separate control (listview, grid, etc) to act as the legend.
Hi Max,
I want all the Y points we will draw in the chart to be there in the legend. I mean all the points we manually plot in the FillSceneGraph event. Will this be possible? I dont want to manually create any control just for showing the chart legend.
Well, you could fallback on the default legend. It's a bit hacky, but at this point any solution to this will be as well. If you intend to show 4 points, you can create a 4 point numeric series to be drawn by the column chart. With the code below and a visible default legend, you will get a legend with 4 set labels, each with their own specified color (note, this code will replace the DataSource assignment of the chart control):ultraChart1.ChartType = ChartType.ColumnChart;NumericSeries series = new NumericSeries();series.Points.Add(new NumericDataPoint(0, "label 1", false));series.Points.Add(new NumericDataPoint(0, "label 2", false));series.Points.Add(new NumericDataPoint(0, "label 3", false));series.Points.Add(new NumericDataPoint(0, "label 4", false));series.Points[0].PE.Fill = Color.Red;series.Points[1].PE.Fill = Color.Blue;series.Points[2].PE.Fill = Color.Green;series.Points[3].PE.Fill = Color.Yellow;ultraChart1.Series.Add(series);
Thanks for the reply. But I want only 1 label on X axis and want legends for all the Y axis points.
So in the below image, I want only "label2" to appear in the middle on X axis. I dont want "label1" and "label3" to appear. And the 3 points on Y axis should appear in the legend with the matching colors.
Ok, you'll have to change a couple of things. Instead of axis labels, you can use a static text label, and you'll also have to adjust the x axis mapping. Here's an example with 4 points:
private void Form1_Load(object sender, EventArgs ev){ ultraChart1.ChartType = ChartType.ColumnChart; ultraChart1.Axis.Y.RangeMin = 0; ultraChart1.Axis.Y.RangeMax = 5; ultraChart1.Axis.Y.RangeType = AxisRangeType.Custom; ultraChart1.Axis.Y.TickmarkStyle = AxisTickStyle.DataInterval; ultraChart1.Axis.Y.TickmarkInterval = 1; ultraChart1.Axis.X.Labels.Visible = false; ultraChart1.Axis.X.Labels.SeriesLabels.Visible = false; ultraChart1.Axis.X.Labels.SeriesLabels.Visible = false; ultraChart1.Axis.X.Labels.Orientation = TextOrientation.Horizontal; ultraChart1.ColorModel.AlphaLevel = 255; ultraChart1.Axis.X.Extent = 30;
NumericSeries series = new NumericSeries(); series.Points.Add(new NumericDataPoint(0, "label 1", false)); series.Points.Add(new NumericDataPoint(0, "label 2", false)); series.Points.Add(new NumericDataPoint(0, "label 3", false)); series.Points.Add(new NumericDataPoint(0, "label 4", false)); series.Points[0].PE.Fill = Color.Red; series.Points[1].PE.Fill = Color.Blue; series.Points[2].PE.Fill = Color.Green; series.Points[3].PE.Fill = Color.Yellow; ultraChart1.Series.Add(series);
ultraChart1.Legend.Location = LegendLocation.Right; ultraChart1.Legend.Visible = true;}
private void ultraChart1_FillSceneGraph(object sender, FillSceneGraphEventArgs e){ if (e.Grid.Count == 0) return; IAdvanceAxis xAxis = (IAdvanceAxis)e.Grid["X"]; IAdvanceAxis yAxis = (IAdvanceAxis)e.Grid["Y"];
Line line = new Line(); line.p1 = new Point((int)xAxis.Map(2), (int)yAxis.MapMinimum); line.p2 = new Point((int)xAxis.Map(2), (int)yAxis.MapMaximum); line.PE.Stroke = Color.Gray; line.PE.StrokeWidth = 2; e.SceneGraph.Add(line);
Symbol s = new Symbol(); s.PE.Fill = Color.Red; s.icon = SymbolIcon.Circle; s.iconSize = SymbolIconSize.Large; s.point = new Point((int)xAxis.Map(2), (int)yAxis.Map(1)); e.SceneGraph.Add(s);
s = new Symbol(); s.PE.Fill = Color.Green; s.icon = SymbolIcon.Circle; s.iconSize = SymbolIconSize.Large; s.point = new Point((int)xAxis.Map(2), (int)yAxis.Map(2)); e.SceneGraph.Add(s);
s = new Symbol(); s.PE.Fill = Color.Blue; s.icon = SymbolIcon.Circle; s.iconSize = SymbolIconSize.Large; s.point = new Point((int)xAxis.Map(2), (int)yAxis.Map(3)); e.SceneGraph.Add(s);
s = new Symbol(); s.PE.Fill = Color.Yellow; s.icon = SymbolIcon.Circle; s.iconSize = SymbolIconSize.Large; s.point = new Point((int)xAxis.Map(2), (int)yAxis.Map(4)); e.SceneGraph.Add(s);
Text label = new Text(); string text = "my label"; label.SetTextString(text); SizeF labelSize = Platform.GetStringSizePixels(text, label.labelStyle.Font); label.bounds = new Rectangle( (int)(xAxis.Map(2) - labelSize.Width/2), (int)(yAxis.MapMinimum + labelSize.Height), (int)labelSize.Width, (int)labelSize.Height);
e.SceneGraph.Add(label);}
You might be interested to know that I could create the above chart including its legend using Scatter chart only. And the best part is that I dont even had to use the FillSceneGrapth event. And the calculations to manipulate the legend was also minimal.
Thanks a lot for the help.
Regards.
Your chart is probably set to use a random color model, which is something you can check in the designer by checking chart.ColorModels.ModelStyle. In any case, I forgot a few lines of code that make the points use the 4 specified colors (the element type was set to None by default):series.Points[0].PE.ElementType = PaintElementType.SolidFill;series.Points[1].PE.ElementType = PaintElementType.SolidFill;series.Points[2].PE.ElementType = PaintElementType.SolidFill;series.Points[3].PE.ElementType = PaintElementType.SolidFill;series.Points[0].PE.Fill = Color.Red;series.Points[1].PE.Fill = Color.Blue;series.Points[2].PE.Fill = Color.Green;series.Points[3].PE.Fill = Color.Yellow;
Regarding saving to XML, things you add in the FillSceneGraph event will not be saved, as they are not properties of the chart. And yes, complex data model will further complicate the calculation you will have to perform to get this type of chart.
Thanks a lot for quickly coming up with these code samples. But I am sorry that I am not still getting the correct legend. The colors in the legend change on each run and do not map to the Y axis points.
Also, going by this strategy I will have to do my calculations correctly when I will have to plot more than 1 line and having variable points. Also will I be able to export/import my chart to xml file in this case?
Thanks a lot.