Difference between revisions of "Charts API"

Jump to: navigation, search
Line 3: Line 3:
 
== Overview ==
 
== Overview ==
  
On the roadmap for Moodle 3.2 was added the requirement for a new charting library.
+
The Charts API is a core set of methods intended to provide a simple and yet modern interface to generate dynamic charts.
  
  
== Requirements ==
+
== Chart types ==
The requirements can be split in two different categories, the rendering, and the API.
 
  
=== Rendering ===
+
The first step to create a new chart is to create an instance of the desired chart type.  
The rendering of the charts must occur on the client-side, in Javascript. It must be visually pleasing without the need for a lot of customisation.
+
At the moment bar, line and pie types are supported and using some display changing methods can change how the charts are displayed.
It has to be accessible, support translation and right-to-left languages. It must reasonably support large datasets and dynamic data changes, for instance
 
when fetching and including more data from an Ajax request.
 
The charts generated can be printed. Aside the feature requiremements, the library itself has to be mature, stable and under active development.
 
Its popularity on networks such as Github and Stackoverflow is a good indicator. It must also be downloadable to be shipped and served locally from Moodle.
 
  
=== The API ===
+
=== Bar ===  
Simplicity is the main keyword here. Programmatically creating a new chart must be as simple as possible.  
+
To create a new bar chart, just create a new instance of '''chart_bar''' class.
The API has to be designed so that using a different rendering engine later on is possible (when switching to another library).
+
<code php>
The API must be available from both PHP and Javascript, so that a chart can be created from any of these even if its rendering will happen solely in Javascript.
+
$chart = new core\chart_bar();
 +
</code>
  
== The winner is ==
+
You might want change how your bar chart are displayed:
'''Chart.js wins'''
 
We have investigated the following libraries:
 
Chart.js
 
Highcharts
 
CanvasJS
 
Chartist
 
n3
 
Google Charts
 
Flot/jQuery
 
D3
 
Plotly.js/D3
 
C3/D3
 
nvd3/D3
 
dimple-js/D3
 
dc-js/D3
 
metricsgraphicsjs/D3
 
ECharts
 
After considering popularity (Github stars, contributors, Stackoverflow questions), license, maturity, and relative simplicity, we shortlisted these:
 
C3
 
Chart.js
 
Echarts
 
Chart.js won because it is the most popular even though it only contains a limited set of chart types. Echarts was very promising but the community around it being mainly non-English speaking felt risky as getting help online would be much harder. C3 is a layer on top of D3 with aim to provide a simpler charting solution, however its popularity was quite limited compared to the other ones.
 
Other more or less popular libraries could have been discarded because of their license, complexity, or being an overkill for what we need.
 
  
== The API ==
+
==== Stacked Bar ====
Just as the requirements, the API was split in two different categories, the chart structure, and the rendering.
+
To display stacked bars, you can call '''set_stacked()''' method, setting the parameter to true.
Data structure
+
<code php>
In order to create a library agnostic to the rendering mechanism used, the API must construct a data structure representing the chart.
+
$chart = new core\chart_bar();
Not only it needs to contain the data to be displayed, but also some information on the display itself, such as the type of chart, the axis labels, etc...
+
$char->set_stacked(true); //Calling set_stacked() passing true as parameter will display stacked bars.
The goal of the data structure is not to contain all the rendering options offered by the multitude of charting libraries out there, it is simply to advise the rendering
+
</code>
method on how the data should be presented. As much as possible the options have to remain simple. For example the data structure will not contain a parameter
+
 
