Hello everyone,
We are currently struggling to implement a rather complex charting solution. We tried to base ourselves on examples we've found here, as well as examples for the regular Winforms chart. The challenge comes from a combination of charts, a dynamic datasource that has changing characteristics and the fact that we allow the user to make changes to the visual appearance of the chart and the selection of data. In all honesty we're a bit inexperienced in using the datavisualisation controls. We're hoping you could provide us with some help on getting this off the ground. If you could point us to some examples, or advise us on how to proceed, we'd appreciate it greatly :)
There are a couple requirements that we need to follow: - our datasource is a dataset, the columns in its datatables vary and we have no way of knowing in advance how they will be structured, in addition the user will make a selection of columns to display data for - Generically speaking, we have a label column and a number of value columns per row. The different values columns have hugely divergent ranges so they would need to be plotted on different Y-axes - The user will select a chart type at runtime, either columns or lines chart, or combinations of the two
The biggest challenge at this point seems to be the multiple Y-axes and switching between chart types.
Hello Sidhume,
There is a really good blog post about the UltraChart that you might want to take a look at. Check that out and then let me know if you still have any questions.
Hello Kim,
What I was just looking for the combination of a Column and Line chart where half y axis is used. I must be dynamic, because I never know what type of chart the user will choose and over how many signals it will go. When I try the example, the result is not correct. It allows the Series F not see. This is a part of my code used.
Thanks in advance.
Dim myLegend As New CompositeLegend() Dim myChartArea As New ChartArea() Dim axisY As New AxisItem()
Sub CreateChart()
Me.UltraChart1.ChartType = ChartType.Composite myChartArea = Me.UltraChart1.CompositeChart.ChartAreas(0) Me.UltraChart1.CompositeChart.ChartAreas.Add(myChartArea)
'Line chart '*************************************************************************** Dim axisX2 As New AxisItem() axisX2.OrientationType = AxisNumber.X2_Axis axisX2.DataType = AxisDataType.Numeric axisX2.Labels.ItemFormatString = "" axisX2.Labels.Orientation = TextOrientation.VerticalLeftFacing axisX2.Extent = 40 myChartArea.Axes.Add(axisX2) With axisY .axisNumber = AxisNumber.Y_Axis .RangeType = AxisRangeType.Automatic .DataType = AxisDataType.Numeric .Labels.ItemFormatString = "" .Labels.Orientation = TextOrientation.Custom .Extent = 40 End With Dim app As New LineChartAppearance app.NullHandling = NullHandling.DontPlot Dim seriesC As XYSeries = GetXYSeriesBound() Dim seriesD As XYSeries = GetXYSeriesUnBound() Me.UltraChart1.CompositeChart.Series.Add(seriesC) Me.UltraChart1.CompositeChart.Series.Add(seriesD) ' Customize the series colors. seriesC.PEs.Add(New PaintElement(Drawing.Color.Green)) seriesD.PEs.Add(New PaintElement(Drawing.Color.Blue)) Dim myScatterLayer As New ChartLayerAppearance() myScatterLayer.ChartType = ChartType.ScatterChart CType(myScatterLayer.ChartTypeAppearance, ScatterChartAppearance).ConnectWithLines = True myScatterLayer.ChartArea = myChartArea myScatterLayer.AxisX = axisX2 myScatterLayer.AxisY = axisY myScatterLayer.Series.Add(seriesC) myScatterLayer.Series.Add(seriesD) Me.UltraChart1.CompositeChart.ChartLayers.Add(myScatterLayer) ' Add the second layer to the legend. myLegend.ChartLayers.Add(myScatterLayer) 'Column chart '*************************************************************************** Dim axisY2 As New AxisItem() Dim axisX As New AxisItem() axisX.OrientationType = AxisNumber.X_Axis axisX.DataType = AxisDataType.String axisX.SetLabelAxisType = SetLabelAxisType.GroupBySeries axisX.Labels.ItemFormatString = "<ITEM_LABEL>" axisX.Labels.Orientation = TextOrientation.VerticalLeftFacing axisY.OrientationType = AxisNumber.Y_Axis axisY.DataType = AxisDataType.Numeric axisY.Labels.ItemFormatString = "<DATA_VALUE:0.#>" myChartArea.Axes.Add(axisX) myChartArea.Axes.Add(axisY) axisY2.OrientationType = AxisNumber.Y2_Axis axisY2.DataType = AxisDataType.Numeric axisY2.Labels.ItemFormatString = "<DATA_VALUE:0.#>" myChartArea.Axes.Add(axisY2) Dim myColumnLayer As New ChartLayerAppearance() Dim myColumnLayer1 As New ChartLayerAppearance() myColumnLayer.ChartType = ChartType.ColumnChart myColumnLayer1.ChartType = ChartType.ColumnChart myColumnLayer.ChartArea = myChartArea myColumnLayer1.ChartArea = myChartArea myColumnLayer.AxisX = axisX myColumnLayer.AxisY = axisY myColumnLayer1.AxisX = axisX myColumnLayer1.AxisY2 = axisY2 Dim seriesA As NumericSeries = GetNumericSeriesBound() Dim seriesB As NumericSeries = GetNumericSeriesUnBound() Dim seriesF As NumericSeries = GetNumericSeriesBound1() myColumnLayer.Series.Add(seriesA) myColumnLayer1.Series.Add(seriesB) myColumnLayer.Series.Add(seriesF) Me.UltraChart1.CompositeChart.Series.Add(seriesA) Me.UltraChart1.CompositeChart.Series.Add(seriesB) Me.UltraChart1.CompositeChart.Series.Add(seriesF) myColumnLayer.SwapRowsAndColumns = True Me.UltraChart1.CompositeChart.ChartLayers.Add(myColumnLayer) Me.UltraChart1.CompositeChart.ChartLayers.Add(myColumnLayer1) myLegend.ChartLayers.Add(myColumnLayer) myLegend.Bounds = New Rectangle(0, 75, 20, 25) myLegend.BoundsMeasureType = MeasureType.Percentage myLegend.PE.ElementType = PaintElementType.Gradient myLegend.PE.FillGradientStyle = GradientStyle.ForwardDiagonal myLegend.PE.Fill = Drawing.Color.CornflowerBlue myLegend.PE.FillStopColor = Drawing.Color.Transparent myLegend.Border.CornerRadius = 10 myLegend.Border.Thickness = 0 Me.UltraChart1.CompositeChart.Legends.Add(myLegend) Me.UltraChart1.InvalidateLayers()
End Sub Private Shared Function GetData() As DataTable Dim table As New DataTable() table = New DataTable table.Columns.Add("Label Column", GetType(String)) table.Columns.Add("Waarde Column", GetType(Double)) table.Columns.Add("Another Waarde Column", GetType(Double)) table.Rows.Add(New Object() {"2000", 1.0, 3.0}) table.Rows.Add(New Object() {"2001", 2.0, 2.0}) table.Rows.Add(New Object() {"2002", 3.0, 1.0}) table.Rows.Add(New Object() {"2003", 4.0, 2.0}) table.Rows.Add(New Object() {"2004", 5.0, 3.0}) Return table End Function Private Shared Function GetNumericSeriesUnBound() As NumericSeries Dim series As New NumericSeries() series.Label = "Series B" ' this code populates the series using unbound data series.Points.Add(New NumericDataPoint(5.0, "2000", False)) series.Points.Add(New NumericDataPoint(4.0, "2001", False)) series.Points.Add(New NumericDataPoint(3.0, "2002", False)) series.Points.Add(New NumericDataPoint(2.0, "2003", False)) series.Points.Add(New NumericDataPoint(1.0, "2004", False)) Return series End Function Private Function GetXYSeriesUnBound() As XYSeries Dim series As New XYSeries() series.Label = "Hello" ' this code populates the series using unbound data series.Points.Add(New XYDataPoint(1.0, 1.0, "2000", False)) series.Points.Add(New XYDataPoint(2.0, 2.0, "2001", False)) series.Points.Add(New XYDataPoint(3.0, 3.0, "2002", False)) series.Points.Add(New XYDataPoint(4.0, 4.0, "2003", False)) series.Points.Add(New XYDataPoint(5.0, 5.0, "2004", False)) Return series End Function Private Function GetXYSeriesBound() As XYSeries Dim series As New XYSeries() series.Label = "Series C" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueXColumn = "Waarde Column" series.Data.ValueYColumn = "Another Waarde Column" Return series End Function Private Shared Function GetNumericSeriesBound() As NumericSeries Dim series As New NumericSeries() series.Label = "Series A" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueColumn = "Waarde Column" Return series End Function Private Shared Function GetNumericSeriesBound1() As NumericSeries Dim series As New NumericSeries() series.Label = "Series F" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueColumn = "Another Waarde Column" Return series End Function
End Sub
Private Shared Function GetData() As DataTable Dim table As New DataTable() table = New DataTable table.Columns.Add("Label Column", GetType(String)) table.Columns.Add("Waarde Column", GetType(Double)) table.Columns.Add("Another Waarde Column", GetType(Double)) table.Rows.Add(New Object() {"2000", 1.0, 3.0}) table.Rows.Add(New Object() {"2001", 2.0, 2.0}) table.Rows.Add(New Object() {"2002", 3.0, 1.0}) table.Rows.Add(New Object() {"2003", 4.0, 2.0}) table.Rows.Add(New Object() {"2004", 5.0, 3.0}) Return table End Function Private Shared Function GetNumericSeriesUnBound() As NumericSeries Dim series As New NumericSeries() series.Label = "Series B" ' this code populates the series using unbound data series.Points.Add(New NumericDataPoint(5.0, "2000", False)) series.Points.Add(New NumericDataPoint(4.0, "2001", False)) series.Points.Add(New NumericDataPoint(3.0, "2002", False)) series.Points.Add(New NumericDataPoint(2.0, "2003", False)) series.Points.Add(New NumericDataPoint(1.0, "2004", False)) Return series End Function Private Function GetXYSeriesUnBound() As XYSeries Dim series As New XYSeries() series.Label = "Hello" ' this code populates the series using unbound data series.Points.Add(New XYDataPoint(1.0, 1.0, "2000", False)) series.Points.Add(New XYDataPoint(2.0, 2.0, "2001", False)) series.Points.Add(New XYDataPoint(3.0, 3.0, "2002", False)) series.Points.Add(New XYDataPoint(4.0, 4.0, "2003", False)) series.Points.Add(New XYDataPoint(5.0, 5.0, "2004", False)) Return series End Function Private Function GetXYSeriesBound() As XYSeries Dim series As New XYSeries() series.Label = "Series C" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueXColumn = "Waarde Column" series.Data.ValueYColumn = "Another Waarde Column" Return series End Function Private Shared Function GetNumericSeriesBound() As NumericSeries Dim series As New NumericSeries() series.Label = "Series A" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueColumn = "Waarde Column" Return series End Function Private Shared Function GetNumericSeriesBound1() As NumericSeries Dim series As New NumericSeries() series.Label = "Series F" ' this code populates the series from an external data source Dim table As DataTable = GetData() series.Data.DataSource = table series.Data.LabelColumn = "Label Column" series.Data.ValueColumn = "Another Waarde Column" Return series End Function
Hello,
The code you provided seems to work properly, if I understand what you're trying to do. To make sure we're on the same page, could you create a mock-up of what you want the chart to look like and post it here?