From e40e624a5d11d8646d1085c06361a4f8fa2d80bd Mon Sep 17 00:00:00 2001 From: kurkle Date: Sun, 20 Jun 2021 08:38:55 +0300 Subject: [PATCH 1/2] New plugin: subtitle --- 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 | 51 ++++++++++++++++++++++ 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, 185 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 75670f30723..335bbea4197 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 00000000000..41fa26d077f --- /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 00000000000..d53d157a675 --- /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 6a228f013e8..eb76545ed4f 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 00000000000..9f55bcb1461 --- /dev/null +++ b/src/plugins/plugin.subtitle.js @@ -0,0 +1,51 @@ +import {Title} from './plugin.title'; +import layouts from '../core/core.layouts'; + +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); + this._title = title; + }, + + stop(chart) { + layouts.removeBox(chart, this.title); + delete this._title; + }, + + beforeUpdate(chart, _args, options) { + const title = this._title; + 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 00000000000..273d3215f64 --- /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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 bdP6I=#exs>mMQS}1?0Cc$hUIOU(WvxNBe$r literal 0 HcmV?d00001 diff --git a/test/specs/plugin.subtitle.tests.js b/test/specs/plugin.subtitle.tests.js new file mode 100644 index 00000000000..10d8ac0a1cb --- /dev/null +++ b/test/specs/plugin.subtitle.tests.js @@ -0,0 +1,3 @@ +describe('plugin.subtitle', function() { + describe('auto', jasmine.fixture.specs('plugin.subtitle')); +}); From 20e1ec89ee386f3ddd01b01d534f5e8db2e5b5ce Mon Sep 17 00:00:00 2001 From: kurkle Date: Sun, 20 Jun 2021 09:09:32 +0300 Subject: [PATCH 2/2] Fix naive error for multiple charts --- src/plugins/plugin.subtitle.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/plugin.subtitle.js b/src/plugins/plugin.subtitle.js index 9f55bcb1461..b68ccb3baed 100644 --- a/src/plugins/plugin.subtitle.js +++ b/src/plugins/plugin.subtitle.js @@ -1,6 +1,8 @@ import {Title} from './plugin.title'; import layouts from '../core/core.layouts'; +const map = new WeakMap(); + export default { id: 'subtitle', @@ -13,16 +15,16 @@ export default { layouts.configure(chart, title, options); layouts.addBox(chart, title); - this._title = title; + map.set(chart, title); }, stop(chart) { - layouts.removeBox(chart, this.title); - delete this._title; + layouts.removeBox(chart, map.get(chart)); + map.delete(chart); }, beforeUpdate(chart, _args, options) { - const title = this._title; + const title = map.get(chart); layouts.configure(chart, title, options); title.options = options; },