# Charts and graphs

Questions or comments?

## Purpose

Dynamically generates charts and graphs from table data.

This feature dynamically generates charts from table data. The table data used to generate the graphic need to have a structure as defined in the techniques for tables. The graphic generated can be easily customized by using the CSS Option set to the tables elements.

The Charts plugin is an interface between a data table and a drawing charts engine. Currently, for extensibility and to ease support, Flot is the charts drawing engine used.

## Use when

- To publish simple or complex charts online
- Before using an image-based charts approach
- To save time in creating long text descriptions for your charts
- To have uniform charting style accross your website

## Working example

English:

- Charts and graphs - Simple and easy
- Labels and reference values
- Customization, custom presets and multiple charts and graphs types
- Customizing pie charts
- Specific test cases

French:

- Graphiques - Simple
- Étiquettage et valeur de référence
- Personalisation, préréglages personnalisés et plusieurs types de graphique
- Personalisation de diagrame circulaire
- Scénarios d'essai spécifiques

## How to implement

1. Organize your chart's data into a table.

   Tips: You can use the techniques for designing tables

2. Add a `class="wb-charts"` element to the table.

       <table class="wb-charts">

3. Quickly customize your chart by adding predefined preset, via CSS class name, to the table.

       <table class="wb-charts wb-charts-bar">

   or to series header.

       <tr>
       	<th class="wb-charts-bar">
       	[...]
       <tr>
       	<th class="wb-charts-line">
       	[...]

## Tips and trick

### Add floating labels to pie charts

1. Add the `wb-charts-slicelegend` class to the chart table

       <table class="wb-charts wb-charts-slicelegend table">

2. Optional: Add `data-flot` to customize label positioning and label for combined slices.
   - `"label": { "threshold" }` defines the percentage share of the pie slices that will be hidden (ranging 0 to 1) i.e. '0.3' will hide all slices 3% or less of the total. Default is '0.05' (5%).
   - `"combine": { "threshold" }` defines the percentage of pie slices that are combined to a single slice (ranging 0 to 1) i.e. a value of '0.03' will combine all slices 3% or less into one slice. Default is '0.05' (5%).
   - `"combine": { "label" }` defines the label text of the combined slice. Default is "Combined slice" and "Quartier regroupé".

       <table class="wb-charts wb-charts-slicelegend table" data-flot='{
       	"series": {
       		"pie": {
       			"label": {
       				"threshold": 0.05
       			},
       			"combine": {
       				"threshold": 0.05,
       				"label": "Combined slice"
       			}
       		}
       	}
       }'>

### Bypass the data cell value on table parsing

This method should be only used as a last resort when the text Content of the data cell can't be parsed as a numerical value which would be understood when drawing the charts.

Add on a table cell the attribute `data-wb-charts-value` and its value would get parsed by the regular expression to extract the value and the unit.

    <td data-wb-charts-value="200$">two hundred dollars</td>

### Increase white space between series

The following data-flot option can be use to simulate more spacing between each series.

    <table class="wb-charts" data-flot='{ "bars": { "lineWidth": 0.2, "show": true } }'>

The result could look like the following visulalization.

Number of pages by main purpose and audience
| Education | Task | Navigation | Support | Information | Corporate
General | 2 | 0 | 20 | 4 | 100 | 50
Students | 2 | 2 | 1 | 5 | 50 | 0
Business | 60 | 10 | 20 | 90 | 50 | 8
Professional | 46 | 26 | 5 | 101 | 200 | 142
Lawyer | 0 | 2 | 4 | 0 | 300 | 300

- You can apply any flot options documented here: https://github.com/flot/flot/blob/master/API.md
- The bar charts functionality is provided by using the flot third party plugin SideBySideImproved available here: https://github.com/pkoltermann/SideBySideImproved

### Decorative grid customization

The following example configure gradients background color for the grid. The documentation is available in the Customizing the grid section in the flot documentation.

    <table class="wb-charts table" data-flot='{ "grid": { "backgroundColor": { "colors" : [ "#23418A", "#fff" ] } } }'>

