From c6976e8975bfa12e1687a7e4df21f9e4c28a12e6 Mon Sep 17 00:00:00 2001 From: Jukka Kurkela Date: Sun, 20 Jun 2021 14:34:55 +0300 Subject: [PATCH] New plugin: subtitle (#9294) * New plugin: subtitle * Fix naive error for multiple charts --- docs/.vuepress/config.js | 6 +++ docs/configuration/subtitle.md | 28 ++++++++++++ docs/samples/subtitle/basic.md | 55 ++++++++++++++++++++++++ src/plugins/index.js | 1 + src/plugins/plugin.subtitle.js | 53 +++++++++++++++++++++++ test/fixtures/plugin.subtitle/basic.js | 41 ++++++++++++++++++ test/fixtures/plugin.subtitle/basic.png | Bin 0 -> 6564 bytes test/specs/plugin.subtitle.tests.js | 3 ++ 8 files changed, 187 insertions(+) create mode 100644 docs/configuration/subtitle.md create mode 100644 docs/samples/subtitle/basic.md create mode 100644 src/plugins/plugin.subtitle.js create mode 100644 test/fixtures/plugin.subtitle/basic.js create mode 100644 test/fixtures/plugin.subtitle/basic.png create mode 100644 test/specs/plugin.subtitle.tests.js diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 75670f307..335bbea41 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -217,6 +217,11 @@ module.exports = { ] }, { + title: 'Subtitle', + children: [ + 'subtitle/basic', + ] + }, { title: 'Tooltip', children: [ 'tooltip/position', @@ -304,6 +309,7 @@ module.exports = { 'configuration/layout', 'configuration/legend', 'configuration/title', + 'configuration/subtitle', 'configuration/tooltip', 'configuration/elements', 'configuration/decimation' diff --git a/docs/configuration/subtitle.md b/docs/configuration/subtitle.md new file mode 100644 index 000000000..41fa26d07 --- /dev/null +++ b/docs/configuration/subtitle.md @@ -0,0 +1,28 @@ +# Subtitle + +Subtitle is a second title placed under the main title, by default. It has exactly the same configuration options with the main [title](./title.md). + +## Subtitle Configuration + +Namespace: `options.plugins.subtitle`. The global defaults for subtitle are configured in `Chart.defaults.plugins.subtitle`. + +Excactly the same configuration options with [title](./title.md) are available for subtitle, the namespaces only differ. + +## Example Usage + +The example below would enable a title of 'Custom Chart Subtitle' on the chart that is created. + +```javascript +var chart = new Chart(ctx, { + type: 'line', + data: data, + options: { + plugins: { + subtitle: { + display: true, + text: 'Custom Chart Subtitle' + } + } + } +}); +``` diff --git a/docs/samples/subtitle/basic.md b/docs/samples/subtitle/basic.md new file mode 100644 index 000000000..d53d157a6 --- /dev/null +++ b/docs/samples/subtitle/basic.md @@ -0,0 +1,55 @@ +# Basic + +This sample shows basic usage of subtitle. + +```js chart-editor +// +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), + }, + ] +}; +// + +// +const config = { + type: 'line', + data: data, + options: { + plugins: { + title: { + display: true, + text: 'Chart Title', + }, + subtitle: { + display: true, + text: 'Chart Subtitle', + color: 'blue', + font: { + size: 12, + family: 'tahoma', + weight: 'normal', + style: 'italic' + }, + padding: { + bottom: 10 + } + } + } + } +}; +// + +module.exports = { + config: config, +}; +``` diff --git a/src/plugins/index.js b/src/plugins/index.js index 6a228f013..eb76545ed 100644 --- a/src/plugins/index.js +++ b/src/plugins/index.js @@ -1,5 +1,6 @@ export {default as Decimation} from './plugin.decimation'; export {default as Filler} from './plugin.filler'; export {default as Legend} from './plugin.legend'; +export {default as SubTitle} from './plugin.subtitle'; export {default as Title} from './plugin.title'; export {default as Tooltip} from './plugin.tooltip'; diff --git a/src/plugins/plugin.subtitle.js b/src/plugins/plugin.subtitle.js new file mode 100644 index 000000000..b68ccb3ba --- /dev/null +++ b/src/plugins/plugin.subtitle.js @@ -0,0 +1,53 @@ +import {Title} from './plugin.title'; +import layouts from '../core/core.layouts'; + +const map = new WeakMap(); + +export default { + id: 'subtitle', + + start(chart, _args, options) { + const title = new Title({ + ctx: chart.ctx, + options, + chart + }); + + layouts.configure(chart, title, options); + layouts.addBox(chart, title); + map.set(chart, title); + }, + + stop(chart) { + layouts.removeBox(chart, map.get(chart)); + map.delete(chart); + }, + + beforeUpdate(chart, _args, options) { + const title = map.get(chart); + layouts.configure(chart, title, options); + title.options = options; + }, + + defaults: { + align: 'center', + display: false, + font: { + weight: 'normal', + }, + fullSize: true, + padding: 0, + position: 'top', + text: '', + weight: 1500 // by default greater than legend (1000) and smaller that title (2000) + }, + + defaultRoutes: { + color: 'color' + }, + + descriptors: { + _scriptable: true, + _indexable: false, + }, +}; diff --git a/test/fixtures/plugin.subtitle/basic.js b/test/fixtures/plugin.subtitle/basic.js new file mode 100644 index 000000000..273d3215f --- /dev/null +++ b/test/fixtures/plugin.subtitle/basic.js @@ -0,0 +1,41 @@ + +module.exports = { + config: { + type: 'scatter', + data: { + datasets: [{ + data: [{x: 0, y: 0}, {x: 1, y: 1}, {x: 2, y: 2}], + backgroundColor: 'red', + radius: 1, + hoverRadius: 0 + }], + }, + options: { + scales: { + x: {display: false}, + y: {display: false} + }, + plugins: { + legend: false, + title: { + display: true, + text: 'Title Text', + }, + subtitle: { + display: true, + text: 'SubTitle Text', + }, + filler: false, + tooltip: false + }, + }, + + }, + options: { + spriteText: true, + canvas: { + height: 400, + width: 400 + } + } +}; diff --git a/test/fixtures/plugin.subtitle/basic.png b/test/fixtures/plugin.subtitle/basic.png new file mode 100644 index 0000000000000000000000000000000000000000..795ebad6953ab6a2939711097acb43923c6e2270 GIT binary patch literal 6564 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