Vuepress samples (#8756)

* Generate API docs with vuepress-plugin-typedoc

* Links, fixes, cleanup

* Convert bar samples to Vuepress

* Some line chart samples moved over

* Fix lint issues

* Derived axis type sample

* LineAreaStacked chart created in vuepress

* added radar area axample

* Line dataset added sample

* final area example added

* Add derived-chart-type

* Bar scriptable sample

* Scriptable samples

* Clean lint errors

* added linear axis samples to vuepress

* change tab to spaces to fix lint error

* Convert the rest of the scale samples

* Scale option samples

* Fix typo

* Fixes

* Legend samples

* Title samples

* Change the title of the tip block to Note (#8758)

* Convert bar samples to Vuepress

* Some line chart samples moved over

* Fix lint issues

* Derived axis type sample

* LineAreaStacked chart created in vuepress

* added radar area axample

* Line dataset added sample

* final area example added

* Add derived-chart-type

* Bar scriptable sample

* Scriptable samples

* Clean lint errors

* added linear axis samples to vuepress

* change tab to spaces to fix lint error

* Convert the rest of the scale samples

* Scale option samples

* Fix typo

* Fixes

* Legend samples

* Advanced samples

* Remove extra section

* Animation samples

* Hide legend from progressive line

* Add a comment on what `from` does

* Tooltip samples

* Ädd other charts to vuepress samples

* enable plugin again since all samples have been converted

* fix skip radar example, middle skip was not calculated correctly

* lint error

* Progressive-line: add 2nd line

* Fix lint errors

Co-authored-by: Jukka Kurkela <jukka.kurkela@gmail.com>
Co-authored-by: Jacco van den Berg <jaccoberg2281@gmail.com>
Co-authored-by: Jacco van den Berg <39033624+LeeLenaleee@users.noreply.github.com>
This commit is contained in:
Evert Timberg
2021-04-02 08:04:39 -04:00
committed by GitHub
parent 49f8fab448
commit 66ee0fecaf
72 changed files with 6616 additions and 5 deletions

View File

@@ -21,7 +21,6 @@ module.exports = {
],
[
'vuepress-plugin-typedoc',
{
entryPoints: ['../../types/index.esm.d.ts'],
hideInPageTOC: true,
@@ -58,13 +57,15 @@ module.exports = {
imports: [
['scripts/register.js'],
['scripts/utils.js', 'Utils'],
['scripts/helpers.js', 'helpers'],
['scripts/components.js', 'components']
]
},
nav: [
{text: 'Home', link: '/'},
{text: 'API', link: '/api/'},
// TODO: Make local when samples moved to vuepress
{text: 'Samples', link: `https://www.chartjs.org/samples/${docsVersion}/`},
{text: 'Samples', link: `/samples/`},
{
text: 'Ecosystem',
ariaLabel: 'Community Menu',
@@ -79,6 +80,131 @@ module.exports = {
'/api/': {
title: 'API'
},
'/samples/': [
'',
{
title: 'Bar Charts',
children: [
'bar/vertical',
'bar/horizontal',
'bar/stacked',
'bar/stacked-groups',
'bar/floating',
'bar/border-radius',
]
},
{
title: 'Line Charts',
children: [
'line/line',
'line/multi-axis',
'line/stepped',
'line/interpolation',
'line/styling',
// 'line/point-styling',
]
},
{
title: 'Other charts',
children: [
'other-charts/bubble',
'other-charts/scatter',
'other-charts/scatter-multi-axis',
'other-charts/doughnut',
'other-charts/pie',
'other-charts/multi-series-pie',
'other-charts/polar-area',
'other-charts/radar',
'other-charts/radar-skip-points',
'other-charts/combo-bar-line',
]
},
{
title: 'Area charts',
children: [
'area/line-boundaries',
'area/line-datasets',
'area/line-stacked',
'area/radar'
]
},
{
title: 'Scales',
children: [
'scales/linear-min-max',
'scales/linear-min-max-suggested',
'scales/linear-step-size',
'scales/log',
'scales/time-line',
'scales/time-max-span',
'scales/time-combo',
]
},
{
title: 'Scale Options',
children: [
'scale-options/grid',
'scale-options/ticks',
'scale-options/titles',
'scale-options/center'
]
},
{
title: 'Legend',
children: [
'legend/position',
'legend/title',
'legend/point-style',
]
},
{
title: 'Title',
children: [
'title/alignment',
]
},
{
title: 'Tooltip',
children: [
'tooltip/position',
'tooltip/interactions',
'tooltip/point-style',
'tooltip/content',
'tooltip/html',
]
},
{
title: 'Scriptable Options',
children: [
'scriptable/bar',
'scriptable/bubble',
'scriptable/pie',
'scriptable/line',
'scriptable/polar',
'scriptable/radar',
]
},
{
title: 'Animations',
children: [
'animations/delay',
'animations/drop',
'animations/loop',
'animations/progressive-line',
]
},
{
title: 'Advanced',
children: [
'advanced/progress-bar',
'advanced/radial-gradient',
'advanced/linear-gradient',
'advanced/programmatic-events',
'advanced/derived-axis-type',
'advanced/derived-chart-type',
]
},
],
'/': [
'',
{

View File

@@ -0,0 +1,50 @@
# Derived Axis Type
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 12;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 1000};
const labels = Utils.months({count: DATA_COUNT});
const data = {
labels: labels,
datasets: [
{
label: 'My First dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
fill: false,
}
],
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data,
options: {
responsive: true,
scales: {
x: {
display: true,
},
y: {
display: true,
type: 'log2',
}
}
}
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```
## Log2 axis implementation
<<< @/docs/scripts/log2.js

View File

@@ -0,0 +1,46 @@
# Derived Chart Type
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100, rmin: 1, rmax: 20};
const data = {
datasets: [
{
label: 'My First dataset',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
borderColor: Utils.CHART_COLORS.blue,
borderWidth: 1,
boxStrokeStyle: 'red',
data: Utils.bubbles(NUMBER_CFG)
}
],
};
// </block:setup>
// <block:config:0>
const config = {
type: 'derivedBubble',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Derived Chart Type'
},
}
}
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```
## DerivedBubble Implementation
<<< @/docs/scripts/derived-bubble.js

View File

@@ -0,0 +1,110 @@
# Linear Gradient
```js chart-editor
// <block:actions:3>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:getGradient:0>
let width, height, gradient;
function getGradient(ctx, chartArea) {
const chartWidth = chartArea.right - chartArea.left;
const chartHeight = chartArea.bottom - chartArea.top;
if (gradient === null || width !== chartWidth || height !== chartHeight) {
// Create the gradient because this is either the first render
// or the size of the chart has changed
width = chartWidth;
height = chartHeight;
gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, Utils.CHART_COLORS.blue);
gradient.addColorStop(0.5, Utils.CHART_COLORS.yellow);
gradient.addColorStop(1, Utils.CHART_COLORS.red);
}
return gradient;
}
// </block:getGradient>
// <block:setup:2>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: function(context) {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) {
// This case happens on initial chart load
return null;
}
return getGradient(ctx, chartArea);
},
},
]
};
// </block:setup>
// <block:config:1>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,103 @@
# Programmatic Event Triggers
```js chart-editor
// <block:hover:0>
function triggerHover(chart) {
if (chart.getActiveElements().length > 0) {
chart.setActiveElements([]);
} else {
chart.setActiveElements([
{
datasetIndex: 0,
index: 0,
}, {
datasetIndex: 1,
index: 0,
}
]);
}
chart.update();
}
// </block:hover>
// <block:tooltip:1>
function triggerTooltip(chart) {
const tooltip = chart.tooltip;
if (tooltip.getActiveElements().length > 0) {
tooltip.setActiveElements([], {x: 0, y: 0});
} else {
const chartArea = chart.chartArea;
tooltip.setActiveElements([
{
datasetIndex: 0,
index: 2,
}, {
datasetIndex: 1,
index: 2,
}
],
{
x: (chartArea.left + chartArea.right) / 2,
y: (chartArea.top + chartArea.bottom) / 2,
});
}
chart.update();
}
// </block:tooltip>
// <block:actions:2>
const actions = [
{
name: 'Trigger Hover',
handler: triggerHover
},
{
name: 'Trigger Tooltip',
handler: triggerTooltip
}
];
// </block:actions>
// <block:setup:4>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
hoverBorderWidth: 5,
hoverBorderColor: 'green',
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
hoverBorderWidth: 5,
hoverBorderColor: 'green',
}
]
};
// </block:setup>
// <block:config:3>
const config = {
type: 'bar',
data: data,
options: {
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,129 @@
# Animation Progress Bar
<progress id="animationProgress" max="1" value="0" style="width: 100%"></progress>
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const progress = document.getElementById('animationProgress');
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
animation: {
duration: 2000,
onProgress: function(animation) {
progress.value = animation.currentStep / animation.numSteps;
},
onComplete: function() {
//
}
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Animation Progress Bar'
}
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,116 @@
# Radial Gradient
```js chart-editor
// <block:setup:3>
const DATA_COUNT = 5;
Utils.srand(110);
const chartColors = Utils.CHART_COLORS;
const colors = [chartColors.red, chartColors.orange, chartColors.yellow, chartColors.green, chartColors.blue];
const cache = new Map();
let width = null;
let height = null;
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:createRadialGradient3:0>
function createRadialGradient3(context, c1, c2, c3) {
const chartArea = context.chart.chartArea;
if (!chartArea) {
// This case happens on initial chart load
return null;
}
const chartWidth = chartArea.right - chartArea.left;
const chartHeight = chartArea.bottom - chartArea.top;
if (width !== chartWidth || height !== chartHeight) {
cache.clear();
}
var gradient = cache.get(c1 + c2 + c3);
if (!gradient) {
// Create the gradient because this is either the first render
// or the size of the chart has changed
width = chartWidth;
height = chartHeight;
const centerX = (chartArea.left + chartArea.right) / 2;
const centerY = (chartArea.top + chartArea.bottom) / 2;
const r = Math.min(
(chartArea.right - chartArea.left) / 2,
(chartArea.bottom - chartArea.top) / 2
);
var ctx = context.chart.ctx;
gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, r);
gradient.addColorStop(0, c1);
gradient.addColorStop(0.5, c2);
gradient.addColorStop(1, c3);
cache.set(c1 + c2 + c3, gradient);
}
return gradient;
}
// </block:createRadialGradient3>
// <block:data:2>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
});
}
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [{
data: generateData()
}]
};
// </block:data>
// <block:config:1>
const config = {
type: 'polarArea',
data: data,
options: {
plugins: {
legend: false,
tooltip: false,
},
elements: {
arc: {
backgroundColor: function(context) {
let c = colors[context.dataIndex];
if (!c) {
return;
}
if (context.active) {
c = helpers.getHoverColor(c);
}
const mid = helpers.color(c).desaturate(0.2).darken(0.2).rgbString();
const start = helpers.color(c).lighten(0.2).rotate(270).rgbString();
const end = helpers.color(c).lighten(0.1).rgbString();
return createRadialGradient3(context, start, mid, end);
},
}
}
}
};
// </block:config>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,79 @@
# Delay
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.blue,
},
{
label: 'Dataset 3',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.green,
},
]
};
// </block:setup>
// <block:config:0>
var delayed;
const config = {
type: 'bar',
data: data,
options: {
animation: {
onComplete: () => {
delayed = true;
},
delay: (context) => {
let delay = 0;
if (context.type === 'data' && context.mode === 'default' && !delayed) {
delay = context.dataIndex * 300 + context.datasetIndex * 100;
}
return delay;
},
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,126 @@
# Drop
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
animations: {
y: {
duration: 2000,
delay: 500
}
},
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
fill: 1,
tension: 0.5
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
animations: {
y: {
easing: 'easeInOutElastic',
from: (ctx) => {
if (ctx.type === 'data') {
if (ctx.mode === 'default' && !ctx.dropped) {
ctx.dropped = true;
return 0;
}
}
}
}
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,126 @@
# Loop
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: DATA_COUNT});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
tension: 0.4,
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
tension: 0.2,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
animations: {
radius: {
duration: 400,
easing: 'linear',
loop: (context) => context.active
}
},
hoverRadius: 12,
hoverBackgroundColor: 'yellow',
interaction: {
mode: 'nearest',
intersect: false,
axis: 'x'
},
plugins: {
tooltip: {
enabled: false
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,90 @@
# Progressive Line
```js chart-editor
// <block:data:2>
const data = [];
const data2 = [];
let prev = 100;
let prev2 = 80;
for (let i = 0; i < 1000; i++) {
prev += 5 - Math.random() * 10;
data.push({x: i, y: prev});
prev2 += 5 - Math.random() * 10;
data2.push({x: i, y: prev2});
}
// </block:data>
// <block:animation:1>
const totalDuration = 10000;
const delayBetweenPoints = totalDuration / data.length;
const previousY = (ctx) => ctx.index === 0 ? ctx.chart.scales.y.getPixelForValue(100) : ctx.chart.getDatasetMeta(ctx.datasetIndex).data[ctx.index - 1].getProps(['y'], true).y;
const animation = {
x: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: NaN, // the point is initially skipped
delay(ctx) {
if (ctx.type !== 'data' || ctx.xStarted) {
return 0;
}
ctx.xStarted = true;
return ctx.index * delayBetweenPoints;
}
},
y: {
type: 'number',
easing: 'linear',
duration: delayBetweenPoints,
from: previousY,
delay(ctx) {
if (ctx.type !== 'data' || ctx.yStarted) {
return 0;
}
ctx.yStarted = true;
return ctx.index * delayBetweenPoints;
}
}
};
// </block:animation>
// <block:config:0>
const config = {
type: 'line',
data: {
datasets: [{
borderColor: Utils.CHART_COLORS.red,
borderWidth: 1,
radius: 0,
data: data,
},
{
borderColor: Utils.CHART_COLORS.blue,
borderWidth: 1,
radius: 0,
data: data2,
}]
},
options: {
animation,
interaction: {
intersect: false
},
plugins: {
legend: false
},
scales: {
x: {
type: 'linear'
}
}
}
};
// </block:config>
module.exports = {
config
};
```

View File

@@ -0,0 +1,341 @@
# Line Chart Boundaries
:::: tabs
::: tab "Fill: false"
```js chart-editor
// <block:setup:2>
const inputs = {
min: -100,
max: 100,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => (Utils.numbers(inputs));
// </block:setup>
// <block:data:0>
const data = {
labels: generateLabels(),
datasets: [
{
label: 'Dataset',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
fill: false
}
]
};
// </block:data>
// <block:actions:3>
let smooth = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
// Utils.srand(Utils.rand())
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:1>
const config = {
type: 'line',
data: data,
options: {
plugins: {
filler: {
propagate: false,
}
},
interaction: {
intersect: false,
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```
:::
::: tab "Fill: origin"
```js chart-editor
// <block:setup:2>
const inputs = {
min: -100,
max: 100,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => (Utils.numbers(inputs));
// </block:setup>
// <block:data:0>
const data = {
labels: generateLabels(),
datasets: [
{
label: 'Dataset',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
fill: 'origin'
}
]
};
// </block:data>
// <block:actions:3>
let smooth = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
// Utils.srand(Utils.rand())
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:1>
const config = {
type: 'line',
data: data,
options: {
plugins: {
filler: {
propagate: false,
}
},
interaction: {
intersect: false
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```
:::
::: tab "Fill: start"
```js chart-editor
// <block:setup:1>
const inputs = {
min: -100,
max: 100,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => (Utils.numbers(inputs));
// </block:setup>
// <block:data:0>
const data = {
labels: generateLabels(),
datasets: [
{
label: 'Dataset',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
fill: 'start'
}
]
};
// </block:data>
// <block:actions:2>
let smooth = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
// Utils.srand(Utils.rand())
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
filler: {
propagate: false,
}
},
interaction: {
intersect: false,
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```
:::
::: tab "Fill: end"
```js chart-editor
// <block:setup:2>
const inputs = {
min: -100,
max: 100,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => (Utils.numbers(inputs));
// </block:setup>
// <block:data:0>
const data = {
labels: generateLabels(),
datasets: [
{
label: 'Dataset',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
fill: 'end'
}
]
};
// </block:data>
// <block:actions:3>
let smooth = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
// Utils.srand(Utils.rand())
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:1>
const config = {
type: 'line',
data: data,
options: {
plugins: {
filler: {
propagate: false,
}
},
interaction: {
intersect: false,
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```
:::
::::

View File

@@ -0,0 +1,166 @@
# Line Chart Datasets
```js chart-editor
// <block:setup:2>
const inputs = {
min: 20,
max: 80,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => (Utils.numbers(inputs));
Utils.srand(42);
// </block:setup>
// <block:data:0>
const data = {
labels: generateLabels(),
datasets: [
{
label: 'D0',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
hidden: true
},
{
label: 'D1',
data: generateData(),
borderColor: Utils.CHART_COLORS.orange,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange),
fill: '-1'
},
{
label: 'D2',
data: generateData(),
borderColor: Utils.CHART_COLORS.yellow,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.yellow),
hidden: true,
fill: 1
},
{
label: 'D3',
data: generateData(),
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green),
fill: '-1'
},
{
label: 'D4',
data: generateData(),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue),
fill: '-1'
},
{
label: 'D5',
data: generateData(),
borderColor: Utils.CHART_COLORS.grey,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.grey),
fill: '+2'
},
{
label: 'D6',
data: generateData(),
borderColor: Utils.CHART_COLORS.purple,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.purple),
fill: false
},
{
label: 'D7',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
fill: 8
},
{
label: 'D8',
data: generateData(),
borderColor: Utils.CHART_COLORS.orange,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange),
fill: 'end',
hidden: true
},
{
label: 'D9',
data: generateData(),
borderColor: Utils.CHART_COLORS.yellow,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.yellow),
fill: {above: 'blue', below: 'red', target: {value: 350}}
}
]
};
// </block:data>
// <block:actions:3>
let smooth = false;
let propagate = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Propagate',
handler(chart) {
propagate = !propagate;
chart.options.plugins.filler.propagate = propagate;
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:1>
const config = {
type: 'line',
data: data,
options: {
scales: {
y: {
stacked: true
}
},
plugins: {
filler: {
propagate: false
},
'samples-filler-analyser': {
target: 'chart-analyser'
}
},
interaction: {
intersect: false,
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```
<div id="chart-analyser" class="analyser"></div>

View File

@@ -0,0 +1,313 @@
# Line Chart Stacked
:::: tabs
::: tab Stacked
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: dsColor,
borderColor: dsColor,
fill: true,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'My First dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
fill: true
},
{
label: 'My Second dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.CHART_COLORS.blue,
fill: true
},
{
label: 'My Third dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.CHART_COLORS.green,
fill: true
},
{
label: 'My Fourth dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.yellow,
backgroundColor: Utils.CHART_COLORS.yellow,
fill: true
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - stacked=true'
},
tooltip: {
mode: 'index'
},
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
scales: {
x: {
title: {
display: true,
text: 'Month'
}
},
y: {
stacked: true,
title: {
display: true,
text: 'Value'
}
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config
};
```
:::
::: tab "Stacked single"
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: dsColor,
borderColor: dsColor,
fill: true,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'My First dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
fill: true
},
{
label: 'My Second dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.CHART_COLORS.blue,
fill: true
},
{
label: 'My Third dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.CHART_COLORS.green,
fill: true
},
{
label: 'My Fourth dataset',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.yellow,
backgroundColor: Utils.CHART_COLORS.yellow,
fill: true
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - stacked=single'
},
tooltip: {
mode: 'index'
},
},
interaction: {
mode: 'nearest',
axis: 'x',
intersect: false
},
scales: {
x: {
title: {
display: true,
text: 'Month'
}
},
y: {
stacked: 'single',
title: {
display: true,
text: 'Value'
}
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config
};
```
:::
::::

141
docs/samples/area/radar.md Normal file
View File

@@ -0,0 +1,141 @@
# Radar Chart Stacked
```js chart-editor
// <block:setup:1>
const inputs = {
min: 8,
max: 16,
count: 8,
decimals: 2,
continuity: 1
};
const generateLabels = () => {
return Utils.months({count: inputs.count});
};
const generateData = () => {
const values = Utils.numbers(inputs);
inputs.from = values;
return values;
};
const labels = Utils.months({count: 8});
const data = {
labels: generateLabels(),
datasets: [
{
label: 'D0',
data: generateData(),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red),
},
{
label: 'D1',
data: generateData(),
borderColor: Utils.CHART_COLORS.orange,
hidden: true,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange),
fill: '-1'
},
{
label: 'D2',
data: generateData(),
borderColor: Utils.CHART_COLORS.yellow,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.yellow),
fill: 1
},
{
label: 'D3',
data: generateData(),
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green),
fill: false
},
{
label: 'D4',
data: generateData(),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue),
fill: '-1'
},
{
label: 'D5',
data: generateData(),
borderColor: Utils.CHART_COLORS.purple,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.purple),
fill: '-1'
},
{
label: 'D6',
data: generateData(),
borderColor: Utils.CHART_COLORS.grey,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.grey),
fill: {value: 85}
}
]
};
// </block:setup>
// <block:actions:2>
let smooth = false;
let propagate = false;
const actions = [
{
name: 'Randomize',
handler(chart) {
inputs.from = [];
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Propagate',
handler(chart) {
propagate = !propagate;
chart.options.plugins.filler.propagate = propagate;
chart.update();
}
},
{
name: 'Smooth',
handler(chart) {
smooth = !smooth;
chart.options.elements.line.tension = smooth ? 0.4 : 0;
chart.update();
}
}
];
// </block:actions>
// <block:config:0>
const config = {
type: 'radar',
data: data,
options: {
plugins: {
filler: {
propagate: false
},
'samples-filler-analyser': {
target: 'chart-analyser'
}
},
interaction: {
intersect: false
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config
};
```
<div id="chart-analyser" class="analyser"></div>

View File

@@ -0,0 +1,71 @@
# Bar Chart Border Radius
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Fully Rounded',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
borderWidth: 2,
borderRadius: Number.MAX_VALUE,
borderSkipped: false,
},
{
label: 'Small Radius',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
borderWidth: 2,
borderRadius: 5,
borderSkipped: false,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,69 @@
# Floating Bars
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = chart.data.labels.map(() => {
return [Utils.rand(-100, 100), Utils.rand(-100, 100)];
});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: labels.map(() => {
return [Utils.rand(-100, 100), Utils.rand(-100, 100)];
}),
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: labels.map(() => {
return [Utils.rand(-100, 100), Utils.rand(-100, 100)];
}),
backgroundColor: Utils.CHART_COLORS.blue,
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Floating Bar Chart'
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,123 @@
# Horizontal Bar Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
indexAxis: 'y',
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each horizontal bar to be 2px wide
elements: {
bar: {
borderWidth: 2,
}
},
responsive: true,
plugins: {
legend: {
position: 'right',
},
title: {
display: true,
text: 'Chart.js Horizontal Bar Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,79 @@
# Stacked Bar Chart with Groups
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.red,
stack: 'Stack 0',
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.blue,
stack: 'Stack 0',
},
{
label: 'Dataset 3',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.green,
stack: 'Stack 1',
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
interaction: {
intersect: false,
},
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,73 @@
# Stacked Bar Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.blue,
},
{
label: 'Dataset 3',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Utils.CHART_COLORS.green,
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart.js Bar Chart - Stacked'
},
},
responsive: true,
scales: {
x: {
stacked: true,
},
y: {
stacked: true
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,115 @@
# Vertical Bar Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

1
docs/samples/index.md Normal file
View File

@@ -0,0 +1 @@
# Samples

View File

@@ -0,0 +1,59 @@
# Point Style
This sample show how to use the dataset point style in the legend instead of a rectangle to identify each dataset..
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Toggle Point Style',
handler(chart) {
chart.options.plugins.legend.labels.usePointStyle = !chart.options.plugins.legend.labels.usePointStyle;
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
borderWidth: 1,
pointStyle: 'rectRot',
pointRadius: 5,
pointBorderColor: 'rgb(0, 0, 0)'
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
legend: {
labels: {
usePointStyle: true,
},
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,68 @@
# Position
This sample show how to change the position of the chart legend.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Position: top',
handler(chart) {
chart.options.plugins.legend.position = 'top';
chart.update();
}
},
{
name: 'Position: right',
handler(chart) {
chart.options.plugins.legend.position = 'right';
chart.update();
}
},
{
name: 'Position: bottom',
handler(chart) {
chart.options.plugins.legend.position = 'bottom';
chart.update();
}
},
{
name: 'Position: left',
handler(chart) {
chart.options.plugins.legend.position = 'left';
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,74 @@
# Alignment and Title Position
This sample show how to configure the alignment and title position of the chart legend.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Title Position: start',
handler(chart) {
chart.options.plugins.legend.align = 'start';
chart.options.plugins.legend.title.position = 'start';
chart.update();
}
},
{
name: 'Title Position: center (default)',
handler(chart) {
chart.options.plugins.legend.align = 'center';
chart.options.plugins.legend.title.position = 'center';
chart.update();
}
},
{
name: 'Title Position: end',
handler(chart) {
chart.options.plugins.legend.align = 'end';
chart.options.plugins.legend.title.position = 'end';
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
legend: {
title: {
display: true,
text: 'Legend Title',
}
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,77 @@
# Interpolation Modes
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 12;
const labels = [];
for (let i = 0; i < DATA_COUNT; ++i) {
labels.push(i.toString());
}
const datapoints = [0, 20, 20, 60, 60, 120, NaN, 180, 120, 125, 105, 110, 170];
const data = {
labels: labels,
datasets: [
{
label: 'Cubic interpolation (monotone)',
data: datapoints,
borderColor: Utils.CHART_COLORS.red,
fill: false,
cubicInterpolationMode: 'monotone',
tension: 0.4
}, {
label: 'Cubic interpolation',
data: datapoints,
borderColor: Utils.CHART_COLORS.blue,
fill: false,
tension: 0.4
}, {
label: 'Linear interpolation (default)',
data: datapoints,
borderColor: Utils.CHART_COLORS.green,
fill: false
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Cubic interpolation mode'
},
},
interaction: {
intersect: false,
},
scales: {
x: {
display: true,
title: {
display: true
}
},
y: {
display: true,
title: {
display: true,
text: 'Value'
},
suggestedMin: -10,
suggestedMax: 200
}
}
},
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

115
docs/samples/line/line.md Normal file
View File

@@ -0,0 +1,115 @@
# Line Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Line Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,86 @@
# Multi Axis Line Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
yAxisID: 'y',
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
yAxisID: 'y1',
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
mode: 'index',
intersect: false,
},
stacked: false,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Multi Axis'
}
},
scales: {
y: {
type: 'linear',
display: true,
position: 'left',
},
y1: {
type: 'linear',
display: true,
position: 'right',
// grid line settings
grid: {
drawOnChartArea: false, // only want the grid lines for one axis to show up
},
},
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,50 @@
# Stepped Line Charts
```js chart-editor
// <block:setup:1>
const data = {
labels: ['Day 1', 'Day 2', 'Day 3', 'Day 4', 'Day 5', 'Day 6'],
datasets: [
{
label: 'Dataset',
data: Utils.numbers({count: 6, min: -100, max: 100}),
borderColor: Utils.CHART_COLORS.red,
fill: false,
// Change the stepped mode to explore different stepped chart options
// false: no stepping
// true: stepped before interpolation
// 'before': step before interpolation
// 'after': step after interpolation
// 'middle': step middle interpolation
stepped: true,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
interaction: {
intersect: false,
axis: 'x'
},
plugins: {
title: {
display: true,
text: (ctx) => 'Step ' + ctx.chart.data.datasets[0].stepped + ' Interpolation',
}
}
}
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,76 @@
# Line Styling
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: DATA_COUNT});
const data = {
labels: labels,
datasets: [
{
label: 'Unfilled',
fill: false,
backgroundColor: Utils.CHART_COLORS.blue,
borderColor: Utils.CHART_COLORS.blue,
data: Utils.numbers(NUMBER_CFG),
}, {
label: 'Dashed',
fill: false,
backgroundColor: Utils.CHART_COLORS.green,
borderColor: Utils.CHART_COLORS.green,
borderDash: [5, 5],
data: Utils.numbers(NUMBER_CFG),
}, {
label: 'Filled',
backgroundColor: Utils.CHART_COLORS.red,
borderColor: Utils.CHART_COLORS.red,
data: Utils.numbers(NUMBER_CFG),
fill: true,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart'
},
},
interaction: {
mode: 'index',
intersect: false
},
scales: {
x: {
display: true,
title: {
display: true,
text: 'Month'
}
},
y: {
display: true,
title: {
display: true,
text: 'Value'
}
}
}
},
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,113 @@
# Bubble
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 5, rmax: 15, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
data: Utils.bubbles({count: data.labels.length, rmin: 5, rmax: 15, min: 0, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 5, rmax: 15, min: 0, max: 100})[0]);
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, rmin: 5, rmax: 15, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.orange,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bubble',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bubble Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,118 @@
# Combo bar/line
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
borderWidth: 1,
data: Utils.numbers({count: data.labels.length, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(-100, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
order: 1
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
type: 'line',
order: 0
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'bar',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Combined Line/Bar Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,112 @@
# Doughnut
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: [],
data: [],
};
for (let i = 0; i < data.labels.length; i++) {
newDataset.data.push(Utils.numbers({count: 1, min: 0, max: 100}));
const colorIndex = i % Object.keys(Utils.CHART_COLORS).length;
newDataset.backgroundColor.push(Object.values(Utils.CHART_COLORS)[colorIndex]);
}
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels.push('data #' + (data.labels.length + 1));
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 5;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Object.values(Utils.CHART_COLORS),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'doughnut',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Doughnut Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,91 @@
# Multi Series Pie
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 5;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: ['Overall Yay', 'Overall Nay', 'Group A Yay', 'Group A Nay', 'Group B Yay', 'Group B Nay', 'Group C Yay', 'Group C Nay'],
datasets: [
{
backgroundColor: ['#AAA', '#777'],
data: [21, 79]
},
{
backgroundColor: ['hsl(0, 100%, 60%)', 'hsl(0, 100%, 35%)'],
data: [33, 67]
},
{
backgroundColor: ['hsl(100, 100%, 60%)', 'hsl(100, 100%, 35%)'],
data: [20, 80]
},
{
backgroundColor: ['hsl(180, 100%, 60%)', 'hsl(180, 100%, 35%)'],
data: [10, 90]
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'pie',
data: data,
options: {
responsive: true,
plugins: {
legend: {
labels: {
generateLabels: function(chart) {
// Get the default label list
const original = Chart.overrides.pie.plugins.legend.labels.generateLabels;
const labelsOriginal = original.call(this, chart);
// Build an array of colors used in the datasets of the chart
var datasetColors = chart.data.datasets.map(function(e) {
return e.backgroundColor;
});
datasetColors = datasetColors.flat();
// Modify the color and hide state of each label
labelsOriginal.forEach(label => {
// There are twice as many labels as there are datasets. This converts the label index into the corresponding dataset index
label.datasetIndex = (label.index - label.index % 2) / 2;
// The hidden state must match the dataset's hidden state
label.hidden = !chart.isDatasetVisible(label.datasetIndex);
// Change the color to match the dataset
label.fillStyle = datasetColors[label.index];
});
return labelsOriginal;
}
},
onClick: function(mouseEvent, legendItem, legend) {
// toggle the visibility of the dataset from what it currently is
legend.chart.getDatasetMeta(
legendItem.datasetIndex
).hidden = legend.chart.isDatasetVisible(legendItem.datasetIndex);
legend.chart.update();
}
},
tooltip: {
callbacks: {
label: function(context) {
const labelIndex = (context.datasetIndex * 2) + context.dataIndex;
return context.chart.data.labels[labelIndex] + ': ' + context.formattedValue;
}
}
}
}
},
};
// </block:config>
module.exports = {
config: config,
};
```

View File

@@ -0,0 +1,112 @@
# Pie
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: [],
data: [],
};
for (let i = 0; i < data.labels.length; i++) {
newDataset.data.push(Utils.numbers({count: 1, min: 0, max: 100}));
const colorIndex = i % Object.keys(Utils.CHART_COLORS).length;
newDataset.backgroundColor.push(Object.values(Utils.CHART_COLORS)[colorIndex]);
}
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels.push('data #' + (data.labels.length + 1));
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 5;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: Object.values(Utils.CHART_COLORS),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'pie',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Pie Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,91 @@
# Polar area
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels.push('data #' + (data.labels.length + 1));
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 5;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = ['Red', 'Orange', 'Yellow', 'Green', 'Blue'];
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
backgroundColor: [
Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
Utils.transparentize(Utils.CHART_COLORS.orange, 0.5),
Utils.transparentize(Utils.CHART_COLORS.yellow, 0.5),
Utils.transparentize(Utils.CHART_COLORS.green, 0.5),
Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
]
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'polarArea',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Polar Area Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,87 @@
# Radar skip points
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach((dataset, i) => {
const data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
if (i === 0) {
data[0] = null;
} else if (i === 1) {
data[Number.parseInt(data.length / 2, 10)] = null;
} else {
data[data.length - 1] = null;
}
dataset.data = data;
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const dataFirstSkip = Utils.numbers(NUMBER_CFG);
const dataMiddleSkip = Utils.numbers(NUMBER_CFG);
const dataLastSkip = Utils.numbers(NUMBER_CFG);
dataFirstSkip[0] = null;
dataMiddleSkip[Number.parseInt(dataMiddleSkip.length / 2, 10)] = null;
dataLastSkip[dataLastSkip.length - 1] = null;
const data = {
labels: labels,
datasets: [
{
label: 'Skip first dataset',
data: dataFirstSkip,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Skip mid dataset',
data: dataMiddleSkip,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
},
{
label: 'Skip last dataset',
data: dataLastSkip,
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'radar',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Radar Skip Points Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config
};
```

View File

@@ -0,0 +1,111 @@
# Radar
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
data: Utils.numbers({count: data.labels.length, min: 0, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'radar',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Radar Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,135 @@
# Scatter - Multi axis
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 1, rmax: 1, min: -100, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
data: Utils.bubbles({count: data.labels.length, rmin: 1, rmax: 1, min: -100, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: -100, max: 100})[0]);
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: -100, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
yAxisID: 'y',
},
{
label: 'Dataset 2',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.orange,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5),
yAxisID: 'y2',
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'scatter',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Scatter Multi Axis Chart'
}
},
scales: {
y: {
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
position: 'left',
ticks: {
color: Utils.CHART_COLORS.red
}
},
y2: {
type: 'linear', // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
position: 'right',
reverse: true,
ticks: {
color: Utils.CHART_COLORS.blue
},
grid: {
drawOnChartArea: false // only want the grid lines for one axis to show up
}
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,113 @@
# Scatter
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.bubbles({count: chart.data.labels.length, rmin: 1, rmax: 1, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: Utils.transparentize(dsColor, 0.5),
borderColor: dsColor,
data: Utils.bubbles({count: data.labels.length, rmin: 1, rmax: 1, min: 0, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.bubbles({count: 1, rmin: 1, rmax: 1, min: 0, max: 100})[0]);
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, rmin: 1, rmax: 1, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.bubbles(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.orange,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.orange, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'scatter',
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Scatter Chart'
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,89 @@
# Center Positioning
This sample show how to place the axis in the center of the chart area, instead of at the edges.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Default Positions',
handler(chart) {
chart.options.scales.x.position = 'bottom';
chart.options.scales.y.position = 'left';
chart.update();
}
},
{
name: 'Position: center',
handler(chart) {
chart.options.scales.x.position = 'center';
chart.options.scales.y.position = 'center';
chart.update();
}
},
{
name: 'Position: Vertical: x=-60, Horizontal: y=30',
handler(chart) {
chart.options.scales.x.position = {y: 30};
chart.options.scales.y.position = {x: -60};
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 6;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
datasets: [
{
label: 'Dataset 1',
data: Utils.points(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.points(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'scatter',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Axis Center Positioning'
}
},
scales: {
x: {
min: -100,
max: 100,
},
y: {
min: -100,
max: 100,
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,94 @@
# Grid Configuration
This sample shows how to use scriptable grid options for an axis to control styling. In this case, the Y axis grid lines are colored based on their value. In addition, booleans are provided to toggle different parts of the X axis grid visibility.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: -100, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: [10, 30, 39, 20, 25, 34, -10],
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: [18, 33, 22, 19, 11, -39, 30],
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
// Change these settings to change the display for different parts of the X axis
// grid configuiration
const DISPLAY = true;
const BORDER = true;
const CHART_AREA = true;
const TICKS = true;
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Grid Line Settings'
}
},
scales: {
x: {
grid: {
display: DISPLAY,
drawBorder: BORDER,
drawOnChartArea: CHART_AREA,
drawTicks: TICKS,
}
},
y: {
grid: {
drawBorder: false,
color: function(context) {
if (context.tick.value > 0) {
return Utils.CHART_COLORS.green;
} else if (context.tick.value < 0) {
return Utils.CHART_COLORS.red;
}
return '#000000';
},
},
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,94 @@
# Tick Configuration
This sample shows how to use different tick features to control how tick labels are shown on the X axis. These features include:
* Multi-line labels
* Filtering labels
* Changing the tick color
* Changing the tick alignment for the X axis
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Alignment: start',
handler(chart) {
chart.options.scales.x.ticks.align = 'start';
chart.update();
}
},
{
name: 'Alignment: center (default)',
handler(chart) {
chart.options.scales.x.ticks.align = 'center';
chart.update();
}
},
{
name: 'Alignment: end',
handler(chart) {
chart.options.scales.x.ticks.align = 'end';
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 12;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: [['June', '2015'], 'July', 'August', 'September', 'October', 'November', 'December', ['January', '2016'], 'February', 'March', 'April', 'May'],
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart with Tick Configuration'
}
},
scales: {
x: {
ticks: {
// For a category axis, the val is the index so the lookup via getLabelForValue is needed
callback: function(val, index) {
// Hide the label of every 2nd dataset
return index % 2 === 0 ? this.getLabelForValue(val) : '';
},
color: 'red',
}
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,76 @@
# Title Configuration
This sample shows how to configure the title of an axis including alignment, font, and color.
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
scales: {
x: {
display: true,
title: {
display: true,
text: 'Month',
color: '#911',
font: {
family: 'Comic Sans MS',
size: 20,
style: 'bold',
lineHeight: 1.2,
},
padding: {top: 20, left: 0, right: 0, bottom: 0}
}
},
y: {
display: true,
title: {
display: true,
text: 'Value',
color: '#191',
font: {
family: 'Times',
size: 20,
style: 'normal',
lineHeight: 1.2,
},
padding: {top: 30, left: 0, right: 0, bottom: 0}
}
}
}
},
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,56 @@
# Linear Scale - Suggested Min-Max
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [10, 30, 39, 20, 25, 34, -10],
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: [18, 33, 22, 19, 11, 39, 30],
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.CHART_COLORS.blue,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Suggested Min and Max Settings'
}
},
scales: {
y: {
// the data minimum used for determining the ticks is Math.min(dataMin, suggestedMin)
suggestedMin: 30,
// the data maximum used for determining the ticks is Math.max(dataMax, suggestedMax)
suggestedMax: 50,
}
}
},
};
// </block:config>
module.exports = {
config: config,
};
```

View File

@@ -0,0 +1,53 @@
# Linear Scale - Min-Max
```js chart-editor
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: [10, 30, 50, 20, 25, 44, -10],
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: [100, 33, 22, 19, 11, 49, 30],
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.CHART_COLORS.blue,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Min and Max Settings'
}
},
scales: {
y: {
min: 10,
max: 50,
}
}
},
};
// </block:config>
module.exports = {
config: config,
};
```

View File

@@ -0,0 +1,139 @@
# Linear Scale - Step Size
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
{
name: 'Add Dataset',
handler(chart) {
const data = chart.data;
const dsColor = Utils.namedColor(chart.data.datasets.length);
const newDataset = {
label: 'Dataset ' + (data.datasets.length + 1),
backgroundColor: dsColor,
borderColor: dsColor,
data: Utils.numbers({count: data.labels.length, min: 0, max: 100}),
};
chart.data.datasets.push(newDataset);
chart.update();
}
},
{
name: 'Add Data',
handler(chart) {
const data = chart.data;
if (data.datasets.length > 0) {
data.labels = Utils.months({count: data.labels.length + 1});
for (var index = 0; index < data.datasets.length; ++index) {
data.datasets[index].data.push(Utils.rand(0, 100));
}
chart.update();
}
}
},
{
name: 'Remove Dataset',
handler(chart) {
chart.data.datasets.pop();
chart.update();
}
},
{
name: 'Remove Data',
handler(chart) {
chart.data.labels.splice(-1, 1); // remove the label first
chart.data.datasets.forEach(dataset => {
dataset.data.pop();
});
chart.update();
}
}
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.CHART_COLORS.blue,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
tooltip: {
mode: 'index',
intersect: false
},
title: {
display: true,
text: 'Chart.js Line Chart'
}
},
hover: {
mode: 'index',
intersec: false
},
scales: {
x: {
title: {
display: true,
text: 'Month'
}
},
y: {
title: {
display: true,
text: 'Value'
},
min: 0,
max: 100,
ticks: {
// forces step size to be 50 units
stepSize: 50
}
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,76 @@
# Log Scale
```js chart-editor
// <block:actions:2>
const logNumbers = (num) => {
const data = [];
for (let i = 0; i < num; ++i) {
data.push(Math.ceil(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5)));
}
return data;
};
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = logNumbers(chart.data.labels.length);
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = Utils.months({count: 7});
const data = {
labels: labels,
datasets: [
{
label: 'Dataset 1',
data: logNumbers(DATA_COUNT),
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.CHART_COLORS.red,
fill: false,
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
responsive: true,
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - Logarithmic'
}
},
scales: {
x: {
display: true,
},
y: {
display: true,
type: 'logarithmic',
}
}
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,82 @@
# Time Scale - Combo Chart
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = Utils.numbers({count: chart.data.labels.length, min: 0, max: 100});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const labels = [];
for (let i = 0; i < DATA_COUNT; ++i) {
labels.push(Utils.newDate(i));
}
const data = {
labels: labels,
datasets: [{
type: 'bar',
label: 'Dataset 1',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
borderColor: Utils.CHART_COLORS.red,
data: Utils.numbers(NUMBER_CFG),
}, {
type: 'bar',
label: 'Dataset 2',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
borderColor: Utils.CHART_COLORS.blue,
data: Utils.numbers(NUMBER_CFG),
}, {
type: 'line',
label: 'Dataset 3',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green, 0.5),
borderColor: Utils.CHART_COLORS.green,
fill: false,
data: Utils.numbers(NUMBER_CFG),
}]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
title: {
text: 'Chart.js Combo Time Scale',
display: true
}
},
scales: {
x: {
type: 'time',
display: true,
offset: true,
time: {
unit: 'day'
}
},
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,112 @@
# Time Scale
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data.forEach(function(dataObj, j) {
const newVal = Utils.rand(0, 100);
if (typeof dataObj === 'object') {
dataObj.y = newVal;
} else {
dataset.data[j] = newVal;
}
});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: 0, max: 100};
const data = {
labels: [ // Date Objects
Utils.newDate(0),
Utils.newDate(1),
Utils.newDate(2),
Utils.newDate(3),
Utils.newDate(4),
Utils.newDate(5),
Utils.newDate(6)
],
datasets: [{
label: 'My First dataset',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
borderColor: Utils.CHART_COLORS.red,
fill: false,
data: Utils.numbers(NUMBER_CFG),
}, {
label: 'My Second dataset',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
borderColor: Utils.CHART_COLORS.blue,
fill: false,
data: Utils.numbers(NUMBER_CFG),
}, {
label: 'Dataset with point data',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green, 0.5),
borderColor: Utils.CHART_COLORS.green,
fill: false,
data: [{
x: Utils.newDateString(0),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(5),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(7),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(15),
y: Utils.rand(0, 100)
}],
}]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
title: {
text: 'Chart.js Time Scale',
display: true
}
},
scales: {
x: {
type: 'time',
time: {
// Luxon format string
tooltipFormat: 'DD T'
},
title: {
display: true,
text: 'Date'
}
},
y: {
title: {
display: true,
text: 'value'
}
}
},
},
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,126 @@
# Time Scale - Max Span
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data.forEach(function(dataObj, j) {
const newVal = Utils.rand(0, 100);
if (typeof dataObj === 'object') {
dataObj.y = newVal;
} else {
dataset.data[j] = newVal;
}
});
});
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const data = {
datasets: [{
label: 'Dataset with string point data',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
borderColor: Utils.CHART_COLORS.red,
fill: false,
data: [{
x: Utils.newDateString(0),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(2),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(4),
y: Utils.rand(0, 100)
}, {
x: Utils.newDateString(6),
y: Utils.rand(0, 100)
}],
}, {
label: 'Dataset with date object point data',
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
borderColor: Utils.CHART_COLORS.blue,
fill: false,
data: [{
x: Utils.newDate(0),
y: Utils.rand(0, 100)
}, {
x: Utils.newDate(2),
y: Utils.rand(0, 100)
}, {
x: Utils.newDate(5),
y: Utils.rand(0, 100)
}, {
x: Utils.newDate(6),
y: Utils.rand(0, 100)
}]
}]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
spanGaps: 1000 * 60 * 60 * 24 * 2, // 2 days
responsive: true,
interaction: {
mode: 'nearest',
},
plugins: {
title: {
display: true,
text: 'Chart.js Time - spanGaps: 172800000 (2 days in ms)'
},
},
scales: {
x: {
type: 'time',
display: true,
title: {
display: true,
text: 'Date'
},
ticks: {
autoSkip: false,
maxRotation: 0,
major: {
enabled: true
},
// color: function(context) {
// return context.tick && context.tick.major ? '#FF0000' : 'rgba(0,0,0,0.1)';
// },
font: function(context) {
if (context.tick && context.tick.major) {
return {
style: 'bold',
};
}
}
}
},
y: {
display: true,
title: {
display: true,
text: 'value'
}
}
}
},
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,73 @@
# Bar Chart
```js chart-editor
// <block:setup:2>
var DATA_COUNT = 16;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:data:1>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: -100,
max: 100
});
}
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [{
data: generateData(),
}]
};
// </block:data>
// <block:options:0>
function colorize(opaque) {
return (ctx) => {
var v = ctx.parsed.y;
var c = v < -50 ? '#D60000'
: v < 0 ? '#F46300'
: v < 50 ? '#0358B6'
: '#44DE28';
return opaque ? c : Utils.transparentize(c, 1 - Math.abs(v / 150));
};
}
const config = {
type: 'bar',
data: data,
options: {
plugins: {
legend: false,
},
elements: {
bar: {
backgroundColor: colorize(false),
borderColor: colorize(true),
borderWidth: 2
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,109 @@
# Bubble Chart
```js chart-editor
// <block:setup:2>
const DATA_COUNT = 16;
const MIN_XY = -150;
const MAX_XY = 100;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:data:1>
function generateData() {
var data = [];
var i;
for (i = 0; i < DATA_COUNT; ++i) {
data.push({
x: Utils.rand(MIN_XY, MAX_XY),
y: Utils.rand(MIN_XY, MAX_XY),
v: Utils.rand(0, 1000)
});
}
return data;
}
const data = {
datasets: [{
data: generateData()
}, {
data: generateData()
}]
};
// </block:data>
// <block:options:0>
function channelValue(x, y, values) {
return x < 0 && y < 0 ? values[0] : x < 0 ? values[1] : y < 0 ? values[2] : values[3];
}
function colorize(opaque, context) {
var value = context.raw;
var x = value.x / 100;
var y = value.y / 100;
var r = channelValue(x, y, [250, 150, 50, 0]);
var g = channelValue(x, y, [0, 50, 150, 250]);
var b = channelValue(x, y, [0, 150, 150, 250]);
var a = opaque ? 1 : 0.5 * value.v / 1000;
return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
}
const config = {
type: 'bubble',
data: data,
options: {
aspectRatio: 1,
plugins: {
legend: false,
tooltip: false,
},
elements: {
point: {
backgroundColor: colorize.bind(null, false),
borderColor: colorize.bind(null, true),
borderWidth: function(context) {
return Math.min(Math.max(1, context.datasetIndex + 1), 8);
},
hoverBackgroundColor: 'transparent',
hoverBorderColor: function(context) {
return Utils.color(context.datasetIndex);
},
hoverBorderWidth: function(context) {
return Math.round(8 * context.raw.v / 1000);
},
radius: function(context) {
var size = context.chart.width;
var base = Math.abs(context.raw.v) / 1000;
return (size / 24) * base;
}
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,91 @@
# Line Chart
```js chart-editor
// <block:setup:2>
const DATA_COUNT = 12;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:data:1>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
});
}
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [{
data: generateData()
}]
};
// </block:data>
// <block:options:0>
function getLineColor(ctx) {
return Utils.color(ctx.datasetIndex);
}
function alternatePointStyles(ctx) {
var index = ctx.dataIndex;
return index % 2 === 0 ? 'circle' : 'rect';
}
function makeHalfAsOpaque(ctx) {
return Utils.transparentize(getLineColor(ctx));
}
function adjustRadiusBasedOnData(ctx) {
var v = ctx.parsed.y;
return v < 10 ? 5
: v < 25 ? 7
: v < 50 ? 9
: v < 75 ? 11
: 15;
}
const config = {
type: 'line',
data: data,
options: {
plugins: {
legend: false,
tooltip: true,
},
elements: {
line: {
fill: false,
backgroundColor: getLineColor,
borderColor: getLineColor,
},
point: {
backgroundColor: getLineColor,
hoverBackgroundColor: makeHalfAsOpaque,
radius: adjustRadiusBasedOnData,
pointStyle: alternatePointStyles,
hoverRadius: 15,
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,87 @@
# Pie Chart
```js chart-editor
// <block:setup:2>
const DATA_COUNT = 5;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
{
name: 'Toggle Doughnut View',
handler(chart) {
if (chart.options.cutout) {
chart.options.cutout = 0;
} else {
chart.options.cutout = '50%';
}
chart.update();
}
}
];
// </block:setup>
// <block:data:1>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: -100,
max: 100
});
}
const data = {
datasets: [{
data: generateData()
}]
};
// </block:data>
// <block:options:0>
function colorize(opaque, hover, ctx) {
var v = ctx.parsed;
var c = v < -50 ? '#D60000'
: v < 0 ? '#F46300'
: v < 50 ? '#0358B6'
: '#44DE28';
var opacity = hover ? 1 - Math.abs(v / 150) - 0.2 : 1 - Math.abs(v / 150);
return opaque ? c : Utils.transparentize(c, opacity);
}
function hoverColorize(ctx) {
return colorize(false, true, ctx);
}
const config = {
type: 'pie',
data: data,
options: {
plugins: {
legend: false,
tooltip: false,
},
elements: {
arc: {
backgroundColor: colorize.bind(null, false, false),
hoverBackgroundColor: hoverColorize
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,77 @@
# Polar Area Chart
```js chart-editor
// <block:setup:2>
const DATA_COUNT = 7;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:data:1>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
});
}
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [{
data: generateData()
}]
};
// </block:data>
// <block:options:0>
function colorize(opaque, hover, ctx) {
var v = ctx.raw;
var c = v < 35 ? '#D60000'
: v < 55 ? '#F46300'
: v < 75 ? '#0358B6'
: '#44DE28';
var opacity = hover ? 1 - Math.abs(v / 150) - 0.2 : 1 - Math.abs(v / 150);
return opaque ? c : Utils.transparentize(c, opacity);
}
function hoverColorize(ctx) {
return colorize(false, true, ctx);
}
const config = {
type: 'polarArea',
data: data,
options: {
plugins: {
legend: false,
tooltip: false,
},
elements: {
arc: {
backgroundColor: colorize.bind(null, false, false),
hoverBackgroundColor: hoverColorize
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,94 @@
# Radar Chart
```js chart-editor
// <block:setup:2>
const DATA_COUNT = 7;
Utils.srand(110);
const actions = [
{
name: 'Randomize',
handler(chart) {
chart.data.datasets.forEach(dataset => {
dataset.data = generateData();
});
chart.update();
}
},
];
// </block:setup>
// <block:data:1>
function generateData() {
return Utils.numbers({
count: DATA_COUNT,
min: 0,
max: 100
});
}
const data = {
labels: [['Eating', 'Dinner'], ['Drinking', 'Water'], 'Sleeping', ['Designing', 'Graphics'], 'Coding', 'Cycling', 'Running'],
datasets: [{
data: generateData()
}]
};
// </block:data>
// <block:options:0>
function getLineColor(ctx) {
return Utils.color(ctx.datasetIndex);
}
function alternatePointStyles(ctx) {
var index = ctx.dataIndex;
return index % 2 === 0 ? 'circle' : 'rect';
}
function makeHalfAsOpaque(ctx) {
return Utils.transparentize(getLineColor(ctx));
}
function make20PercentOpaque(ctx) {
return Utils.transparentize(getLineColor(ctx), 0.8);
}
function adjustRadiusBasedOnData(ctx) {
var v = ctx.parsed.y;
return v < 10 ? 5
: v < 25 ? 7
: v < 50 ? 9
: v < 75 ? 11
: 15;
}
const config = {
type: 'radar',
data: data,
options: {
plugins: {
legend: false,
tooltip: false,
},
elements: {
line: {
backgroundColor: make20PercentOpaque,
borderColor: getLineColor,
},
point: {
backgroundColor: getLineColor,
hoverBackgroundColor: makeHalfAsOpaque,
radius: adjustRadiusBasedOnData,
pointStyle: alternatePointStyles,
hoverRadius: 15,
}
}
}
};
// </block:options>
module.exports = {
actions,
config,
};
```

View File

@@ -0,0 +1,69 @@
# Alignment
This sample show how to configure the alignment of the chart title
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Title Alignment: start',
handler(chart) {
chart.options.plugins.title.align = 'start';
chart.update();
}
},
{
name: 'Title Alignment: center (default)',
handler(chart) {
chart.options.plugins.title.align = 'center';
chart.update();
}
},
{
name: 'Title Alignment: end',
handler(chart) {
chart.options.plugins.title.align = 'end';
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
plugins: {
title: {
display: true,
text: 'Chart Title',
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,66 @@
# Custom Tooltip Content
This sample shows how to use the tooltip callbacks to add additional content to the tooltip.
```js chart-editor
// <block:footer:2>
const footer = (tooltipItems) => {
let sum = 0;
tooltipItems.forEach(function(tooltipItem) {
sum += tooltipItem.parsed.y;
});
return 'Sum: ' + sum;
};
// </block:footer>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100, decimals: 0};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
tooltip: {
callbacks: {
footer: footer,
}
}
}
}
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,165 @@
# External HTML Tooltip
This sample shows how to use the external tooltip functionality to generate an HTML tooltip.
```js chart-editor
// <block:external:2>
const getOrCreateTooltip = (chart) => {
let tooltipEl = chart.canvas.parentNode.querySelector('div');
if (!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.style.background = 'rgba(0, 0, 0, 0.7)';
tooltipEl.style.borderRadius = '3px';
tooltipEl.style.color = 'white';
tooltipEl.style.opacity = 1;
tooltipEl.style.pointerEvents = 'none';
tooltipEl.style.position = 'absolute';
tooltipEl.style.transform = 'translate(-50%, 0)';
tooltipEl.style.transition = 'all .1s ease';
const table = document.createElement('table');
table.style.margin = '0px';
tooltipEl.appendChild(table);
chart.canvas.parentNode.appendChild(tooltipEl);
}
return tooltipEl;
};
const externalTooltipHandler = (context) => {
// Tooltip Element
const {chart, tooltip} = context;
const tooltipEl = getOrCreateTooltip(chart);
// Hide if no tooltip
if (tooltip.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// Set Text
if (tooltip.body) {
const titleLines = tooltip.title || [];
const bodyLines = tooltip.body.map(b => b.lines);
const tableHead = document.createElement('thead');
titleLines.forEach(title => {
const tr = document.createElement('tr');
tr.style.borderWidth = 0;
const th = document.createElement('th');
th.style.borderWidth = 0;
const text = document.createTextNode(title);
th.appendChild(text);
tr.appendChild(th);
tableHead.appendChild(tr);
});
const tableBody = document.createElement('tbody');
bodyLines.forEach((body, i) => {
const colors = tooltip.labelColors[i];
const span = document.createElement('span');
span.style.background = colors.backgroundColor;
span.style.borderColor = colors.borderColor;
span.style.borderWidth = '2px';
span.style.marginRight = '10px';
span.style.height = '10px';
span.style.width = '10px';
span.style.display = 'inline-block';
const tr = document.createElement('tr');
tr.style.backgroundColor = 'inherit';
tr.style.borderWidth = 0;
const td = document.createElement('td');
td.style.borderWidth = 0;
const text = document.createTextNode(body);
td.appendChild(span);
td.appendChild(text);
tr.appendChild(td);
tableBody.appendChild(tr);
});
const tableRoot = tooltipEl.querySelector('table');
// Remove old children
while (tableRoot.firstChild) {
tableRoot.firstChild.remove();
}
// Add new children
tableRoot.appendChild(tableHead);
tableRoot.appendChild(tableBody);
}
const {offsetLeft: positionX, offsetTop: positionY} = chart.canvas;
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.left = positionX + tooltip.caretX + 'px';
tooltipEl.style.top = positionY + tooltip.caretY + 'px';
tooltipEl.style.font = tooltip.options.bodyFont.string;
tooltipEl.style.padding = tooltip.padding + 'px ' + tooltip.padding + 'px';
};
// </block:external>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100, decimals: 0};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
interaction: {
mode: 'index',
intersect: false,
},
plugins: {
title: {
display: true,
text: 'Chart.js Line Chart - External Tooltips'
},
tooltip: {
enabled: false,
position: 'nearest',
external: externalTooltipHandler
}
}
}
};
// </block:config>
module.exports = {
actions: [],
config: config,
};
```

View File

@@ -0,0 +1,110 @@
# Interaction Modes
This sample shows how to use the tooltip position mode setting.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Mode: index',
handler(chart) {
chart.options.interaction.mode = 'index';
chart.update();
}
},
{
name: 'Mode: dataset',
handler(chart) {
chart.options.interaction.mode = 'dataset';
chart.update();
}
},
{
name: 'Mode: point',
handler(chart) {
chart.options.interaction.mode = 'point';
chart.update();
}
},
{
name: 'Mode: nearest',
handler(chart) {
chart.options.interaction.mode = 'nearest';
chart.update();
}
},
{
name: 'Mode: x',
handler(chart) {
chart.options.interaction.mode = 'x';
chart.update();
}
},
{
name: 'Mode: y',
handler(chart) {
chart.options.interaction.mode = 'y';
chart.update();
}
},
{
name: 'Toggle Intersect',
handler(chart) {
chart.options.interaction.intersect = !chart.options.interaction.intersect;
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
},
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
title: {
display: true,
text: (ctx) => {
const {intersect, mode} = ctx.chart.options.interaction;
return 'Mode: ' + mode + ', intersect: ' + intersect;
}
},
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,80 @@
# Point Style
This sample shows how to use the dataset point style in the tooltip instead of a rectangle to identify each dataset.
```js chart-editor
// <block:actions:2>
const actions = [
{
name: 'Toggle Tooltip Point Style',
handler(chart) {
chart.options.plugins.tooltip.usePointStyle = !chart.options.plugins.tooltip.usePointStyle;
chart.update();
}
},
];
// </block:actions>
// <block:setup:1>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Triangles',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
pointStyle: 'triangle',
pointRadius: 6,
},
{
label: 'Circles',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
pointStyle: 'circle',
pointRadius: 6,
},
{
label: 'Stars',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.green,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.green, 0.5),
pointStyle: 'star',
pointRadius: 6,
}
]
};
// </block:setup>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
interaction: {
mode: 'index',
},
plugins: {
title: {
display: true,
text: (ctx) => 'Tooltip point style: ' + ctx.chart.options.plugins.tooltip.usePointStyle,
},
tooltip: {
usePointStyle: true,
}
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

View File

@@ -0,0 +1,93 @@
# Position
This sample shows how to use the tooltip position mode setting.
```js chart-editor
// <block:actions:3>
const actions = [
{
name: 'Position: average',
handler(chart) {
chart.options.plugins.tooltip.position = 'average';
chart.update();
}
},
{
name: 'Position: nearest',
handler(chart) {
chart.options.plugins.tooltip.position = 'nearest';
chart.update();
}
},
{
name: 'Position: bottom (custom)',
handler(chart) {
chart.options.plugins.tooltip.position = 'bottom';
chart.update();
}
},
];
// </block:actions>
// <block:setup:2>
const DATA_COUNT = 7;
const NUMBER_CFG = {count: DATA_COUNT, min: -100, max: 100};
const data = {
labels: Utils.months({count: DATA_COUNT}),
datasets: [
{
label: 'Dataset 1',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.red,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.red, 0.5),
},
{
label: 'Dataset 2',
data: Utils.numbers(NUMBER_CFG),
fill: false,
borderColor: Utils.CHART_COLORS.blue,
backgroundColor: Utils.transparentize(Utils.CHART_COLORS.blue, 0.5),
},
]
};
// </block:setup>
// <block:positioner:1>
// Create a custom tooltip positioner to put at the bottom of the chart area
components.Tooltip.positioners.bottom = function(items) {
const pos = components.Tooltip.positioners.average(items);
const chart = this._chart;
return {
x: pos.x,
y: chart.chartArea.bottom,
};
};
// </block:positioner>
// <block:config:0>
const config = {
type: 'line',
data: data,
options: {
interaction: {
intersect: false,
mode: 'index',
},
plugins: {
title: {
display: true,
text: (ctx) => 'Tooltip position mode: ' + ctx.chart.options.plugins.tooltip.position,
},
}
}
};
// </block:config>
module.exports = {
actions: actions,
config: config,
};
```

60
docs/scripts/analyzer.js Normal file
View File

@@ -0,0 +1,60 @@
export default {
id: 'samples-filler-analyser',
beforeInit: function(chart, args, options) {
this.element = document.getElementById(options.target);
},
afterUpdate: function(chart) {
var datasets = chart.data.datasets;
var element = this.element;
var stats = [];
var meta, i, ilen, dataset;
if (!element) {
return;
}
for (i = 0, ilen = datasets.length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i).$filler;
if (meta) {
dataset = datasets[i];
stats.push({
fill: dataset.fill,
target: meta.fill,
visible: meta.visible,
index: i
});
}
}
this.element.innerHTML = '<table>' +
'<tr>' +
'<th>Dataset</th>' +
'<th>Fill</th>' +
'<th>Target (visibility)</th>' +
'</tr>' +
stats.map(function(stat) {
var target = stat.target;
var row =
'<td><b>' + stat.index + '</b></td>' +
'<td>' + JSON.stringify(stat.fill) + '</td>';
if (target === false) {
target = 'none';
} else if (isFinite(target)) {
target = 'dataset ' + target;
} else {
target = 'boundary "' + target + '"';
}
if (stat.visible) {
row += '<td>' + target + '</td>';
} else {
row += '<td>(hidden)</td>';
}
return '<tr>' + row + '</tr>';
}).join('') + '</table>';
}
};

View File

@@ -0,0 +1,3 @@
// Add Chart components needed in samples here.
// Usable through `components[name]`.
export {Tooltip} from '../../dist/chart.esm';

View File

@@ -0,0 +1,34 @@
import {Chart, BubbleController} from 'chart.js';
class Custom extends BubbleController {
draw() {
// Call bubble controller method to draw all the points
super.draw(arguments);
// Now we can do some custom drawing for this dataset.
// Here we'll draw a box around the first point in each dataset,
// using `boxStrokeStyle` dataset option for color
var meta = this.getMeta();
var pt0 = meta.data[0];
const {x, y} = pt0.getProps(['x', 'y']);
const {radius} = pt0.options;
var ctx = this.chart.ctx;
ctx.save();
ctx.strokeStyle = this.options.boxStrokeStyle;
ctx.lineWidth = 1;
ctx.strokeRect(x - radius, y - radius, 2 * radius, 2 * radius);
ctx.restore();
}
}
Custom.id = 'derivedBubble';
Custom.defaults = {
// Custom defaults. Bubble defaults are inherited.
boxStrokeStyle: 'red'
};
// Overrides are only inherited, but not merged if defined
// Custom.overrides = Chart.overrides.bubble;
// Stores the controller so that the chart initialization routine can look it up
Chart.register(Custom);

4
docs/scripts/helpers.js Normal file
View File

@@ -0,0 +1,4 @@
// Add helpers needed in samples here.
// Usable through `helpers[name]`.
export {color, getHoverColor} from '../../dist/helpers.esm';

67
docs/scripts/log2.js Normal file
View File

@@ -0,0 +1,67 @@
import {Scale, LinearScale} from 'chart.js';
export default class Log2Axis extends Scale {
constructor(cfg) {
super(cfg);
this._startValue = undefined;
this._valueRange = 0;
}
parse(raw, index) {
const value = LinearScale.prototype.parse.apply(this, [raw, index]);
return isFinite(value) && value > 0 ? value : null;
}
determineDataLimits() {
const {min, max} = this.getMinMax(true);
this.min = isFinite(min) ? Math.max(0, min) : null;
this.max = isFinite(max) ? Math.max(0, max) : null;
}
buildTicks() {
const ticks = [];
let power = Math.floor(Math.log2(this.min));
let maxPower = Math.ceil(Math.log2(this.max));
while (power <= maxPower) {
ticks.push({value: Math.pow(2, power)});
power += 1;
}
this.min = ticks[0].value;
this.max = ticks[ticks.length - 1].value;
return ticks;
}
/**
* @protected
*/
configure() {
const start = this.min;
super.configure();
this._startValue = Math.log2(start);
this._valueRange = Math.log2(this.max) - Math.log2(start);
}
getPixelForValue(value) {
if (value === undefined || value === 0) {
value = this.min;
}
return this.getPixelForDecimal(value === this.min ? 0
: (Math.log2(value) - this._startValue) / this._valueRange);
}
getValueForPixel(pixel) {
const decimal = this.getDecimalForPixel(pixel);
return Math.pow(2, this._startValue + decimal * this._valueRange);
}
}
Log2Axis.id = 'log2';
Log2Axis.defaults = {};
// The derived axis is registered like this:
// Chart.register(Log2Axis);

View File

@@ -1,3 +1,8 @@
import {Chart, registerables} from '../../dist/chart.esm';
import Log2Axis from './log2';
import './derived-bubble';
import analyzer from './analyzer';
Chart.register(...registerables);
Chart.register(Log2Axis);
Chart.register(analyzer);

View File

@@ -1,3 +1,6 @@
import colorLib from '@kurkle/color';
import {DateTime} from 'luxon';
import 'chartjs-adapter-luxon';
import {valueOrDefault} from '../../dist/helpers.esm';
// Adapted from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
@@ -44,6 +47,13 @@ export function points(config) {
return xs.map((x, i) => ({x, y: ys[i]}));
}
export function bubbles(config) {
return this.points(config).map(pt => {
pt.r = this.rand(config.rmin, config.rmax);
return pt;
});
}
export function labels(config) {
var cfg = config || {};
var min = cfg.min || 0;
@@ -109,12 +119,12 @@ export function color(index) {
return COLORS[index % COLORS.length];
}
export function transparentize(color, opacity) {
export function transparentize(value, opacity) {
var alpha = opacity === undefined ? 0.5 : 1 - opacity;
return Color(color).alpha(alpha).rgbString();
return colorLib(value).alpha(alpha).rgbString();
}
export const chartColors = {
export const CHART_COLORS = {
red: 'rgb(255, 99, 132)',
orange: 'rgb(255, 159, 64)',
yellow: 'rgb(255, 205, 86)',
@@ -123,3 +133,25 @@ export const chartColors = {
purple: 'rgb(153, 102, 255)',
grey: 'rgb(201, 203, 207)'
};
const NAMED_COLORS = [
CHART_COLORS.red,
CHART_COLORS.orange,
CHART_COLORS.yellow,
CHART_COLORS.green,
CHART_COLORS.blue,
CHART_COLORS.purple,
CHART_COLORS.grey,
];
export function namedColor(index) {
return NAMED_COLORS[index % NAMED_COLORS.length];
}
export function newDate(days) {
return DateTime.now().plus({days}).toJSDate();
}
export function newDateString(days) {
return DateTime.now().plus({days}).toISO();
}

12
package-lock.json generated
View File

@@ -5632,6 +5632,12 @@
"integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==",
"dev": true
},
"chartjs-adapter-luxon": {
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/chartjs-adapter-luxon/-/chartjs-adapter-luxon-1.0.0-beta.2.tgz",
"integrity": "sha512-1DKxf5jMXs5b1n+NPtzkeM7iAWCSCwCOVI6mmh1/U4rTzprxDRyWQcA9SOdScdZQNFHuij/VbmerQpnrKEHUJA==",
"dev": true
},
"chartjs-adapter-moment": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-0.1.2.tgz",
@@ -10448,6 +10454,12 @@
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
"dev": true
},
"luxon": {
"version": "1.26.0",
"resolved": "https://registry.npmjs.org/luxon/-/luxon-1.26.0.tgz",
"integrity": "sha512-+V5QIQ5f6CDXQpWNICELwjwuHdqeJM1UenlZWx5ujcRMc9venvluCjFb4t5NYLhb6IhkbMVOxzVuOqkgMxee2A==",
"dev": true
},
"magic-string": {
"version": "0.25.7",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",

View File

@@ -57,6 +57,7 @@
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vuepress/plugin-google-analytics": "1.8.2",
"chartjs-adapter-luxon": "^1.0.0-beta.2",
"chartjs-adapter-moment": "^0.1.2",
"chartjs-test-utils": "^0.2.2",
"concurrently": "^6.0.0",
@@ -80,6 +81,7 @@
"karma-rollup-preprocessor": "^7.0.7",
"karma-safari-private-launcher": "^1.0.0",
"karma-spec-reporter": "0.0.32",
"luxon": "^1.26.0",
"markdown-it-include": "^2.0.0",
"moment": "^2.29.1",
"pixelmatch": "^5.2.1",