Number of pages by main purpose and audience
| Education | Task | Navigation | Support | Information | Corporate
General | 2 | 0 | 20 | 4 | 100 | 50
Students | 2 | 2 | 1 | 5 | 50 | 0
Business | 60 | 10 | 20 | 90 | 50 | 8
Professional | 46 | 26 | 5 | 101 | 200 | 142
Lawyer | 0 | 2 | 4 | 0 | 300 | 300

### Using functions with a custom preset

Supported version: This is supported by all WET 4 version.

Goal: Extracting and parsing custom tabular data to create your chart or graph. If you need just to set plain options, take a look at the Customizing pie charts working example.

#### Declaring your custom preset function

    <script>
    window[ "wb-charts" ] = {
    	charts: {
    		custom: {
    			fn: {
    				"/getcellvalue": function(elem){
    					var raw = $(elem).text().replace(/\s\s+/g, ' ').replace(/^\s+|\s+$/g, '').replace(/N/g, '');
    					return [parseFloat(raw.match(/[\+\-0-9]+[0-9,\. ]*/)), raw.match(/[^\+\-\.\, 0-9]+[^\-\+0-9]*/)];
    				}
    			}
    		}
    	}
    };
    </script>

The key for the `fn` object is similar to the JSON pointer defined in RFC 6901. The key identifies what should be overwritten with the function.

You can rename "custom" by anything you want, just keep in mind of that placeholder name will be the same name for your CSS custom option.

`<table class="wb-charts wb-charts-custom table">`

Contributions to WET from May 5, 2012 to May 4, 2013
Contributor | Commits | Additions | Deletions
--- | --- | --- | ---
pjackson28 | 1N713 | 1N483N907 | 928N648
nschonni | 506 | 90N412 | 72N797
LaurentGoderre | 398 | 52N983 | 29N957
duboisp | 289 | 168N976 | 106N100
patheard | 135 | 6N820 | 3N639
cfarquharson | 85 | 18N572 | 3N518

#### Going beyond

The previous unctionality allowed you to set any javascript function to better control flot plugin and to the call back defined in the flot API core.

The following examples show you how you can control the pie chart label formater. Note that the context has been changed to target directly the flot options.

##### Custom pie chart label formater, code example

    <script>
    window[ "wb-charts" ] = {
    	flot: {
    		mylabelformater: {
    			fn: {
    				"/series/pie/label/formatter": function( label, series ) {
    					var textlabel;
    					if ( !optionsCharts.decimal ) {
    						textlabel = Math.round( series.percent );
    					} else {
    						textlabel = Math.round( series.percent * Math.pow( 10, optionsCharts.decimal ) );
    						textlabel = textlabel / Math.pow( 10, optionsCharts.decimal );
    					}

    					return label + "<br />" + textlabel + "%";
    				}
    			}
    		}
    	}
    };
    </script>

`<table class="wb-charts wb-charts-pie wb-charts-mylabelformater table">`

##### Custom pie chart type, code example

The same result is produced in this example, but the functionality of the 'pie' chart is inherited using the option named base. By doing this, you create a new chart type based on the pie chart while including your customized settings.

    <script>
    window[ "wb-charts" ] = {
    	flot: {
    		mycustompie: {
    			base: "pie",
    			fn: {
    				"/series/pie/label/formatter": function( label, series ) {
    					var textlabel;
    					if ( !optionsCharts.decimal ) {
    						textlabel = Math.round( series.percent );
    					} else {
    						textlabel = Math.round( series.percent * Math.pow( 10, optionsCharts.decimal ) );
    						textlabel = textlabel / Math.pow( 10, optionsCharts.decimal );
    					}

    					return label + "<br />" + textlabel + "%";
    				}
    			}
    		}
    	}
    };
    </script>

`<table class="wb-charts wb-charts-mycustompie table">`

##### Mixing two contexts

