The Dashboard class represents a container of visual components such as plots, line graphics and text labels. Initially the dashboard contains two Panel classes to which its components should be added:
- RootPanel is the root of dashboard components' hierarchy. Its elements are drawn overlapping on top of each other. Here you can add elements whose position should not depend on the size of the dashboard and their siblings. For example, Chart controls display LegendRenderer inside the RootPanel.
- LayoutPanel is a vertical stack panel by default. Its components are arranged next to each other and dimensions are calculated automatically from available space. The components that we are going to create in this tutorial will be added here.
Let's start by adding a HTML canvas element to the page and create a Dashboard instance from this element. In addition, set the style and dimensions of the Dashboard so that it fills its parent div element. You can also add aliases to the commonly used namespaces.
HTML
Copy Code
|
---|
<div style="position: absolute; left: 0px; top: 60px; bottom: 0px; right: 0px;"> <canvas id="dashboard" style="display:block;width:100%;height:100%"></canvas> </div> |
JavaScript
Copy Code
|
---|
var Charting = MindFusion.Charting; var Controls = MindFusion.Controls; var Components = MindFusion.Charting.Components; var Collections = MindFusion.Common.Collections; var Drawing = MindFusion.Drawing;
var dashboardEl = document.getElementById('dashboard'); dashboardEl.width = dashboardEl.offsetParent.clientWidth; dashboardEl.height = dashboardEl.offsetParent.clientHeight; var dashboard = new Controls.Dashboard(dashboardEl); |
Next, add a TextComponent that will display the dashboard's title. As LayoutPanel arranges its children in a vertical stack, the title will show at the top of the dashboard if it's the first component added. The following code creates and adds the title component, while also setting its appearance properties:
JavaScript
Copy Code
|
---|
var tc = new Components.TextComponent(); tc.text = "TITLE TEXT"; tc.fontName = "Times New Roman"; tc.fontStyle = Drawing.FontStyle.Underline; tc.fontSize = 20.4; tc.horizontalAlignment = Components.LayoutAlignment.Center; dashboard.layoutPanel.children.add(tc); |
We want to divide the remaining space in two rows and two columns, creating four cells in total. For that purpose, add a GridPanel, which can host multiple components in each of its cells. Its default constructor creates one GridRow and one GridColumn, i.e. it defines a single cell. We'll add one more row and column to respective collection properties of the panel:
JavaScript
Copy Code
|
---|
var grid = new Components.GridPanel(); grid.columns.add(new Components.GridColumn()); grid.rows.add(new Components.GridRow()); dashboard.layoutPanel.children.add(grid); |
Now that we have defined our layout, lets create sample data series. MindFusion.Charting offers multiple classes you could use to represent data. All of them implement the
Series interface, which you could implement in your own model classes if you prefer. The data class we'll use in this example is
BarSeries; it takes a list of values to display as bar height, and automatically assigns bar positions at equal distances. It is convenient for creation of barcharts, but can actually be used with any other type of
SeriesRenderer.
JavaScript
Copy Code
|
---|
var data1 = new Charting.BarSeries( new Collections.List([10, 15, 17, 16, 20, 15, 14, 13, 10, 17, 22, 25, 25, 25, 21, 21]), null, null, new Collections.List(["nov\n2014", "dec\n2014", "jan\n2015", "feb\n2015", "mar\n2015", "apr\n2015", "may\n2015", "jun\n2015", "jul\n2015", "aug\n2015", "sep\n2015", "oct\n2015", "nov\n2015", "dec\n2015", "jan\n2016", "feb\n2016"])); data1.title = "LP Vinyl";
var data2 = new Charting.BarSeries( new Collections.List([13, 13, 14, 16, 23, 25, 20, 19, 16, 17, 15, 13, 13, 17, 18, 21]), null); data2.title = "CD";
var data3 = new Charting.BarSeries( new Collections.List([29, 28, 29, 31, 33, 35, 33, 27, 28, 28, 27, 29, 29, 31, 33, 29]), null); data3.title = "MP3"; |
You can see that BarSeries has two overloaded constructors. They let you specify different kinds of labels for the bars. MindFusion.Charting supports six kinds of labels displayed at various locations of rendered graphics. BarSeries lets you define inner labels drawn inside bars, top labels drawn above their bars, and X axis labels drawn along the axis. In the example above we'll only show axis labels, passing null for the other arguments. The Title values will be drawn by a LegendRenderer we are going to add later.
For visualizing the data, you must create an instance of a class derived from SeriesRenderer, each drawing a different kind of graphics. In this tutorial we'll see how several of them work, starting with a LineRenderer:
JavaScript
Copy Code
|
---|
var lineRenderer = new Charting.LineRenderer(new Collections.ObservableCollection([data1, data2, data3])); |
Apart from the kind of graphics drawn, a SeriesRenderer lets you specify styling attributes for the graphic primitives, such as stroke and fill colors:
JavaScript
Copy Code
|
---|
lineRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 0, 0)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 0, 0, 255)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 0, 255, 0))]), new Collections.List([ new Drawing.Brush(new Drawing.Color("Red")), new Drawing.Brush(new Drawing.Color("Blue")), new Drawing.Brush(new Drawing.Color("Green"))])); |
SeriesRenderer objects must be placed inside Plot components. In this tutorial we'll use three different kinds of plots: Plot2D and Plot3D for drawing in 2D and 3D Cartesian coordinate systems respectively, and RadarPlot for drawing in polar coordinate system. For the LineRenderer we defined above, create a Plot2D and set its background:
JavaScript
Copy Code
|
---|
var linePlot = new Charting.Plot2D(); linePlot.background = new Drawing.LinearGradientBrush(new Drawing.Color("White"), Drawing.Color.fromArgb(1, 224, 224, 224), 90); |
Add the line renderer to plot's SeriesRenderers collection:
JavaScript
Copy Code
|
---|
linePlot.seriesRenderers.add(lineRenderer); |
The data points renderered inside a Plot2D are scaled relatively to the Axis ranges defined via its XAxis and YAxis properties. For each Axis you can define its first and last visible values by setting MinValue and MaxValue properties. If their values are not specified, the control will calculate them automatically to fit all data provided through plot's SeriesRenderer objects. In addition, the Interval property lets you specify the distance between coordinate labels. The Axis class also has a Title property that lets you show description for the measure represented by an axis:
JavaScript
Copy Code
|
---|
linePlot.xAxis = new Charting.Axis(); linePlot.xAxis.minValue = 0; linePlot.xAxis.maxValue = 15; linePlot.xAxis.interval = 1; linePlot.xAxis.title = "When?";
linePlot.yAxis = new Charting.Axis(); linePlot.yAxis.minValue = 0; linePlot.yAxis.maxValue = 35; linePlot.yAxis.interval = 5; linePlot.yAxis.title = "How many thousands?"; |
If you want to show coordinates for the values drawn inside a plot, you must also add
XAxisRenderer and
YAxisRenderer components to the dashboard. Each of them can optionally display
Axis coordinates and
Title, ticks and data labels. In order to display data labels from a series, you must also set the
LabelsSource property to either a
SeriesRenderer or a
Plot:
JavaScript
Copy Code
|
---|
var xRenderer = new Charting.XAxisRenderer(linePlot.xAxis); xar.labelsSource = linePlot; xar.showCoordinates = false;
var yRenderer = new Charting.YAxisRenderer(linePlot.yAxis); |
In order to align axes to their plot, we'll add an intermediate GridPanel inside the top-left cell of the parent grid. We can do this on a couple of lines of code with the help of LayoutBuilder. That class lets us build layout fragments from several components and add them to a parent panel. In this case we'll call the CreatePlotWithBottomAndLeftAxes method to automatically create a GridPanel and add specified components to it. Other variants of this method can also automatically add the created panel to dashboard's LayoutPanel, but in this tutorial we'll add the result to our custom child panel.
JavaScript
Copy Code
|
---|
var builder = new Controls.LayoutBuilder(dashboard); var panel1 = builder.createPlotWithBottomAndLeftAxes(linePlot, xRenderer, yRenderer); |
We want to display this fragment inside top-left cell of the GridPanel we created earlier. This can be done by setting the GridRow and GridColumn properties defined in base Component class, which specify respectively the row or column index of a cell inside parent grid panel. The index is zero-based, so we set both properties to zero:
JavaScript
Copy Code
|
---|
panel1.gridRow = 0; panel1.gridColumn = 0; grid.children.add(panel1); |
Following the same approach, we can display same data using a different kind of graphics and with different appearance attributes. Lets draw bars this time:
JavaScript
Copy Code
|
---|
var barDataRenderer = new Charting.BarRenderer(new Collections.ObservableCollection([data1, data2, data3])); |
We'll specify a different fill color for each series of bars by providing a list of brushes to PerSeriesStyle class.
JavaScript
Copy Code
|
---|
barDataRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 128, 0, 128)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 240, 230, 140)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 165, 0))])); |
You could add the BarRenderer to the same plot that now draws line graphics to create a mixed chart, but lets create a new plot for drawing bars only:
JavaScript
Copy Code
|
---|
var barPlot = new Charting.Plot2D(); |
Lets show axes for this plot too. Note that we are assigning same range properties as for the linechart, but through a new Axis instance. If you reused the Axis instance (by setting barPlot.XAxis = linePlot.XAxis), the plots would scroll together when the user pans any of them.
JavaScript
Copy Code
|
---|
barPlot.xAxis = new Charting.Axis(); barPlot.xAxis.minValue = -1; barPlot.xAxis.maxValue = 15; barPlot.xAxis.interval = 1; barPlot.xAxis.title = "When?";
barPlot.yAxis = new Charting.Axis(); barPlot.yAxis.minValue = 0; barPlot.yAxis.maxValue = 35; barPlot.yAxis.interval = 5; barPlot.yAxis.title = "How many thousands?"; |
Add the bar renderer to its plot:
JavaScript
Copy Code
|
---|
barPlot.seriesRenderers.add(barDataRenderer); |
Use
LayoutBuilder again to align axes to plot and add them to a grid panel:
JavaScript
Copy Code
|
---|
var panel2 = builder.createPlotWithBottomAndRightAxes(barPlot, xRenderer, new Charting.YAxisRenderer(barPlot.yAxis));
panel2.gridColumn = 1; panel2.gridRow = 0; grid.children.add(panel2); |
Now lets draw a radar chart using RadarRenderer:
JavaScript
Copy Code
|
---|
var radarDataRenderer = new Charting.RadarRenderer(new Collections.ObservableCollection([data1, data2, data3])); |
Set the AreaOpacity property to fill the radar polygons using a semi-transparent fill:
JavaScript
Copy Code
|
---|
radarDataRenderer.areaOpacity = 0.2; |
Set the stroke and fill colors:
JavaScript
Copy Code
|
---|
radarDataRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(new Drawing.Color("PaleGreen")), new Drawing.Brush(new Drawing.Color("PaleTurquoise")), new Drawing.Brush(new Drawing.Color("PaleVioletRed"))]), new Collections.List([ new Drawing.Brush(new Drawing.Color("PaleGreen")), new Drawing.Brush(new Drawing.Color("PaleTurquoise")), new Drawing.Brush(new Drawing.Color("PaleVioletRed"))]), new Collections.List([5])); |
Create a
RadarPlot and set its data range:
JavaScript
Copy Code
|
---|
var radarPlot = new Charting.RadarPlot(); radarPlot.defaultAxis.minValue = 0; radarPlot.defaultAxis.maxValue = 35; radarPlot.defaultAxis.interval = 5; |
Set axis appearance attributes:
JavaScript
Copy Code
|
---|
radarPlot.axisOptions = new Charting.RadarAxisOptions(radarPlot.defaultAxis); radarPlot.axisOptions.showSeriesLabels = true; radarPlot.axisOptions.axisStroke = new Drawing.Brush(new Drawing.Color("LightGray")); radarPlot.defaultAxis.title = ""; |
Add the radar renderer to its plot:
JavaScript
Copy Code
|
---|
radarPlot.seriesRenderers.add(radarDataRenderer); |
Add the plot to lower-left cell of parent grid:
JavaScript
Copy Code
|
---|
radarPlot.gridColumn = 0; radarPlot.gridRow = 1; grid.children.add(radarPlot); |
We now have one last unused cell in our parent grid - lets add four more plots to it using third-level grid panel. In its first cell we'll show horizontal bars. In other ones we'll show 3D bars and also show how to set them up to scroll together. We'll again show the same data as in previous plots:
JavaScript
Copy Code
|
---|
var horizontalBar3DDataRenderer = new Charting.BarRenderer(new Collections.ObservableCollection([data1, data2, data3])); |
Set their fills:
JavaScript
Copy Code
|
---|
horizontalBar3DDataRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 128, 0, 128)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 240, 230, 140)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 165, 0))]), null, new Collections.List([1])); |
Set the bars orientation:
JavaScript
Copy Code
|
---|
horizontalBar3DDataRenderer.horizontalBars = true; |
Add the horizontal bar renderer to a plot:
JavaScript
Copy Code
|
---|
var plot4 = new Charting.Plot2D(); plot4.seriesRenderers.add(horizontalBar3DDataRenderer); |
Set up plot's axes:
JavaScript
Copy Code
|
---|
plot4.yAxis = new Charting.Axis(); plot4.yAxis.minValue = 0; plot4.yAxis.maxValue = 4; plot4.yAxis.interval = 1; plot4.yAxis.title = "Months";
plot4.xAxis = new Charting.Axis(); plot4.xAxis.minValue = 0; plot4.xAxis.maxValue = 40; plot4.xAxis.interval = 5; plot4.xAxis.title = "Thousands"; |
Specify that this plot should scroll vertically:
JavaScript
Copy Code
|
---|
plot4.verticalScroll = true; |
Create axis renderers and set up their appearance:
JavaScript
Copy Code
|
---|
var xAxisRenderer = new Charting.XAxisRenderer(plot4.xAxis); xAxisRenderer.axisStroke = new Drawing.Brush(new Drawing.Color("Red")); xAxisRenderer.axisStrokeThickness = 3; xAxisRenderer.titleBrush = new Drawing.Brush(new Drawing.Color("Orange")); xAxisRenderer.titleFontName = "Courier New"; xAxisRenderer.titleFontSize = 15;
var yAxisRenderer = new Charting.YAxisRenderer(plot4.yAxis); yAxisRenderer.axisStroke = new Drawing.Brush(new Drawing.Color("Red")); yAxisRenderer.axisStrokeThickness = 3; yAxisRenderer.titleBrush = new Drawing.Brush(new Drawing.Color("Orange")); yAxisRenderer.titleFontName = "Courier New"; yAxisRenderer.titleFontSize = 15; |
Create a panel for the plot and axes:
JavaScript
Copy Code
|
---|
var panel6 = builder.createPlotWithTopAndLeftAxes(plot4, xAxisRenderer, yAxisRenderer); panel6.gridColumn = 0; panel6.gridRow = 0; |
Now let's create some 3D bars:
JavaScript
Copy Code
|
---|
var bar3DDataRenderer = new Charting.BarRenderer3D(new Collections.ObservableCollection([data1, data2, data3])); |
Set their style:
JavaScript
Copy Code
|
---|
bar3DDataRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 128, 0, 128)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 240, 230, 140)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 165, 0))]), null, new Collections.List([1])); |
Create a plot for 3D bars:
JavaScript
Copy Code
|
---|
var plot3d1 = new Charting.Plot3D(); plot3d1.seriesRenderers.add(bar3DDataRenderer); |
Set up axes. We'll reuse these
Axis instances later in order to implement synchronized scrolling in several plots:
JavaScript
Copy Code
|
---|
plot3d1.xAxis = new Charting.Axis(); plot3d1.xAxis.minValue = 0; plot3d1.xAxis.maxValue = 5; plot3d1.xAxis.interval = 1; plot3d1.xAxis.title = "Months";
plot3d1.yAxis = new Charting.Axis(); plot3d1.yAxis.minValue = 0; plot3d1.yAxis.maxValue = 40; plot3d1.yAxis.interval = 5; plot3d1.yAxis.title = "Thousands"; |
Add last plot and axes to the layout:
JavaScript
Copy Code
|
---|
var xar = new Charting.XAxisRenderer(plot3d1.xAxis); xar.showCoordinates = false; xar.titleBrush = new Drawing.Brush(new Drawing.Color("Green")); xar.titleFontName = "Verdana"; xar.titleFontSize = 10;
var yar = new Charting.YAxisRenderer(plot3d1.yAxis); yar.titleBrush = new Drawing.Brush(new Drawing.Color("Green")); yar.titleFontName = "Verdana"; yar.titleFontSize = 10;
var panel3 = builder.createPlotWithTopAndRightAxes(plot3d1, xar, yar); |
Create a BarOverlayRenderer3D instance, which draws each series as a different row of bars:
JavaScript
Copy Code
|
---|
var barOverlay3DRenderer = new Charting.BarOverlayRenderer3D(new Collections.ObservableCollection([data1, data2, data3])); |
Set its style:
JavaScript
Copy Code
|
---|
barOverlay3DRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 128, 0, 128)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 240, 230, 140)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 165, 0))]), null, new Collections.List([1])); |
Create a plot and reuse axes of previous one:
JavaScript
Copy Code
|
---|
var plot3d3 = new Plot3D(); plot3d3.seriesRenderers.add(barOverlay3DRenderer); plot3d3.xAxis = plot3d1.xAxis; plot3d3.yAxis = plot3d1.yAxis; |
Add this plot and new axis renderers to the layout:
JavaScript
Copy Code
|
---|
var xar = new Charting.XAxisRenderer(plot3d3.xAxis); xar.titleBrush = new Drawing.Brush(new Drawing.Color("Purple")); xar.titleFontName = "Courier New"; xar.titleFontSize = 12;
var yar = new Charting.YAxisRenderer(plot3d3.yAxis); yar.titleBrush = new Drawing.Brush(new Drawing.Color("Purple")); yar.titleFontName = "Courier New"; yar.titleFontSize = 12;
var panel5 = builder.createPlotWithTopAndRightAxes(plot3d3, xar, yar); |
And the last one will show data series as 3D bar stacks:
JavaScript
Copy Code
|
---|
var barStack3DRenderer = new Charting.BarStackRenderer3D(new Collections.ObservableCollection([data1, data2, data3]));
barStack3DRenderer.seriesStyle = new Charting.PerSeriesStyle(new Collections.List([ new Drawing.Brush(Drawing.Color.fromArgb(0.6, 128, 0, 128)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 240, 230, 140)), new Drawing.Brush(Drawing.Color.fromArgb(0.6, 255, 165, 0))]), null, new Collections.List([1])); var plot3d2 = new Plot3D(); plot3d2.seriesRenderers.add(barStack3DRenderer); plot3d2.xAxis = plot3d1.xAxis; |
Here we want a different Y axis range because the stacks will get higher than standalone bars from older plots:
JavaScript
Copy Code
|
---|
plot3d2.yAxis = new Charting.Axis(); plot3d2.yAxis.minValue = 0; plot3d2.yAxis.maxValue = 100; plot3d2.yAxis.interval = 5; plot3d2.yAxis.title = "Thousands"; |
Add a panel for the last plot and axes:
JavaScript
Copy Code
|
---|
var xar = new Charting.XAxisRenderer(plot3d2.xAxis); xar.titleBrush = new Drawing.Brush(new Drawing.Color("Blue")); xar.titleFontName = "Times New Roman"; xar.titleFontSize = 15;
var yar = new Charting.YAxisRenderer(plot3d2.yAxis); yar.titleBrush = new Drawing.Brush(new Drawing.Color("Blue")); yar.titleFontName = "Times New Roman"; yar.titleFontSize = 15; yar.titleFontStyle = Drawing.FontStyle.Bold;
var panel4 = builder.createPlotWithTopAndLeftAxes(plot3d2, xar, yar); |
Set the grid positions for all child panels:
JavaScript
Copy Code
|
---|
panel3.gridColumn = 1; panel3.gridRow = 0; panel4.gridColumn = 0; panel4.gridRow = 1; panel5.gridColumn = 1; panel5.gridRow = 1; |
Finally, arrange them in a grid in the lower-right corner of parent grid:
JavaScript
Copy Code
|
---|
var miniGrid = new Components.GridPanel(); miniGrid.columns.add(new Components.GridColumn()); miniGrid.rows.add(new Components.GridRow()); miniGrid.children.add(panel3); miniGrid.children.add(panel4); miniGrid.children.add(panel5); miniGrid.children.add(panel6);
miniGrid.gridColumn = 1; miniGrid.gridRow = 1; grid.children.add(miniGrid); |
Now create a legend and the dashboard is complete. The legend will display the series titles we assigned earlier:
JavaScript
Copy Code
|
---|
var legend = new Charting.LegendRenderer(); legend.content.add(lineRenderer); dashboard.rootPanel.children.add(legend); |
Finally, call the draw method of the dashboard to render it on the page:
JavaScript
Copy Code
|
---|
dashboard.draw(); |
If you run the application, you should now see this image:
