Combination Chart in JavaScript

In this blog post we will use the Charting for JavaScript library to create the chart that you see below:

This is a combination chart has one line series and two bar series drawn in stacks. We will use the Dashboard control to combine the building elements of the chart: data series, legend, axes, title and plot.

I. HTML Setup

We need an HTML Canvas element for the chart to draw itsself onto. It is important that we give it an id. The Canvas element will render the chart and its position and size will determine where and how big the chart will be drawn.

<canvas id="dashboard" style="width: 100%; height: 100%; display: block;"></canvas>

The Dashboard control needs the MindFusion.Charting.js library. We also need the MindFusion.Drawing module for presentation classes like brushes, pens etc. We include reference to these files at the end of the web page, before the closing BODY tag:

<a href="http://Scripts/MindFusion.Common.js">http://Scripts/MindFusion.Common.js</a>
<a href="http://Scripts/MindFusion.Charting.js">http://Scripts/MindFusion.Charting.js</a>

The two library JavaScript files are in a subfolder called Scripts. We prefer to keep the JavaScript code for the combination chart separate from the web page and we include one final JS reference:

<a href="http://CombinationChart.js">http://CombinationChart.js</a>

This is the code-behind file where we will write all code that creates and customizes the combination chart.

II. Creating the Dashboard and General Chart Settings

We add mappings to the chart and drawing namespaces that we want to use. If your IDE supports Intellisense you can also add a reference to the Intellisense file.

/// 
var Charting = MindFusion.Charting;

var Controls = Charting.Controls;
var Collections = Charting.Collections;
var Drawing = Charting.Drawing;
var Components = Charting.Components;

The Dashboard class requires and HTML element in the constructor. We get the Canvas from the web page with the help of its id:

// create the dashboard
var dashboardEl = document.getElementById('dashboard');
dashboardEl.width = dashboardEl.offsetParent.clientWidth;
dashboardEl.height = dashboardEl.offsetParent.clientHeight;
var dashboard = new Controls.Dashboard(dashboardEl);

The Dashboard control is a container for all elements of a dashboard. In order to render a chart, we need a Plot element that can visualize data. We create an instance of the Plot2D class:

var plot = new Charting.Plot2D();
plot.gridType = Charting.GridType.Horizontal;
plot.gridColor1 = plot.gridColor2 = new Drawing.Color.fromArgb(200, 243, 244, 254);

Then we specify that the plot will render a horizontal grid with light gray grid lines. Each Plot2D has a seriesRenderers property that stores all -SeriesRenderer -s that are responsible for drawing correctly the data series according to their type – LineSeries BarSeries PieSeries etc. More about that later.

III. Data Series and Renderers

Each data series is represented by a class that corresponds to its type. MindFusion Charting for JavaScript has a variety of ISeries classes, some of whom can be used in different chart types. We will first use the BarSeries class to create one of the series that render bars:

// data for first bar series
var barSeries1 = new Charting.BarSeries(
		new Collections.List([9, 11, 13, 18, 19, 22, 23, 26, 29, 32, 33, 36, 41, 46, 49, 55, 57, 58, 61, 63]), //y
		null, null,
		new Collections.List(["1999", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", 
		"2012", "2013", "2014", "2015", "2016", "2017", "2018"]));

The BarSeries constructor requires several arguments. The first one is the data list, the second are lists with the top and inner labels, which we do not use. The last parameter are the labels for the X-axis and we set here the desired labels.

Then we set the title property of the BarSeries – it is important because it will render as a legend item.

barSeries1.title = "Total amount of goods sold";

We create then another series for the top row of bars. We don’t need any labels any more so we use now a simple Series2D instance:

var barSeries2 = new Charting.Series2D(
		new Collections.List([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]),//x
		new Collections.List([3, 4, 5, 5, 7, 8, 7, 6, 8, 15, 17, 21, 19, 18, 17, 16, 17, 19, 20, 22]),//y
		null);

barSeries2.title = "Extra production to meet demand";

The series need a SeriesRenderer that can draw them. There are different SeriesRenderer -s for the different types of series. The different SeriesRenderer instances support different ISeries classes.

In our case we want a stack bar chart and we use the BarStackRenderer . Each SeriesRenderer accepts a list with the Series instances it must render. Here is the code for the stack bars:

// draw bars
var barRenderer = new Charting.BarStackRenderer(new Collections.ObservableCollection([barSeries1, barSeries2]));
barRenderer.seriesStyle = new Charting.PerSeriesStyle (new Collections.List([new Drawing.Brush("#230A59"), new Drawing.Brush("#3E38F2")]));
barRenderer.barSpacingRatio = 0.7;

The different SeriesRenderer instances have different sets of properties that allow you to customize how the data series will be drawn. Here we use the barSpacingRatio to specify the thickness of the stack bars.

As we mentioned earlier, the Plot2D class has a seriesRenderers property where we can add the different SeriesRenderer -s that we want to show. We add the BarStackRenderer add graphics to plot
plot.seriesRenderers.add(barRenderer);

The procedure is the same for the line chart. We create another Series2D instance:

// sample data for line graphics
var lineSeries = new Charting.Series2D(
				new Collections.List([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),//x
				new Collections.List([7, 9, 12, 15, 18, 23, 24, 27, 35, 41, 46, 49, 53, 55, 58,  61, 63, 66, 67, 69 ]),//right-y
				null);
lineSeries.title = "Peak demand";

We give it a title and create a LineRenderer that will render this series:

// draw lines
var lineRenderer = new Charting.LineRenderer(
				new Collections.ObservableCollection([lineSeries]));
lineRenderer.seriesStyle = new Charting.UniformSeriesStyle(new Drawing.Brush("#ffffff"), new Drawing.Brush("#ffffff"), 6);

Finally we add the LineRenderer to the seriesRenderers collection of the Plot2D instance.

plot.seriesRenderers.add(lineRenderer);

You might have noticed that we also set the seriesStyle property in both the BarStackRenderer and the LineRenderer classes. This is the property that specifies how the chart series will be painted. There are different classes that derive from SeriesStyle All of them concern a different pattern of applying brushes and pens to the element of a Series We use here an instance of the PerSeriesStyle class that accepts lists with brushes and strokes and applies one consequtive brush and stroke to all elements in the corresponding Series . The LineRenderer uses the UniformSeriesStyle , which accepts just two Brush instances as arguments and applies them to fill and stroke all elements in all Series instances in the SeriesRenderer .

IV. The Axes

The chart axes are instances of the Axis class. We use their min , max and interval properties to specify the numeric data of each of the two axes that our dashboard will have – X and Y:

// create axes
var xAxis = new Charting.Axis();
xAxis.interval = 0;
xAxis.minValue = -1;
xAxis.maxValue = 20;
xAxis.title = "";

// create axes
var yAxis = new Charting.Axis();
yAxis.interval = 10;
yAxis.minValue = 0;
yAxis.maxValue = 100;
yAxis.title = "Cost of goods in mlns of USD";

Then we specify to the Plot2D that the Axis instances we created are its X and Y axes:

plot.yAxis = yAxis;
plot.xAxis = xAxis;

As you might have guessed, the Axis need Renderer-s to render them. They are called respectively XAxisRenderer and YAxisRenderer .

// create renderers for the two axes
var xAxisRenderer = new Charting.XAxisRenderer(xAxis);
xAxisRenderer.margin = new Charting.Margins(0, 0, 0, 10);
xAxisRenderer.labelsSource = plot;
xAxisRenderer.showCoordinates = false;


var yAxisRenderer = new Charting.YAxisRenderer(yAxis);
yAxisRenderer.margin = new Charting.Margins(10, 0, 0, 0);

The renderers have various properties for specifying how the axes will be rendered. We use margin to add some space around the two axes.

Finally, we use the layoutBuilder property of the Dashboard class to create a GridPanel that will correctly measure and arrange all building blocks of our cobination chart:

dashboard.layoutBuilder.createAndAddPlotAndAxes(
		plot, null,
		[yAxisRenderer],
		[ xAxisRenderer ],
		null);

V. The Legend

As we said, the legend items are taken from the title property of each Series . We use a LegendRenderer to render the legend and set some of its properties:

// add legend
var legendRenderer = new Charting.LegendRenderer();
legendRenderer.content = new Collections.ObservableCollection([barRenderer, lineRenderer]);
legendRenderer.background = new Drawing.Brush("#d0d3fb");
legendRenderer.borderStroke = new Drawing.Brush("#BDBFAA");
legendRenderer.showTitle = false;
legendRenderer.horizontalAlignment = Components.LayoutAlignment.Far;

The content property of LegendRenderer allows us to specify a collection of SeriesRenderer instances. This way we can have one legend for series of different kinds. We don’t need a title for our legend, so we set showTitle to false.

The LegendRenderer requires no special positioning in the dashboard layout, so we simple add it to the rootPanel of the Dashboard and let it handle its easure and placement:

dashboard.rootPanel.children.add(legendRenderer);

VI. The Title and Subtitle

The title is an instance of the TextComponent class:

var tc = new Components.TextComponent();
tc.text = "STEADY GROWTH";
tc.fontSize = 20.4;
tc.horizontalAlignment = Components.LayoutAlignment.Near;
tc.margin = new Charting.Margins(100, 10, 0, 0);
dashboard.layoutPanel.children.add(tc);

It has various appearance properties. Just like the LegendRenderer the TextComponent can be added directly to the children of the layoutPanel.

Now that we’ve made all arrangements for the chart let’s not forget to call the draw method that will render the chart on the screen:

dashboard.draw();

That was everything. You can see an online demo of the chart here.

You can download the full source code of this combination chart in JavaScript together with all used libraries from here:

Combination Chart in JavaScript Full Code

About Charting for JavaScript: MindFusion library for interactive charts and gauges. It supports all common chart types including 3D bar charts. Charts can have a grid, a legend, unlimitd number of axes and series. Scroll, zoom and pan are supported out of the box. You can easily create your own chart series by implementing the Series interface.
The gauges library is part of Charting for JavaScript. It supports oval and linear gauge with several types of labels and ticks. Various samples show you how the implement the gauges to create and customize all popular gauge types: car dashboard, clock, thermometer, compass etc. Learn more about Charting and Gauges for JavaScript at https://mindfusion.eu/javascript-chart.html.

Combination Chart in Android

This post is a step-by-step tutorial in how to create a combination chart in android with the Charting for Android library.

I. Project configuration

Let’s create a new project. In Eclipse, we choose File -> New -> Android Application Project. We write “CombinationChart” as an application name. The package is called com.mindfusion.combinationchart. The other settings remain unchanged.

II. Adding the jar file.

With project created, it’s time to add the libraries. Copy the droidchart.jar from the libs directory of the sample project (download file here) to the libs directory of your project. Then right-click on your project and choose Properties -> Java Build Path -> Libraries -> Add JARs. Navigate to the libs folder and add the droidchart.jar.

Adding a JAR library to an Android application project

Adding a JAR library to an Android application project

III. Declaring the chart

Time to declare the chart in the layout of the application. We build a simple application, where the chart will be the only thing that shows. So, we edit the activity_main.xml file, which is found in res -> layout folder in the project tree for the CombinationChart application.

We change the layout to Linear and we introduce a new xml node – chart. The chart node refers to a class found in the com.mindfusion.charting namespace.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:chart="http://schemas.android.com/apk/lib/com.mindfusion.charting"
...

Then we declare the chart:

<com.mindfusion.charting.AxesChart
android:id=”@+id/combi_chart”
android:layout_width=”fill_parent”
android:layout_height=”wrap_content”
chart:gridType=”horizontal”
chart:titleOffset=”40dp”
chart:titleHeight=”40dp”
chart:labelHeight=”12dp”
tools:context=”.MainActivity” />

We name it combi_chart. This is important because we’ll use the name to retrieve the chart object in the next step.

IV. General chart settings.

In this step we’ll set the general chart settings. First, we get the chart object, which is declared in the layour (see previous step).


private AxesChart chart;
....
chart = (AxesChart)findViewById(R.id.combi_chart);

Then we set the title and the offset of the title e.g. the space between the title and the plot are for the chart. We also set the height of the font for the title labels and the other labels at the chart.


chart.setTitle("Visitors in Paradise Hotels");
chart.setTitleOffset(50f);
chart.setTitleHeight(30f);
chart.setLabelHeight(20f);

V. The grid.

Our chart has a crossed grid with light gray grid stripes. This is set with the following code:


ArrayList gridStrokes = new ArrayList();
gridStrokes.add(Color.rgb(207, 207, 207));
chart.setGridStrokeColors(gridStrokes);


chart.setGridType(GridType.Crossed);

VI. The axes.

The X-axis has 10 intervals. Each division has its own label. We set the label type to custom text, specify the labels and customize the min and max numbers to be shown:


chart.xAxisSettings.setMin(0f);
chart.xAxisSettings.setMax(10f);
chart.xAxisSettings.setInterval(1f);
chart.xAxisSettings.setLabelType(AxisLabelType.Custom);


ArrayList xLabels = new ArrayList();
Collections.addAll(xLabels, "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014");
chart.xAxisSettings.setLabels(xLabels);

The Y-axis has no custom labels, it just shows the value intervals. But it has a title. Here is how we set it:


chart.yAxisSettings.setMin(0f);
chart.yAxisSettings.setMax(30f);
chart.yAxisSettings.setInterval(10f);
chart.yAxisSettings.setLabelType(AxisLabelType.Scale);
chart.yAxisSettings.setTitle("in thousands");

VII. The bar series.

The first series is a bar series. We create a new instance of the BarSeries class and add 10 x and y float numbers, which will be used to calculate the size and location of the bars:


BarSeries series1 = new BarSeries();

ArrayList xData = new ArrayList();
for(int i = 0; i < 10; i++)
xData.add((float)i);
series1.setXData(xData);


ArrayList yData1 = new ArrayList();
Collections.addAll(yData1, 15f, 17f, 18f, 19f, 18.4f, 16.4f, 12f, 17f, 18.7f, 19.1f );
series1.setYData(yData1);

The next thing to do is to specify the colors for the bars and their outlining. The library has the FillColors and StrokeColors property, which we use:


ArrayList fillColors1 = new ArrayList();
fillColors1.add(Color.rgb(174, 200, 68));
series1.setFillColors(fillColors1);


ArrayList strokeColors1 = new ArrayList();
strokeColors1.add(Color.rgb(115, 133, 45));
series1.setStrokeColors(strokeColors1);

Let’s not forget to add the ready series to the collection of series.


chart.addSeries(series1);

VIII. The line series with scatters.

The line series is an instance of the LineSeries class, where we set the ScatterType and LineType properties:


LineSeries series2 = new LineSeries();
series2.setScatterType(ScatterType.Circle);
series2.setLineType(LineType.Line);
series2.setScatterSize(20f);
...
chart.addSeries(series2);

The ScatterFillColors and ScatterStrokeColors are used for setting the colors of the scatters. The properties for the line are the same as with the bar series: StrokeColors.

IX The area series.

The area series has a different line type than the scatter series. We don’t set the scatter type here since its set to “None” by default.

The data in both line series is set in the same way as in the bar series and we don’t cite it again.


LineSeries series3 = new LineSeries();
series3.setLineType(LineType.Area);
...
chart.addSeries(series3);

Here is the final chart:

An elegant combination chart for Android mobile devices.

An elegant combination chart for Android mobile devices.

The sample is available for download from here:

Download Android Combination Chart Sample

Read more about MindFusion Charting for Android library here.