|
| 1 | +# Inner chart |
| 2 | + |
| 3 | +```js chart-editor |
| 4 | +// <block:setup:5> |
| 5 | +const DATA_COUNT = 12; |
| 6 | +const MIN = 0; |
| 7 | +const MAX = 100; |
| 8 | + |
| 9 | +const innerChart = Utils.getChart(); |
| 10 | +const innerDataset = innerChart.data.datasets[0]; |
| 11 | + |
| 12 | +const numberCfg = {count: DATA_COUNT, min: MIN, max: MAX}; |
| 13 | + |
| 14 | +const data = { |
| 15 | + labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], |
| 16 | + datasets: [{ |
| 17 | + data: Utils.numbers(numberCfg), |
| 18 | + borderColor: innerDataset.backgroundColor[0], |
| 19 | + backgroundColor: 'transparent' |
| 20 | + }, { |
| 21 | + data: Utils.numbers(numberCfg), |
| 22 | + borderColor: innerDataset.backgroundColor[1], |
| 23 | + backgroundColor: 'transparent', |
| 24 | + hidden: true |
| 25 | + }, { |
| 26 | + data: Utils.numbers(numberCfg), |
| 27 | + borderColor: innerDataset.backgroundColor[2], |
| 28 | + backgroundColor: 'transparent', |
| 29 | + hidden: true |
| 30 | + }] |
| 31 | +}; |
| 32 | +// </block:setup> |
| 33 | + |
| 34 | +// <block:annotation1:1> |
| 35 | +const annotation1 = { |
| 36 | + type: 'label', |
| 37 | + content: innerChart.canvas, |
| 38 | + xValue: 1, |
| 39 | + yValue: 135, |
| 40 | + enter: (ctx) => setCursor(ctx, 'pointer'), |
| 41 | + leave: (ctx) => setCursor(ctx, 'default'), |
| 42 | + click: clickOnInnerChart |
| 43 | +}; |
| 44 | +// </block:annotation1> |
| 45 | + |
| 46 | +// <block:annotation2:2> |
| 47 | +const annotation2 = { |
| 48 | + type: 'label', |
| 49 | + content: (ctx) => [innerChart.data.labels[getVisibleDatasetIndex(ctx)], |
| 50 | + 'items trend'], |
| 51 | + callout: { |
| 52 | + enabled: true, |
| 53 | + position: 'bottom', |
| 54 | + margin: 0 |
| 55 | + }, |
| 56 | + font: { |
| 57 | + size: 16 |
| 58 | + }, |
| 59 | + backgroundColor: 'white', |
| 60 | + borderWidth: 1, |
| 61 | + xAdjust: -60, |
| 62 | + xValue: (ctx) => point(ctx).x, |
| 63 | + yAdjust: -60, |
| 64 | + yValue: (ctx) => point(ctx).y |
| 65 | +}; |
| 66 | +// </block:annotation2> |
| 67 | + |
| 68 | +// <block:annotation3:3> |
| 69 | +const annotation3 = { |
| 70 | + type: 'label', |
| 71 | + content: ['Click on a slice of the pie chart', 'to see the data in the main chart'], |
| 72 | + color: 'rgba(0, 0, 0, 0.5)', |
| 73 | + xValue: 3.2, |
| 74 | + yValue: 150, |
| 75 | +}; |
| 76 | +// </block:annotation3> |
| 77 | + |
| 78 | +/* <block:config:0> */ |
| 79 | +const config = { |
| 80 | + type: 'line', |
| 81 | + data, |
| 82 | + options: { |
| 83 | + scales: { |
| 84 | + y: { |
| 85 | + beginAtZero: true, |
| 86 | + min: 0, |
| 87 | + max: 160 |
| 88 | + } |
| 89 | + }, |
| 90 | + plugins: { |
| 91 | + annotation: { |
| 92 | + annotations: { |
| 93 | + annotation1, |
| 94 | + annotation2, |
| 95 | + annotation3 |
| 96 | + } |
| 97 | + } |
| 98 | + } |
| 99 | + } |
| 100 | +}; |
| 101 | +/* </block:config> */ |
| 102 | + |
| 103 | +// <block:utils:4> |
| 104 | +function clickOnInnerChart(ctx, event) { |
| 105 | + event.x = event.x - ctx.element.x; |
| 106 | + event.y = event.y - ctx.element.y; |
| 107 | + const elements = innerChart.getElementsAtEventForMode(event, 'point', {}, true); |
| 108 | + if (elements.length) { |
| 109 | + const first = elements[0]; |
| 110 | + ctx.chart.setDatasetVisibility(getVisibleDatasetIndex(ctx), false); |
| 111 | + ctx.chart.show(first.index); |
| 112 | + } |
| 113 | +} |
| 114 | + |
| 115 | +function getVisibleDatasetIndex(ctx) { |
| 116 | + const chart = ctx.chart; |
| 117 | + for (let i = 0; i < chart.data.datasets.length; i++) { |
| 118 | + if (chart.isDatasetVisible(i)) { |
| 119 | + return i; |
| 120 | + } |
| 121 | + } |
| 122 | + return 0; |
| 123 | +} |
| 124 | + |
| 125 | +function point(ctx) { |
| 126 | + const dataset = ctx.chart.data.datasets[getVisibleDatasetIndex(ctx)]; |
| 127 | + const values = dataset.data.filter((value, i) => i > dataset.data.length - 4); |
| 128 | + const y = Math.max(...values); |
| 129 | + const x = dataset.data.lastIndexOf(y); |
| 130 | + return {x, y}; |
| 131 | +} |
| 132 | + |
| 133 | +function setCursor(ctx, type) { |
| 134 | + ctx.chart.canvas.style.cursor = type; |
| 135 | +} |
| 136 | +// </block:utils> |
| 137 | + |
| 138 | +const actions = [ |
| 139 | + { |
| 140 | + name: 'Randomize', |
| 141 | + handler: function(chart) { |
| 142 | + chart.data.datasets.forEach(function(dataset, i) { |
| 143 | + dataset.data = dataset.data.map(() => Utils.rand(MIN, MAX)); |
| 144 | + }); |
| 145 | + chart.update(); |
| 146 | + innerChart.data.datasets.forEach(function(dataset, i) { |
| 147 | + dataset.data = dataset.data.map(() => Utils.rand(MIN, MAX)); |
| 148 | + }); |
| 149 | + innerChart.update(); |
| 150 | + } |
| 151 | + } |
| 152 | +]; |
| 153 | + |
| 154 | +module.exports = { |
| 155 | + actions: actions, |
| 156 | + config: config |
| 157 | +}; |
| 158 | +``` |
0 commit comments