You can push you configuration even further by mixing two contexts of settings like flot and charts. When called, the options of both contexts will be applied.

    <script>
    window[ "wb-charts" ] = {
    	flot: {
    		mysuperconfig: {
    			base: "pie",
    			fn: {
    				"/series/pie/label/formatter": function( label, series ) {
    					var textlabel;
    					if ( !optionsCharts.decimal ) {
    						textlabel = Math.round( series.percent );
    					} else {
    						textlabel = Math.round( series.percent * Math.pow( 10, optionsCharts.decimal ) );
    						textlabel = textlabel / Math.pow( 10, optionsCharts.decimal );
    					}

    					return label + "<br />" + textlabel + "%";
    				}
    			}
    		}
    	},
    	charts: {
    		mysuperconfig: {
    			fn: {
    				"/getcellvalue": function(elem){
    					var raw = $(elem).text().replace(/\s\s+/g, ' ').replace(/^\s+|\s+$/g, '').replace(/N/g, '');
    					return [parseFloat(raw.match(/[\+\-0-9]+[0-9,\. ]*/)), raw.match(/[^\+\-\.\, 0-9]+[^\-\+0-9]*/)];
    				}
    			}
    		}
    	}
    };
    </script>

`<table class="wb-charts wb-charts-mysuperconfig table">`

### Other customization for your chart

- Configure the plugin using the `data-wb-charts` on the `table` element. This parameter allows you configure the options on how your data table will be interpreted in a programmatically determined way.

      <table class="wb-charts table" data-wb-charts='{ "referencevalue": 1, "labelposition": 1, "noencapsulation": true }'>

- Configure the plugin using the `data-flot` on the `th` element

      <!-- The following example configure a specific color for a serie -->
      <th data-flot='{"color":"#56E"}'>

### Beyond your customization

- Create your own preset. Take a look at the Customizing pie charts working example.
- Extends with other Flot Plugin. Take a look at Pierre Dubois comment on the Github issue.

### Prioritization of the configuration

1. Javascript JSON object passed through global variable.
2. CSS Preset, will be executed sequentially.
3. HTML5 data attribute.

## Preset configuration options

The following are the available preset, built-in, configuration options specific to wet-charts plugins.

Preset | Inherit | What it does
--- | --- | ---
defaults |  | Sets minimal defaults options for the charts. It contains the instruction to activate the Flot Canvas plugin, the defaults colors array for charting, the defaults function to parse the data content of a table cells.
wb-charts-line |  | Do nothing, here for conviniance and to add more clarity on the charts generated from the data table.
wb-charts-area |  | Customization of a Flot line charts. It's fill the area under the line.
wb-charts-bar |  | Configuration defaults options to create a bars charts. This preset, when detected, will activate the orderbar Flot plugin and set the associated configuration requirement.
wb-charts-pie |  | Default options and activation of the Flot pie chart plugin. It set a default label formater function for the pie chart labels.
wb-charts-donut | wb-charts-pie | Build on pie charts preset. It set default options that will transform the pie chart into a donut charts. Also set the pie label formater to use only one decimal precision
wb-charts-stacked | wb-charts-bar | Only for series. Avoid to be cought and have no impact on how the orderbar plugin will be configured.
wb-charts-thousandcomma |  | This option was removed by #6614 in favor of an i18n solution. Replace the function to parse the data content of a table cells in order to support thousand comma separator numbers.
wb-charts-thousanddot |  | This option was removed by #6614 in favor of an i18n solution. Replace the function to parse the data content of a table cells in order to support thousand dot separator numbers

## Configuration options

For any configuration options related to Flot, please look at the Flot Reference documentation or/and the pie charts options.

The following configuration options are specific to wet-charts plugins.

