@mozaic-ds/chart 0.1.0-beta.29 → 0.1.0-beta.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/mozaic-chart.js +2303 -2109
- package/dist/mozaic-chart.umd.cjs +9 -9
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/assets/base.css +1 -1
- package/src/components/bar/BarChart.stories.ts +99 -99
- package/src/components/bar/BarChart.vue +70 -53
- package/src/components/bar/index.ts +3 -3
- package/src/components/bubble/BubbleChart.stories.ts +12 -12
- package/src/components/bubble/BubbleChart.vue +118 -91
- package/src/components/bubble/index.ts +3 -3
- package/src/components/doughnut/DoughnutChart.stories.ts +38 -37
- package/src/components/doughnut/DoughnutChart.vue +89 -71
- package/src/components/doughnut/index.ts +3 -3
- package/src/components/index.ts +4 -4
- package/src/components/line/LineChart.stories.ts +38 -38
- package/src/components/line/LineChart.vue +54 -51
- package/src/components/line/index.ts +3 -3
- package/src/components/mixed/MixedBarLineChart.stories.ts +15 -15
- package/src/components/mixed/MixedBarLineChart.vue +44 -44
- package/src/components/mixed/index.ts +1 -1
- package/src/components/radar/RadarChart.stories.ts +100 -100
- package/src/components/radar/RadarChart.vue +41 -34
- package/src/components/radar/index.ts +3 -3
- package/src/main.ts +14 -7
- package/src/plugin.ts +9 -9
- package/src/services/BarChartFunctions.ts +133 -35
- package/src/services/BubbleTooltipService.ts +58 -56
- package/src/services/ChartsCommonLegend.ts +271 -127
- package/src/services/ColorFunctions.ts +1 -1
- package/src/services/DoughnutChartFunctions.ts +42 -13
- package/src/services/FormatUtilities.ts +28 -14
- package/src/services/GenericTooltipService.ts +125 -65
- package/src/services/MixedBarLineFunctions.ts +46 -44
- package/src/services/PatternFunctions.ts +25 -18
- package/src/services/RadarChartFunctions.ts +5 -5
- package/src/services/patterns/ChartDesign.ts +35 -24
- package/src/services/patterns/patternCircles.ts +63 -36
- package/src/services/patterns/patternDashedDiagonals.ts +64 -57
- package/src/services/patterns/patternDiagonals.ts +138 -106
- package/src/services/patterns/patternSquares.ts +86 -80
- package/src/services/patterns/patternVerticalLines.ts +76 -69
- package/src/services/patterns/patternZigzag.ts +92 -85
- package/src/stories/Changelog.mdx +2 -2
- package/src/stories/Contributing.mdx +2 -2
- package/src/stories/GettingStarted.mdx +5 -5
- package/src/stories/SupportAndOnboarding.mdx +6 -6
- package/src/types/AxisDefinition.ts +0 -2
- package/src/types/Chart.ts +9 -7
- package/src/types/DoughnutData.ts +8 -0
- package/src/types/GenericData.ts +10 -10
- package/src/types/LineChart.ts +4 -4
- package/src/types/RadarData.ts +33 -29
- package/src/types/TooltipChartType.ts +7 -7
- package/src/vite-env.d.ts +3 -3
package/src/main.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import BarChart from
|
|
2
|
-
import DoughnutChart from
|
|
3
|
-
import LineChart from
|
|
4
|
-
import RadarChart from
|
|
5
|
-
import MixedBarLineChart from
|
|
6
|
-
import BubbleChart from
|
|
1
|
+
import BarChart from './components/bar/BarChart.vue';
|
|
2
|
+
import DoughnutChart from './components/doughnut/DoughnutChart.vue';
|
|
3
|
+
import LineChart from './components/line/LineChart.vue';
|
|
4
|
+
import RadarChart from './components/radar/RadarChart.vue';
|
|
5
|
+
import MixedBarLineChart from './components/mixed/MixedBarLineChart.vue';
|
|
6
|
+
import BubbleChart from './components/bubble/BubbleChart.vue';
|
|
7
7
|
|
|
8
|
-
export {
|
|
8
|
+
export {
|
|
9
|
+
BarChart,
|
|
10
|
+
DoughnutChart,
|
|
11
|
+
LineChart,
|
|
12
|
+
RadarChart,
|
|
13
|
+
MixedBarLineChart,
|
|
14
|
+
BubbleChart
|
|
15
|
+
};
|
package/src/plugin.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { App } from
|
|
2
|
-
import * as Components from
|
|
1
|
+
import type { App } from 'vue';
|
|
2
|
+
import * as Components from './components';
|
|
3
3
|
|
|
4
4
|
const MozaicChart = {
|
|
5
5
|
install: (app: App, options: {}) => {
|
|
@@ -7,14 +7,14 @@ const MozaicChart = {
|
|
|
7
7
|
// @ts-ignore
|
|
8
8
|
app.component(name, Components[name]);
|
|
9
9
|
});
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export default MozaicChart;
|
|
14
14
|
|
|
15
|
-
export { BarChart } from
|
|
16
|
-
export { DoughnutChart } from
|
|
17
|
-
export { LineChart } from
|
|
18
|
-
export { RadarChart } from
|
|
19
|
-
export { MixedBarLineChart } from
|
|
20
|
-
export { BubbleChart } from
|
|
15
|
+
export { BarChart } from './components/bar';
|
|
16
|
+
export { DoughnutChart } from './components/doughnut';
|
|
17
|
+
export { LineChart } from './components/line';
|
|
18
|
+
export { RadarChart } from './components/radar';
|
|
19
|
+
export { MixedBarLineChart } from './components/mixed';
|
|
20
|
+
export { BubbleChart } from './components/bubble';
|
|
@@ -1,50 +1,95 @@
|
|
|
1
1
|
import { reactive, ref } from 'vue';
|
|
2
2
|
import type { Ref } from 'vue';
|
|
3
|
-
import {
|
|
4
|
-
getHtmlLegendPlugin
|
|
5
|
-
} from './ChartsCommonLegend';
|
|
3
|
+
import { getHtmlLegendPlugin } from './ChartsCommonLegend';
|
|
6
4
|
import PatternFunctions from './PatternFunctions';
|
|
7
5
|
import { addAlpha } from './ColorFunctions';
|
|
8
|
-
import {getVirtualNodeHeight} from 'mermaid/dist/diagrams/timeline/svgDraw';
|
|
6
|
+
import { getVirtualNodeHeight } from 'mermaid/dist/diagrams/timeline/svgDraw';
|
|
9
7
|
|
|
10
8
|
const { getPatternIndexWithShift } = PatternFunctions();
|
|
11
9
|
|
|
12
10
|
interface Dataset {
|
|
13
|
-
data: number[]
|
|
14
|
-
label: any
|
|
15
|
-
stack?: number
|
|
11
|
+
data: number[];
|
|
12
|
+
label: any;
|
|
13
|
+
stack?: number;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
16
|
export default function () {
|
|
19
17
|
const borderWidth = ref(3);
|
|
20
18
|
const barChartRef = ref(null as any);
|
|
21
|
-
const onHoverIndex: { dataSetIndex: number
|
|
19
|
+
const onHoverIndex: { dataSetIndex: number; columnIndex: number } = reactive({
|
|
22
20
|
dataSetIndex: -1,
|
|
23
21
|
columnIndex: -1
|
|
24
22
|
});
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
function privateGetHtmlLegendPlugin(
|
|
25
|
+
legendContainer: Ref,
|
|
26
|
+
selectMode: Ref<boolean>,
|
|
27
|
+
disableAccessibility: Ref<boolean>,
|
|
28
|
+
patternsColors: Ref<string[]>,
|
|
29
|
+
patternsList: Ref<
|
|
30
|
+
((
|
|
31
|
+
hover: boolean,
|
|
32
|
+
color: string,
|
|
33
|
+
disableAccessibility: boolean
|
|
34
|
+
) => CanvasPattern)[]
|
|
35
|
+
>,
|
|
36
|
+
enableHoverFeature: Ref<boolean>
|
|
37
|
+
) {
|
|
38
|
+
return getHtmlLegendPlugin(
|
|
39
|
+
legendContainer,
|
|
40
|
+
selectMode,
|
|
41
|
+
onHoverIndex,
|
|
42
|
+
disableAccessibility,
|
|
43
|
+
patternsColors,
|
|
44
|
+
patternsList,
|
|
45
|
+
enableHoverFeature
|
|
46
|
+
);
|
|
29
47
|
}
|
|
30
48
|
// Hack to force the chart to reload on Hover
|
|
31
|
-
function reloadChart
|
|
49
|
+
function reloadChart() {
|
|
32
50
|
borderWidth.value = 4;
|
|
33
51
|
borderWidth.value = 3;
|
|
34
52
|
}
|
|
35
53
|
|
|
36
|
-
function getStackedDatasets
|
|
54
|
+
function getStackedDatasets(
|
|
55
|
+
datasets: Dataset[],
|
|
56
|
+
stackDatasets: boolean,
|
|
57
|
+
disableAccessibility: boolean,
|
|
58
|
+
patternsColors: string[],
|
|
59
|
+
patternsList: ((
|
|
60
|
+
hover: boolean,
|
|
61
|
+
color: string,
|
|
62
|
+
disableAccessibility: boolean
|
|
63
|
+
) => CanvasPattern)[],
|
|
64
|
+
patternShifting?: number
|
|
65
|
+
) {
|
|
37
66
|
// Hack to force refresh
|
|
38
67
|
const borderWithValue = borderWidth.value;
|
|
39
68
|
return datasets.map((dataset, datasetIndex) => {
|
|
40
69
|
return {
|
|
41
70
|
borderColor: function (context: any) {
|
|
42
|
-
return disableAccessibility
|
|
71
|
+
return disableAccessibility
|
|
72
|
+
? '#00000000'
|
|
73
|
+
: getBorderColor(
|
|
74
|
+
datasetIndex,
|
|
75
|
+
context.index,
|
|
76
|
+
patternsColors,
|
|
77
|
+
patternShifting
|
|
78
|
+
);
|
|
43
79
|
},
|
|
44
80
|
backgroundColor: function (context: any) {
|
|
45
|
-
return getPattern(
|
|
81
|
+
return getPattern(
|
|
82
|
+
datasetIndex,
|
|
83
|
+
context.index,
|
|
84
|
+
disableAccessibility,
|
|
85
|
+
patternsColors,
|
|
86
|
+
patternsList,
|
|
87
|
+
patternShifting
|
|
88
|
+
);
|
|
89
|
+
},
|
|
90
|
+
borderWidth: function () {
|
|
91
|
+
return disableAccessibility ? 1 : borderWithValue;
|
|
46
92
|
},
|
|
47
|
-
borderWidth: function () {return disableAccessibility ? 1 : borderWithValue},
|
|
48
93
|
|
|
49
94
|
data: dataset.data,
|
|
50
95
|
label: dataset.label,
|
|
@@ -53,53 +98,106 @@ export default function () {
|
|
|
53
98
|
});
|
|
54
99
|
}
|
|
55
100
|
|
|
56
|
-
function getDatasets
|
|
57
|
-
|
|
101
|
+
function getDatasets(
|
|
102
|
+
firstDataSet: Dataset,
|
|
103
|
+
secondDataSet: Dataset,
|
|
104
|
+
patternsColors: string[],
|
|
105
|
+
patternsList: ((
|
|
106
|
+
hover: boolean,
|
|
107
|
+
color: string,
|
|
108
|
+
disableAccessibility: boolean
|
|
109
|
+
) => CanvasPattern)[],
|
|
110
|
+
disableAccessibility: boolean
|
|
111
|
+
) {
|
|
112
|
+
return getStackedDatasets(
|
|
113
|
+
[firstDataSet, secondDataSet],
|
|
114
|
+
false,
|
|
115
|
+
disableAccessibility,
|
|
116
|
+
patternsColors,
|
|
117
|
+
patternsList
|
|
118
|
+
);
|
|
58
119
|
}
|
|
59
120
|
|
|
60
|
-
function getBorderColor
|
|
121
|
+
function getBorderColor(
|
|
122
|
+
dataSetIndex: number,
|
|
123
|
+
contextIndex: number,
|
|
124
|
+
patternsColors: string[],
|
|
125
|
+
patternShifting?: number
|
|
126
|
+
) {
|
|
61
127
|
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
|
|
62
128
|
if (displayFullOpacity(dataSetIndex, contextIndex)) {
|
|
63
129
|
return patternsColors[index];
|
|
64
130
|
} else {
|
|
65
|
-
return addAlpha(patternsColors[index],0.2);
|
|
131
|
+
return addAlpha(patternsColors[index], 0.2);
|
|
66
132
|
}
|
|
67
133
|
}
|
|
68
134
|
|
|
69
|
-
function getPattern
|
|
135
|
+
function getPattern(
|
|
136
|
+
dataSetIndex: number,
|
|
137
|
+
contextIndex: number,
|
|
138
|
+
disableAccessibility: boolean,
|
|
139
|
+
patternsColors: string[],
|
|
140
|
+
patternsList: ((
|
|
141
|
+
hover: boolean,
|
|
142
|
+
color: string,
|
|
143
|
+
disableAccessibility: boolean
|
|
144
|
+
) => CanvasPattern)[],
|
|
145
|
+
patternShifting?: number
|
|
146
|
+
) {
|
|
70
147
|
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
|
|
71
148
|
if (displayFullOpacity(dataSetIndex, contextIndex)) {
|
|
72
|
-
return patternsList[index](
|
|
149
|
+
return patternsList[index](
|
|
150
|
+
false,
|
|
151
|
+
patternsColors[index],
|
|
152
|
+
disableAccessibility
|
|
153
|
+
);
|
|
73
154
|
} else {
|
|
74
|
-
return patternsList[index](
|
|
155
|
+
return patternsList[index](
|
|
156
|
+
true,
|
|
157
|
+
patternsColors[index],
|
|
158
|
+
disableAccessibility
|
|
159
|
+
);
|
|
75
160
|
}
|
|
76
161
|
}
|
|
77
162
|
|
|
78
|
-
function nothingHovered
|
|
163
|
+
function nothingHovered(): boolean {
|
|
79
164
|
return onHoverIndex.dataSetIndex < 0;
|
|
80
165
|
}
|
|
81
166
|
|
|
82
|
-
function columnHovered
|
|
83
|
-
return
|
|
167
|
+
function columnHovered(dataSetIndex: number, contextIndex: number): boolean {
|
|
168
|
+
return (
|
|
169
|
+
onHoverIndex.dataSetIndex === dataSetIndex &&
|
|
170
|
+
onHoverIndex.columnIndex === contextIndex
|
|
171
|
+
);
|
|
84
172
|
}
|
|
85
173
|
|
|
86
|
-
function legendHovered
|
|
87
|
-
return
|
|
174
|
+
function legendHovered(dataSetIndex: number): boolean {
|
|
175
|
+
return (
|
|
176
|
+
onHoverIndex.dataSetIndex === dataSetIndex && onHoverIndex.columnIndex < 0
|
|
177
|
+
);
|
|
88
178
|
}
|
|
89
179
|
|
|
90
|
-
function displayFullOpacity
|
|
91
|
-
|
|
180
|
+
function displayFullOpacity(
|
|
181
|
+
dataSetIndex: number,
|
|
182
|
+
contextIndex: number
|
|
183
|
+
): boolean {
|
|
184
|
+
return (
|
|
185
|
+
nothingHovered() ||
|
|
92
186
|
columnHovered(dataSetIndex, contextIndex) ||
|
|
93
|
-
legendHovered(dataSetIndex)
|
|
187
|
+
legendHovered(dataSetIndex)
|
|
188
|
+
);
|
|
94
189
|
}
|
|
95
190
|
|
|
96
|
-
function resetOnHoverIndex
|
|
191
|
+
function resetOnHoverIndex() {
|
|
97
192
|
onHoverIndex.dataSetIndex = -1;
|
|
98
193
|
onHoverIndex.columnIndex = -1;
|
|
99
194
|
}
|
|
100
195
|
|
|
101
|
-
function getOnHoverOptions
|
|
102
|
-
return (
|
|
196
|
+
function getOnHoverOptions() {
|
|
197
|
+
return (
|
|
198
|
+
_ignore: unknown,
|
|
199
|
+
activeElements: Array<{ index: number; datasetIndex: number }>
|
|
200
|
+
) => {
|
|
103
201
|
if (activeElements[0] !== undefined) {
|
|
104
202
|
onHoverIndex.dataSetIndex = activeElements[0].datasetIndex;
|
|
105
203
|
onHoverIndex.columnIndex = activeElements[0].index;
|
|
@@ -120,6 +218,6 @@ export default function () {
|
|
|
120
218
|
privateGetHtmlLegendPlugin,
|
|
121
219
|
getPatternIndexWithShift,
|
|
122
220
|
barChartRef,
|
|
123
|
-
borderWidth
|
|
221
|
+
borderWidth
|
|
124
222
|
};
|
|
125
223
|
}
|
|
@@ -1,65 +1,67 @@
|
|
|
1
|
-
import {Context, GenericTooltipService} from './GenericTooltipService';
|
|
1
|
+
import { Context, GenericTooltipService } from './GenericTooltipService';
|
|
2
2
|
|
|
3
3
|
export type BubbleTooltipLine = {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
const tooltipLineStyle =
|
|
4
|
+
label: string;
|
|
5
|
+
value: string;
|
|
6
|
+
unit: string;
|
|
7
|
+
};
|
|
8
|
+
const tooltipLineStyle =
|
|
9
|
+
'background: white; border-bottom: 1px solid #CCCCCC; border-radius: 5px; padding: 10px 20px';
|
|
9
10
|
|
|
10
11
|
export class BubbleTooltipService extends GenericTooltipService {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
createBubbleTooltip(
|
|
14
|
-
context: Context,
|
|
15
|
-
lines: BubbleTooltipLine[],
|
|
16
|
-
title: string,
|
|
17
|
-
) {
|
|
18
|
-
if(!title || title === ''){
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
let tooltipEl = document.querySelector('#chartjs-tooltip') as HTMLElement | null;
|
|
22
|
-
if (!tooltipEl) {
|
|
23
|
-
tooltipEl = this.createNewTooltipElement();
|
|
24
|
-
}
|
|
25
|
-
const tooltipModel = context.tooltip;
|
|
26
|
-
if (tooltipModel.opacity === 0) {
|
|
27
|
-
tooltipEl.style.opacity = '0';
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
if (tooltipModel.body) {
|
|
31
|
-
this.titleLines = tooltipModel.title || [];
|
|
32
|
-
const bodyLines = tooltipModel.body.map(this.getBody);
|
|
33
|
-
const body = bodyLines[0];
|
|
34
|
-
this.addBubbleLegendToDom(lines, body, tooltipEl, title);
|
|
12
|
+
fontProperties = 'font-family: Arial; font-size: 16px';
|
|
35
13
|
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
createBubbleTooltip(
|
|
15
|
+
context: Context,
|
|
16
|
+
lines: BubbleTooltipLine[],
|
|
17
|
+
title: string
|
|
18
|
+
) {
|
|
19
|
+
if (!title || title === '') {
|
|
20
|
+
return;
|
|
38
21
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
title: string,
|
|
45
|
-
) {
|
|
46
|
-
const legendText = body[0].split(':')[0];
|
|
47
|
-
const spanText = `<span style="${this.fontProperties}">${title}</span>`;
|
|
48
|
-
let innerHtml = `<div style="${tooltipLineStyle}; font-weight: bold" class="tooltipTitle">${spanText}</div>`;
|
|
49
|
-
const innerHtmlToAdd = this.getBubbleInnerHtml(lines);
|
|
50
|
-
innerHtml += innerHtmlToAdd;
|
|
51
|
-
const tableRoot = tooltipEl?.querySelector('.tooltipCtn') as HTMLElement;
|
|
52
|
-
tableRoot.innerHTML = innerHtml;
|
|
22
|
+
let tooltipEl = document.querySelector(
|
|
23
|
+
'#chartjs-tooltip'
|
|
24
|
+
) as HTMLElement | null;
|
|
25
|
+
if (!tooltipEl) {
|
|
26
|
+
tooltipEl = this.createNewTooltipElement();
|
|
53
27
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
innerLinesHtml += `<div style="${this.fontProperties}; ${tooltipLineStyle}; display:flex; justify-content: space-between;">`;
|
|
59
|
-
innerLinesHtml += `<div>${line.label}</div>`;
|
|
60
|
-
innerLinesHtml += `<div>${line.value}${line.unit}</div>`;
|
|
61
|
-
innerLinesHtml += `</div>`;
|
|
62
|
-
})
|
|
63
|
-
return `<div>${innerLinesHtml}</div>`;
|
|
28
|
+
const tooltipModel = context.tooltip;
|
|
29
|
+
if (tooltipModel.opacity === 0) {
|
|
30
|
+
tooltipEl.style.opacity = '0';
|
|
31
|
+
return;
|
|
64
32
|
}
|
|
33
|
+
if (tooltipModel.body) {
|
|
34
|
+
this.titleLines = tooltipModel.title || [];
|
|
35
|
+
const bodyLines = tooltipModel.body.map(this.getBody);
|
|
36
|
+
const body = bodyLines[0];
|
|
37
|
+
this.addBubbleLegendToDom(lines, body, tooltipEl, title);
|
|
38
|
+
}
|
|
39
|
+
this.handleTooltipPosition(context, tooltipModel, tooltipEl);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
addBubbleLegendToDom(
|
|
43
|
+
lines: BubbleTooltipLine[],
|
|
44
|
+
body: Array<string>,
|
|
45
|
+
tooltipEl: HTMLElement,
|
|
46
|
+
title: string
|
|
47
|
+
) {
|
|
48
|
+
const legendText = body[0].split(':')[0];
|
|
49
|
+
const spanText = `<span style="${this.fontProperties}">${title}</span>`;
|
|
50
|
+
let innerHtml = `<div style="${tooltipLineStyle}; font-weight: bold" class="tooltipTitle">${spanText}</div>`;
|
|
51
|
+
const innerHtmlToAdd = this.getBubbleInnerHtml(lines);
|
|
52
|
+
innerHtml += innerHtmlToAdd;
|
|
53
|
+
const tableRoot = tooltipEl?.querySelector('.tooltipCtn') as HTMLElement;
|
|
54
|
+
tableRoot.innerHTML = innerHtml;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getBubbleInnerHtml(lines: BubbleTooltipLine[]): string {
|
|
58
|
+
let innerLinesHtml = '';
|
|
59
|
+
lines.forEach((line) => {
|
|
60
|
+
innerLinesHtml += `<div style="${this.fontProperties}; ${tooltipLineStyle}; display:flex; justify-content: space-between;">`;
|
|
61
|
+
innerLinesHtml += `<div>${line.label}</div>`;
|
|
62
|
+
innerLinesHtml += `<div>${line.value}${line.unit}</div>`;
|
|
63
|
+
innerLinesHtml += `</div>`;
|
|
64
|
+
});
|
|
65
|
+
return `<div>${innerLinesHtml}</div>`;
|
|
66
|
+
}
|
|
65
67
|
}
|