determining the thickness of the lines in a chart, that is the sole responsibility of the rendering engine.
+
==== Horizontal Bar ====
The API to construct the data structure of a chart is available in both PHP and Javascript, however it is acceptable for the validation of the data to only occur in Javascript.  
+
To display you bar chart in the horizontal position, you need to call '''set_horizontal()''':
This to avoid duplicating too much code, especially as Javascript is always invoked for rendering purposes.
+
<code php>
The PHP objects of the API implement the built-in interface jsonSerializable. The serialisation will be the mechanism used to export a PHP-made structure to Javascript as a JSON object. Only PHP needs to support the serialisation. The Javascript API implements the mechanism to restore a chart structure from JSON data.
+
$chart = new core\chart_bar();
Whilst limiting, it is important to not oversee the benefits of this data structure. It creates a self-documenting API exposing the different attributes and methods a data structure supports. It streamlines the data visualisation to its essential components, offering a quick and easy way to implement new charts to developers without the need for a knowledge of the rendering library. And it allows for a chart structure to be exported to any Moodle frontend such as the Web interface, but also the mobile app.
+
$char->set_horizontal(true); // Calling set_horizontal() passing true as parameter will display horizonal bar charts.
== Rendering ==
+
</code>
This part of the API only happens in Javascript. The rendering engine receives the data structure and converts it to a visualisation of this data. Mainly this will translate the data structure into the format expected by existing charting libraries and output the result. This allows for an instant migration to another charting library, simply by replacing the rendering engine, and for custom rendering engines such as outputting the chart data to a table for accessibility purposes.
+
 
The engine can be notified that the chart data structure has changed and that the output needs to be updated.
+
=== Line ===
Moodle will ship with an output engine for Chart.js and another one to generate HTML tables.
+
To create a new line chart, just create an instance of '''chart_line''' class. By default, lines are tensioned.  
 +
<code php>
 +
$chart = new core\chart_line();
 +
</code>
 +
 
 +
==== Smooth lines ====
 +
You might want to change you line chart to display '''smooth lines''':
 +
<code php>
 +
$chart = new core\chart_line();
 +
$chart->set_smooth(true); // Calling set_smooth() passing true as parameter, will display smooth lines.
 +
</code>
 +
 
 +
=== Pie ===
 +
To create a pie chart you just need to create a new instance of chart_pie class.
 +
<code php>
 +
$chart = new core\chart_pie();
 +
</code>
 +
 
 +
==== Doughnut ====
 +
You might want to change you pie chart to be displayed as doughnut:
 +
<code php>
 +
$chart->set_doughnut(true);
 +
</code>
 +
 
 +
== Series ==
 +
Series can be defined as a set of values. To set series of a chart, you need to create an instance of '''chart_series''' object and pass the title and an array of values.
 +
The title and the data are displayed when mouse over the specific point representing the serie on the chart.
 +
'''The number of values of the series must be equal to the number of labels.'''
 +
<code php>
 +
$serie1 = new core\chart_series('My series title', [400, 460, 1120, 540]);
 +
</code>
 +
 
 +
== Properties ==
 +
 
 +
=== Title ===
 +
It is possible to set a title for a chart, by calling set_title and passing the title as string method.
 +
<code php>
 +
$chart->set_title('chart with a title');
 +
</code>
 +
 
 +
=== Labels ===
 +
Labels are the description in which the data will be grouped, in the example above labels are an array of years. The number of values on the series must match the number of labels.
 +
<code php>
 +
$chart->set_labels(['2004', '2005', '2006', '2007']);
 +
</code>
 +
 
 +
== Axis ==
 +
 
 +
 
 +
 
 +
== Mixed chart types ==
 +
It is possible to combine two types of chart by setting the type of the series differently of the chart type. For example, to create a chart that combine a bar chart with a line chart:
 +
<code php>
 +
$chart = new \core\chart_bar(); // Create a bar chart instance.
 +
$series1 = new \core\chart_series('Series 1 (Bar)', [1000, 1170, 660, 1030]);
 +
$series2 = new \core\chart_series('Series 2 (Line)', [400, 460, 1120, 540]);
 +
$series2->set_type(\core\chart_series::TYPE_LINE); // Set the series type to line chart.
 +
$chart->add_series($series2);
 +
$chart->add_series($series1);
 +
$chart->set_labels(['2004', '2005', '2006', '2007']);
 +
</code>
 +
Please note the order you call add_series change the order series are displayed on the chart. In the example above, the first to be displayed will be line chart and in the background the bar chart.
 +
 
 +