Option | Description | How to configure | Values
--- | --- | --- | ---
reversettblparsing | Define how the data table should be traversed. The default traversal direction is the same as the direction defined in HTML spec. The HTML spec direction is row base. Holds a boolean value. | data-wb-charts='{ "reversettblparsing": true }' | false (default): The data of the table will be parsed in the row direction true: The data of the table will be parsed in the column direction
labelposition | Specify the row or the column to use to set label on the charts. A vector is a row or column where the direction is of no importance. Holds a numeric value. | data-wb-charts='{ "labelposition": 1 }' | false (default): false means the deepest vector will be used for labelling 1: First vector is used to set labels on the chart 2: Second vector is used to set labels on the chart Numerical Value: The numeric value represent the number of vector in the header group that will be use to set labels on the chart
referencevalue | Specify the row or the column to use as the value of reference to set the steps (x-axis ticks) on the charts. A vector is a row or column where the direction has no importance. Holds a numeric value. | data-wb-charts='{ "referencevalue": 1 }' | false (default): false means the deepest vector will be used for calculate the reference 1: First vector is used to set the value of reference steps on the chart 2: Second vector is used to set the value of reference steps on the chart Numerical Value: The numeric value represents the number of vectors in the header group that will be used to set the value of reference steps on the chart
decimal | For pie charts, sets the percentage label decimal precision. Holds a numeric value | data-wb-charts='{ "decimal": 1 }' | 0 (default): The percentage label will include no decimal 1: One decimal of the percentage label will included. Numerical Value: Number of decimal to be included in the percentage pie label.
nolegend | Ability to destroy the flot-generated legend. Hold a boolean value. | data-wb-charts='{ "nolegend": true }' | false (default): Flot creates the legend, as it does by default true: The legend will be destroyed. It may also allow you to have pie label on each pie quarter.
legendinline | Ability to move the flot-generated legend after the table to meet WCAG 2.0 Level AA guidelines. Holds a boolean value. | data-wb-charts='{ "legendinline": true }' | false (default): The DOM produced by flot will be manipulated to move the legend from inside the charts to next to it true: No DOM manipulation. This may allow more control when using the flot labeling options.
noencapsulation | Wrap or not the table in details/summary elements. Holds a boolean value. | data-wb-charts='{ "noencapsulation": true }' | false: The table will be wrapped in details/summary elements. Default when table has caption. true: The table will be left as is. Default when table has no caption.
height | Sets the height of a chart. Holds numeric value mesured in pixels. | data-wb-charts='{ "height": 350 }' | $elm.height() (default): The height, in pixels, of the table. If unknown, it would use a value of 200 pixels. Numerical Value: Number of pixel that represent the chart's height.
width | Set the width of a chart. It may useful for pie charts but are useless for other charts because the Flot Canvas plugin will allow the charts to fit the full width of the table container. Holds a numeric value mesured in pixel. | data-wb-charts='{ "width": 350 }' | $elm.width() (default): The width, in pixels, of the table, if unknow it would use a value of 200 pixels. Numerical Value: Number of pixel that represent the chart's width.

## Events

Document the public events that can be used by implementers or developers.

Event | Trigger | What it does
--- | --- | ---
`wb-init.wb-charts` | Triggered manually (e.g., `$elm.trigger( "wb-init.wb-charts" );`). | Used to manually initialize the Charts plugin. Note: The Charts plugin will be initialized automatically unless the required markup is added after the page has already loaded.
`wb-ready.wb-charts` (v4.0.5+) | Triggered automatically after a chart initializes. | Used to identify which chart was initialized (target of the event)
    $( document ).on( "wb-ready.wb-charts", ".wb-charts", function( event ) {
    });
    $elm.on( "wb-ready.wb-charts", function( event ) {
    });
`wb-updated.wb-charts` (v4.0.5+) | Triggered automatically each time the chart is updated. | Used to identify which chart was updated (target of the event)
    $( document ).on( "wb-updated.wb-charts", ".wb-charts", function( event ) {
    });
    $elm.on( "wb-updated.wb-charts", function( event ) {
    });
`wb-ready.wb` (v4.0.5+) | Triggered automatically when WET has finished loading and executing. | Used to identify when all WET plugins and polyfills have finished loading and executing.
    $( document ).on( "wb-ready.wb", function( event ) {
    });
passiveparse.wb-tableparser | When the charts need the table parser to parse the table. When this event is triggered, the Flot library is loaded. You can also take advantage of this event to load your own Flot plugin. | It will parse the data table and attach the information to a data attribute named tblparser on every element that is related to the table.
parsecomplete.wb-tableparser | When the table parser has completed its parsing job. | Indicates that the tblparser data attribute is now ready to be used. It is after this event that the data will be prepared for Flot. Then the charts will be created.

## Source code

- Core: Charts plugin
- Dependency: Complex Table Parser
- Dependency: Flot
- Flot Pluging third party dependency: SideBySideImproved

Date modified:
  2015-03-10