ChartDirector Ver 3.0 (C++ Edition)

Pareto Chart




A pareto chart is a bar chart with the data sorted in descending order, together with a line chart showing the same data in accumulated form. In the current example, the data is shown as both percentages and value on the two y-axes.

The chart in this example is composed of two layers - a BarLayer added using XYChart.addBarLayer, and a LineLayer added using XYChart.addLineLayer.

This example employs the ArrayMath object for computing the accumulated line, obtaining the scaling factor between the two y-axes, and re-scaling the line data as percentages.

The two y-axes are synchronized using XYChart.syncYAxis.

Source Code Listing

[The following project is available in "cppdemo/pareto".]
#include "chartdir.h" int main(int argc, char *argv[]) { //The data for the chart double data[] = {40, 15, 7, 5, 2}; //The labels for the chart const char *labels[] = {"Hard Disk", "PCB", "Printer", "CDROM", "Keyboard"}; //Create a XYChart object of size 400 x 225 pixels XYChart *c = new XYChart(400, 225); //Set the background color of the chart to gold (goldGradient). Use a 2 //pixel 3D border. c->setBackground(c->gradientColor(goldGradient), -1, 2); //Add a title box using 11 point Arial Bold font. Set the background color //to blue metallic (blueMetalGradient). Use a 1 pixel 3D border. c->addTitle("Hardware Defects", "arialbd.ttf", 11)->setBackground( c->gradientColor(blueMetalGradient), -1, 1); //Set the plotarea at (50, 40) and of 300 x 150 pixels in size. Use //0x80ccccff as the background color. c->setPlotArea(50, 40, 300, 150, 0x80ccccff); //Add a line layer for the pareto line LineLayer *layer = c->addLineLayer(); //Compute the pareto line by accumulating the data ArrayMath lineData = ArrayMath(DoubleArray(data, sizeof(data)/sizeof(*data)) ); lineData.acc(); //Set a scaling factor such as the maximum point of the line is scaled to //100 double scaleFactor = 100 / lineData.max(); //Add the pareto line using the scaled data. Use deep blue (0x80) as the //line color, with light blue (0x9999ff) diamond symbols layer->addDataSet(lineData.mul(scaleFactor), 0x80)->setDataSymbol( DiamondSymbol, 9, 0x9999ff); //Set the line width to 2 pixel layer->setLineWidth(2); //Add a multi-color bar layer using the given data. Bind the layer to the //secondary (right) y-axis. c->addBarLayer(DoubleArray(data, sizeof(data)/sizeof(*data)), IntArray(0, 0) )->setUseYAxis2(); //Set the x axis labels using the given labels c->xAxis()->setLabels(StringArray(labels, sizeof(labels)/sizeof(*labels))); //Set the primary y-axis scale as 0 - 100 with a tick every 20 units c->yAxis()->setLinearScale(0, 100, 20); //Set the label format of the y-axis label to include a percentage sign c->yAxis()->setLabelFormat("{value}%"); //Add a title to the secondary y-axis c->yAxis2()->setTitle("Frequency"); //Set the secondary y-axis label foramt to show no decimal point c->yAxis2()->setLabelFormat("{value|0}"); //Set the relationship between the two y-axes, which only differ by a //scaling factor c->syncYAxis(1 / scaleFactor); //output the chart c->makeChart("pareto.png"); //free up resources delete c; return 0; }