== Renderering ==
 +
All charts are rendered by render_chart() located on outputrenderers.php, once the chart object is ready, it must be passed to chart_render.
 +
<cide php>
 +
echo $OUTPUT->render($chart);
 +
</code>
 +
 
 +
=== Show chart data ===
 +
To make the chart data accessible to users with special needs, a link on the bottom of the chart will display a table containing all data.  
 +
In some cases, the same information is displayed on the page and might not be necessary display chart table.  
 +
In that case, you need to pass false as the second parameter when calling the render:
 +
<code php>
 +
echo $OUTPUT->render($chart, false);
 +
</code>

Revision as of 06:01, 29 November 2016

Moodle 3.2


Overview

The Charts API is a core set of methods intended to provide a simple and yet modern interface to generate dynamic charts.


Chart types

The first step to create a new chart is to create an instance of the desired chart type. At the moment bar, line and pie types are supported and using some display changing methods can change how the charts are displayed.

Bar

To create a new bar chart, just create a new instance of chart_bar class.

$chart = new core\chart_bar();

You might want change how your bar chart are displayed:

Stacked Bar

To display stacked bars, you can call set_stacked() method, setting the parameter to true.

$chart = new core\chart_bar();
$char->set_stacked(true); //Calling set_stacked() passing true as parameter will display stacked bars.

Horizontal Bar

To display you bar chart in the horizontal position, you need to call set_horizontal():

$chart = new core\chart_bar();
$char->set_horizontal(true); // Calling set_horizontal() passing true as parameter will display horizonal bar charts.

Line

To create a new line chart, just create an instance of chart_line class. By default, lines are tensioned.

$chart = new core\chart_line();

Smooth lines

You might want to change you line chart to display smooth lines:

$chart = new core\chart_line();
$chart->set_smooth(true); // Calling set_smooth() passing true as parameter, will display smooth lines.

Pie

To create a pie chart you just need to create a new instance of chart_pie class.

$chart = new core\chart_pie();

Doughnut

You might want to change you pie chart to be displayed as doughnut:

$chart->set_doughnut(true);

Series

Series can be defined as a set of values. To set series of a chart, you need to create an instance of chart_series object and pass the title and an array of values. The title and the data are displayed when mouse over the specific point representing the serie on the chart. The number of values of the series must be equal to the number of labels.

$serie1 = new core\chart_series('My series title', [400, 460, 1120, 540]);

Properties

Title

It is possible to set a title for a chart, by calling set_title and passing the title as string method.

$chart->set_title('chart with a title');

Labels

Labels are the description in which the data will be grouped, in the example above labels are an array of years. The number of values on the series must match the number of labels.

$chart->set_labels(['2004', '2005', '2006', '2007']);

Axis

Mixed chart types

It is possible to combine two types of chart by setting the type of the series differently of the chart type. For example, to create a chart that combine a bar chart with a line chart:

$chart = new \core\chart_bar(); // Create a bar chart instance.
$series1 = new \core\chart_series('Series 1 (Bar)', [1000, 1170, 660, 1030]);
$series2 = new \core\chart_series('Series 2 (Line)', [400, 460, 1120, 540]);
$series2->set_type(\core\chart_series::TYPE_LINE); // Set the series type to line chart.
$chart->add_series($series2);
$chart->add_series($series1);
$chart->set_labels(['2004', '2005', '2006', '2007']);

Please note the order you call add_series change the order series are displayed on the chart. In the example above, the first to be displayed will be line chart and in the background the bar chart.

Renderering

All charts are rendered by render_chart() located on outputrenderers.php, once the chart object is ready, it must be passed to chart_render. <cide php> echo $OUTPUT->render($chart); </code>

Show chart data

To make the chart data accessible to users with special needs, a link on the bottom of the chart will display a table containing all data. In some cases, the same information is displayed on the page and might not be necessary display chart table. In that case, you need to pass false as the second parameter when calling the render:

echo $OUTPUT->render($chart, false);