Skip to content

Commit

Permalink
Implement multiple labels per data element
Browse files Browse the repository at this point in the history
  • Loading branch information
simonbrunel committed Sep 3, 2019
1 parent 9bd22fa commit e1347fc
Show file tree
Hide file tree
Showing 30 changed files with 971 additions and 79 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Requires [Chart.js](https://github.com/chartjs/Chart.js/releases) **2.7.0** or l
- [Introduction](https://chartjs-plugin-datalabels.netlify.com/guide/)
- [Getting Started](https://chartjs-plugin-datalabels.netlify.com/guide/getting-started.html)
- [Options](https://chartjs-plugin-datalabels.netlify.com/guide/options.html)
- [Labels](https://chartjs-plugin-datalabels.netlify.com/guide/labels.html)
- [Positioning](https://chartjs-plugin-datalabels.netlify.com/guide/positioning.html)
- [Formatting](https://chartjs-plugin-datalabels.netlify.com/guide/formatting.html)
- [Events](https://chartjs-plugin-datalabels.netlify.com/guide/events.html)
Expand Down
1 change: 1 addition & 0 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module.exports = {
'/guide/',
'/guide/getting-started',
'/guide/options',
'/guide/labels',
'/guide/positioning',
'/guide/formatting',
'/guide/events'
Expand Down
1 change: 1 addition & 0 deletions docs/guide/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This plugin doesn't provide any public API (except the plugin options), thus you

* [Getting Started](getting-started.md)
* [Options](options.md)
* [Labels](labels.md)
* [Positioning](positioning.md)
* [Formating](formatting.md)
* [Events](events.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ This plugin currently supports the following label events:

## Listeners

The `listeners` option allows to register callbacks to be notified when an event is detected on a specific label. This option is an object where the property is the type of the event to listen and the value is a callback with a unique `context` argument.
The `listeners` option allows to register callbacks to be notified when an event is detected on a specific label. This option is an object where each property represents an event, the key being the type of the event to listen and the value being a callback accepting a unique `context` argument.

The `context` contains the same information as for [scriptable options](options.md#option-context), can be modified (e.g. add new properties) and thus, **if the callback explicitly returns `true`**, the label is updated with the new context and the chart re-rendered. This allows to implement visual interactions with labels such as highlight, selection, etc.

Expand Down
150 changes: 150 additions & 0 deletions docs/guide/labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# Labels

By default, a single label is created per data, however, it's possible to define multiple labels for each data element using the `labels` options. This option is an object where each property represents a new label, the key being the label key and the value being the options specific to each label. These options are merged on top of the options defined at the chart **and** dataset levels.

## Multiple Labels

The following snippet creates two labels for every data element, the first with `title` as key and the second with `value` as key. The `title` label text is blue with font in bold. The `value` label text is green with normal font.

```js
{
options: {
plugins: {
datalabels: {
color: 'blue',
labels: {
title: {
font: {
weight: 'bold'
}
},
value: {
color: 'green'
}
}
}
}
}
}
```

## Dataset Overrides

While the previous example creates multiple labels with the same options for all datasets, it's possible to add, modify and remove labels for specific datasets by referring to the label key.

### Modifying Labels

To modify a label for a specific dataset, create an entry in the `labels` dataset options using the same key:

```js
{
data: {
datasets: [{
// First dataset.
datalabels: {
color: 'yellow'
}
}, {
// Second dataset.
datalabels: {
labels: {
title: {
color: 'green'
}
}
}
}]
},
options: {
plugins: {
datalabels: {
color: 'pink',
labels: {
value: {},
title: {
color: 'blue'
}
}
}
}
}
}
```

This example creates for each data element in the *first* dataset:
- a `value` label with text in yellow
- a `title` label with text in blue

and for each data element in the *second* dataset:
- a `value` label with text in pink
- a `title` label with text in green

::: warning IMPORTANT
Options defined under each `labels.<key>` always override options defined at the chart **and** dataset level (in the previous example, the `title` label text of the *first* dataset is blue, not yellow).
:::

### Adding Label

To add a new label to a specific dataset, create an entry under the `labels` dataset options using a *inexistent* label key. The following example creates one label (`title`) for each data element in the *first* dataset and two labels (`title` and `value`) for each data element in the *second* dataset:

```js
{
data: {
datasets: [{
// First dataset.
}, {
// Second dataset.
datalabels: {
labels: {
value: {
color: 'green'
}
}
}
}]
},
options: {
plugins: {
datalabels: {
labels: {
title: {
color: 'blue'
}
}
}
}
}
}
```

### Removing Label

To remove a label for a specific dataset, create an `null` entry under the `labels` dataset options for the key of the label to remove. The following example removes the `title` label in the *second* dataset:

```js
{
data: {
datasets: [{
// First dataset.
}, {
// Second dataset.
datalabels: {
labels: {
title: null
}
}
}]
},
options: {
plugins: {
datalabels: {
labels: {
title: {
color: 'blue'
}
}
}
}
}
}
```
13 changes: 8 additions & 5 deletions docs/guide/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The following table lists all available options:
| `font.weight` | `string` | - | - | `'normal'`
| [`font.lineHeight`](formatting.md#multiline-labels) | `number` \| `string` | - | - | `1.2`
| [`formatter`](formatting.md#data-transformation) | `function` \| `null` | - | - | -
| [`labels`](labels.md) | `object` | - | - | `undefined`
| [`listeners`](events.md) | `object` | - | - | `{}`
| [`offset`](positioning.md#alignment-and-offset) | `number` | Yes | Yes | `4`
| `opacity` | `number` | Yes | Yes | `1`
Expand Down Expand Up @@ -62,11 +63,13 @@ The option context is used to give contextual information when resolving options

The context object contains the following properties:

- `active` (bool): whether the associated element is hovered ([see interactions](http://www.chartjs.org/docs/latest/general/interactions/))
- `chart` (Chart): the associated chart
- `dataIndex` (int): index of the associated data
- `dataset` (object): the dataset at index `datasetIndex`
- `datasetIndex` (int): index of the associated dataset
| Property | Type | Description
| -------- | ---- | -----------
| `active` | `bool` | Whether the associated element is hovered ([see interactions](http://www.chartjs.org/docs/latest/general/interactions/)).
| `chart` | `Chart` | The associated chart.
| `dataIndex` | `number` | The index of the associated data.
| `dataset` | `object` | The dataset at index `datasetIndex`.
| `datasetIndex` | `number` | The index of the associated dataset.

## Indexable Options

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

<script>
var SAMPLE_INFO = {
group: 'Formatting',
group: 'Advanced',
name: 'Custom Labels',
desc: 'This example displays the data labels instead ' +
'of the data values, using a custom formatter'
Expand Down
176 changes: 176 additions & 0 deletions samples/advanced/multiple-labels.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="../style.css">
<link rel="icon" type="image/ico" href="../favicon.ico">
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.7.0/dist/Chart.min.js"></script>
<script src="../../dist/chartjs-plugin-datalabels.js"></script>
<script src="../utils.js"></script>
</head>
<body>
<div id="side">
<div id="header"></div>
<div id="actions">
<button onclick="randomize(this)">Randomize</button>
</div>
</div>

<div id="charts">
<div class="wrapper"><canvas id="chart-0"></canvas></div>
</div>

<script>
var SAMPLE_INFO = {
group: 'Advanced',
name: 'Multiple Labels',
desc: 'This example displays 3 labels per data, one for the '
+ 'index, one for the label and one for the value. Move '
+ 'the mouse over the chart to display label ids.'
};
</script>

<script id="script-init">
var DATA_COUNT = 4;
var labels = [
'Earth',
'Mars',
'Saturn',
'Jupiter'
];

Samples.srand(4);

Chart.helpers.merge(Chart.defaults.global, {
aspectRatio: 4 / 3,
tooltips: false,
layout: {
padding: {
top: 42,
right: 16,
bottom: 32,
left: 8
}
},
elements: {
line: {
fill: false
},
point: {
hoverRadius: 7,
radius: 5
}
},
plugins: {
legend: false,
title: false
}
});
</script>

<script id="script-construct">
var chart = new Chart('chart-0', {
type: 'doughnut',
data: {
labels: labels,
datasets: [{
backgroundColor: Samples.colors({
color: Samples.color(1),
mode: 'darken'
}),
hoverBorderColor: 'white',
data: Samples.numbers({
count: DATA_COUNT,
min: 0,
max: 100
}),
datalabels: {
labels: {
index: {
align: 'end',
anchor: 'end',
color: function(ctx) {
return ctx.dataset.backgroundColor;
},
font: {size: 18},
formatter: function(value, ctx) {
return ctx.active
? 'index'
: '#' + (ctx.dataIndex + 1);
},
offset: 8,
opacity: function(ctx) {
return ctx.active ? 1 : 0.5;
}
},
name: {
align: 'top',
font: {size: 16},
formatter: function(value, ctx) {
return ctx.active
? 'name'
: ctx.chart.data.labels[ctx.dataIndex];
}
},
value: {
align: 'bottom',
backgroundColor: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 50 ? 'white' : null;
},
borderColor: 'white',
borderWidth: 2,
borderRadius: 4,
color: function(ctx) {
var value = ctx.dataset.data[ctx.dataIndex];
return value > 50
? ctx.dataset.backgroundColor
: 'white';
},
formatter: function(value, ctx) {
return ctx.active
? 'value'
: Math.round(value * 1000) / 1000;
},
padding: 4
}
}
}
}]
},
options: {
cutoutPercentage: 8,
padding: 64,
plugins: {
datalabels: {
color: 'white',
display: function(ctx) {
return ctx.dataset.data[ctx.dataIndex] > 10;
},
font: {weight: 'bold'},
offset: 0,
padding: 0
}
}
}
});
</script>

<script id="script-actions">
function randomize() {
chart.data.datasets.forEach(function(dataset, i) {
dataset.backgroundColor = Samples.colors({
color: Samples.color(),
mode: 'darken'
});
dataset.data = dataset.data.map(function(value) {
return Samples.rand(0, 100);
});
});
chart.update();
}
</script>
</body>
</html>
Loading

0 comments on commit e1347fc

Please sign in to comment.