@mozaic-ds/chart 0.1.0-beta.0 → 0.1.0-beta.2
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/dist/mozaic-chart.js +2421 -2255
- package/dist/mozaic-chart.umd.cjs +11 -11
- package/dist/style.css +1 -1
- package/package.json +25 -23
- package/src/components/bar/BarChart.stories.ts +7 -0
- package/src/components/bar/BarChart.vue +60 -8
- package/src/components/bar/index.ts +8 -0
- package/src/components/doughnut/DoughnutChart.stories.ts +2 -0
- package/src/components/doughnut/DoughnutChart.vue +98 -51
- package/src/components/doughnut/index.ts +8 -0
- package/src/components/index.ts +4 -0
- package/src/components/line/LineChart.vue +46 -3
- package/src/components/line/index.ts +8 -0
- package/src/components/radar/RadarChart.vue +59 -15
- package/src/components/radar/index.ts +8 -0
- package/src/plugin.ts +18 -0
- package/src/services/BarChartFunctions.ts +16 -20
- package/src/services/ChartsCommonLegend.ts +20 -25
- package/src/services/ColorFunctions.ts +4 -0
- package/src/services/DoughnutChartFunctions.ts +24 -17
- package/src/services/GenericTooltipService.ts +39 -32
- package/src/services/patterns/ChartDesign.ts +15 -9
- package/src/services/patterns/patternCircles.ts +63 -50
- package/src/services/patterns/patternDashedDiagonals.ts +46 -32
- package/src/services/patterns/patternDiagonals.ts +85 -71
- package/src/services/patterns/patternSquares.ts +56 -44
- package/src/services/patterns/patternVerticalLines.ts +41 -28
- package/src/services/patterns/patternZigzag.ts +20 -7
|
@@ -22,10 +22,11 @@ import type { Area } from '../../types/RadarData';
|
|
|
22
22
|
import { Radar } from 'vue-chartjs';
|
|
23
23
|
import type { ActiveElement, ChartData } from 'chart.js';
|
|
24
24
|
import {Context, GenericTooltipService} from '../../services/GenericTooltipService';
|
|
25
|
-
import { formatWithThousandsSeprators } from '../../services/FormatUtilities';
|
|
25
|
+
import { formatWithThousandsSeprators, numberWithThousandSeparators } from '../../services/FormatUtilities';
|
|
26
26
|
import { TooltipChartType } from '../../types/TooltipChartType';
|
|
27
27
|
import { drawLabels } from '../../services/RadarChartFunctions';
|
|
28
28
|
import type { Chart, ChartItem } from '../../services/ChartsCommonLegend';
|
|
29
|
+
import { addAlpha } from '../../services/ColorFunctions'
|
|
29
30
|
import {
|
|
30
31
|
Chart as ChartJS,
|
|
31
32
|
Filler,
|
|
@@ -48,6 +49,8 @@ import {
|
|
|
48
49
|
switchItemVisibility
|
|
49
50
|
} from '../../services/ChartsCommonLegend';
|
|
50
51
|
|
|
52
|
+
import ChartDesign from '../../services/patterns/ChartDesign';
|
|
53
|
+
|
|
51
54
|
ChartJS.register(
|
|
52
55
|
Title,
|
|
53
56
|
Tooltip,
|
|
@@ -57,6 +60,12 @@ ChartJS.register(
|
|
|
57
60
|
PointElement,
|
|
58
61
|
Filler,
|
|
59
62
|
);
|
|
63
|
+
|
|
64
|
+
const {
|
|
65
|
+
colourSets,
|
|
66
|
+
patternsStandardList
|
|
67
|
+
} = ChartDesign();
|
|
68
|
+
|
|
60
69
|
const radarComponentChartProps = defineProps({
|
|
61
70
|
chartId: {
|
|
62
71
|
type: String,
|
|
@@ -70,6 +79,27 @@ const radarComponentChartProps = defineProps({
|
|
|
70
79
|
type: Array as PropType<string[]>,
|
|
71
80
|
default: () => []
|
|
72
81
|
},
|
|
82
|
+
// disable accessibility patterns
|
|
83
|
+
disableAccessibility: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
default: false
|
|
86
|
+
},
|
|
87
|
+
// colourSet props is used to choose the colour set of the charts as defined in the Figma prototypes.
|
|
88
|
+
// 7 colour sets are currently defined :
|
|
89
|
+
// - Default 0 corresponds to the current one
|
|
90
|
+
// - 1 to 6 corresponds to the "new" colour sets : https://www.figma.com/file/Hn6PyvnR385Ta0XN3KqOI9/04.-Dataviz---Documentation-(read-only)?type=design&node-id=1-69316&mode=design&t=sDytQ5BipsryWkuA-0
|
|
91
|
+
// Remark : All the sets are defined in /src/services/patterns/ChartDesign.ts
|
|
92
|
+
colourSet: {
|
|
93
|
+
type: Number,
|
|
94
|
+
default: 0
|
|
95
|
+
},
|
|
96
|
+
// 6 patterns exist and are not randomly given but follow the order defined in patternsStandardList /src/services/patterns/ChartDesign.ts
|
|
97
|
+
// Additionally, a pattern has only one possible colour per colour set as defined in the Figma prototype.
|
|
98
|
+
// In some use cases, the chart may need to show a different orders of these patterns, this can be changed using the props newPatternsOrder
|
|
99
|
+
newPatternsOrder: {
|
|
100
|
+
type: Array as PropType<number[]>,
|
|
101
|
+
default: () => [0,1,2,3,4,5]
|
|
102
|
+
},
|
|
73
103
|
areas: {
|
|
74
104
|
type: Array as PropType<Area[]>,
|
|
75
105
|
default: () => []
|
|
@@ -87,36 +117,47 @@ const radarComponentChartProps = defineProps({
|
|
|
87
117
|
default: () => [],
|
|
88
118
|
},
|
|
89
119
|
})
|
|
120
|
+
|
|
121
|
+
const patternsColors = computed(() => radarComponentChartProps.newPatternsOrder.length !== 6
|
|
122
|
+
? colourSets[radarComponentChartProps.colourSet]
|
|
123
|
+
: radarComponentChartProps.newPatternsOrder.map((id)=> {return colourSets[radarComponentChartProps.colourSet][id]})
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
const patternsOrderedList = computed(() => radarComponentChartProps.newPatternsOrder.length !== 6
|
|
127
|
+
? patternsStandardList
|
|
128
|
+
: radarComponentChartProps.newPatternsOrder.map((id)=> {return patternsStandardList[id]})
|
|
129
|
+
)
|
|
130
|
+
|
|
90
131
|
const radarData = computed<ChartData<'radar'>>(() => ({
|
|
91
132
|
labels: getRadarLabels(),
|
|
92
133
|
datasets: [
|
|
93
134
|
{
|
|
94
135
|
label: 'Data One',
|
|
95
|
-
backgroundColor:
|
|
96
|
-
borderColor:
|
|
97
|
-
pointBackgroundColor:
|
|
98
|
-
pointBorderColor:
|
|
136
|
+
backgroundColor: addAlpha(patternsColors.value[0], 0.1),
|
|
137
|
+
borderColor: patternsColors.value[0],
|
|
138
|
+
pointBackgroundColor: '#FFFFFF',
|
|
139
|
+
pointBorderColor: patternsColors.value[0],
|
|
99
140
|
pointBorderWidth: 2,
|
|
100
141
|
borderWidth: 2,
|
|
101
142
|
pointHitRadius: 55,
|
|
102
143
|
pointRadius: 5,
|
|
103
|
-
pointHoverBackgroundColor:
|
|
104
|
-
pointHoverBorderColor:
|
|
144
|
+
pointHoverBackgroundColor: patternsColors.value[0],
|
|
145
|
+
pointHoverBorderColor: patternsColors.value[0],
|
|
105
146
|
data: radarComponentChartProps.areas[0].areaData.map((x: { position: number }) => x.position)
|
|
106
147
|
},
|
|
107
148
|
{
|
|
108
149
|
label: 'Data Two',
|
|
109
|
-
backgroundColor:
|
|
110
|
-
borderColor:
|
|
111
|
-
pointBackgroundColor: '
|
|
112
|
-
pointBorderColor:
|
|
150
|
+
backgroundColor: addAlpha(patternsColors.value[1], 0.1),
|
|
151
|
+
borderColor: patternsColors.value[1],
|
|
152
|
+
pointBackgroundColor: '#FFFFFF',
|
|
153
|
+
pointBorderColor: patternsColors.value[1],
|
|
113
154
|
pointBorderWidth: 2,
|
|
114
155
|
borderWidth: 2,
|
|
115
156
|
pointHitRadius: 55,
|
|
116
157
|
pointRadius: 5,
|
|
117
158
|
pointStyle: 'rectRot',
|
|
118
|
-
pointHoverBackgroundColor:
|
|
119
|
-
pointHoverBorderColor:
|
|
159
|
+
pointHoverBackgroundColor: patternsColors.value[1],
|
|
160
|
+
pointHoverBorderColor: patternsColors.value[1],
|
|
120
161
|
data: radarComponentChartProps.areas[1].areaData.map((x: { position: number }) => x.position)
|
|
121
162
|
}
|
|
122
163
|
]
|
|
@@ -145,7 +186,10 @@ const chartOptions: any = {
|
|
|
145
186
|
new GenericTooltipService().createTooltip(
|
|
146
187
|
context,
|
|
147
188
|
getTooltipData,
|
|
148
|
-
{ chartType: TooltipChartType.RADAR }
|
|
189
|
+
{ chartType: TooltipChartType.RADAR },
|
|
190
|
+
patternsColors.value,
|
|
191
|
+
patternsOrderedList.value,
|
|
192
|
+
radarComponentChartProps.disableAccessibility
|
|
149
193
|
);
|
|
150
194
|
}
|
|
151
195
|
}
|
|
@@ -220,7 +264,7 @@ const radarPlugins = [{
|
|
|
220
264
|
let liContent;
|
|
221
265
|
li.style.marginRight = '0.625rem';
|
|
222
266
|
if (!selectMode.value) {
|
|
223
|
-
liContent = createLegendElementWithSquareArea(item);
|
|
267
|
+
liContent = createLegendElementWithSquareArea(item, true);
|
|
224
268
|
} else {
|
|
225
269
|
liContent = createLegendElementWithCheckbox(chart, item);
|
|
226
270
|
}
|
package/src/plugin.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { App } from "vue";
|
|
2
|
+
import * as Components from "./components";
|
|
3
|
+
|
|
4
|
+
const MozaicChart = {
|
|
5
|
+
install: (app: App, options: {}) => {
|
|
6
|
+
Object.keys(Components).forEach((name) => {
|
|
7
|
+
// @ts-ignore
|
|
8
|
+
app.component(name, Components[name]);
|
|
9
|
+
});
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default MozaicChart;
|
|
14
|
+
|
|
15
|
+
export { BarChart } from "./components/bar";
|
|
16
|
+
export { DoughnutChart } from "./components/doughnut";
|
|
17
|
+
export { LineChart } from "./components/line";
|
|
18
|
+
export { RadarChart } from "./components/radar";
|
|
@@ -4,14 +4,9 @@ import {
|
|
|
4
4
|
getHtmlLegendPlugin
|
|
5
5
|
} from './ChartsCommonLegend';
|
|
6
6
|
import PatternFunctions from './PatternFunctions';
|
|
7
|
-
import
|
|
7
|
+
import { addAlpha } from './ColorFunctions';
|
|
8
8
|
|
|
9
9
|
const { getPatternIndexWithShift } = PatternFunctions();
|
|
10
|
-
const {
|
|
11
|
-
patternsColors,
|
|
12
|
-
patternsColorsLowerOpacity,
|
|
13
|
-
patternsStandardList
|
|
14
|
-
} = ChartDesign();
|
|
15
10
|
|
|
16
11
|
interface Dataset {
|
|
17
12
|
data: any,
|
|
@@ -27,8 +22,8 @@ export default function () {
|
|
|
27
22
|
});
|
|
28
23
|
|
|
29
24
|
|
|
30
|
-
function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>) {
|
|
31
|
-
return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex);
|
|
25
|
+
function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>) {
|
|
26
|
+
return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex, disableAccessibility, patternsColors, patternsList);
|
|
32
27
|
}
|
|
33
28
|
// Hack to force the chart to reload on Hover
|
|
34
29
|
function reloadChart () {
|
|
@@ -36,16 +31,18 @@ export default function () {
|
|
|
36
31
|
borderWidth.value = 3;
|
|
37
32
|
}
|
|
38
33
|
|
|
39
|
-
function getStackedDatasets (datasets: Dataset[], stackDatasets: boolean, patternShifting?: number) {
|
|
34
|
+
function getStackedDatasets (datasets: Dataset[], stackDatasets: boolean, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], patternShifting?: number) {
|
|
35
|
+
// Hack to force refresh
|
|
36
|
+
const borderWithValue = borderWidth.value;
|
|
40
37
|
return datasets.map((dataset, index) => {
|
|
41
38
|
return {
|
|
42
39
|
borderColor: function (context: any) {
|
|
43
|
-
return getBorderColor(index, context.index, patternShifting);
|
|
40
|
+
return disableAccessibility ? '#00000000' : getBorderColor(index, context.index, patternsColors, patternShifting);
|
|
44
41
|
},
|
|
45
42
|
backgroundColor: function (context: any) {
|
|
46
|
-
return getPattern(index, context.index, patternShifting);
|
|
43
|
+
return getPattern(index, context.index, disableAccessibility, patternsColors, patternsList, patternShifting);
|
|
47
44
|
},
|
|
48
|
-
borderWidth:
|
|
45
|
+
borderWidth: function () {return disableAccessibility ? 1 : borderWithValue},
|
|
49
46
|
data: dataset.data,
|
|
50
47
|
label: dataset.label,
|
|
51
48
|
stack: `Stack ${stackDatasets ? '0' : index}`
|
|
@@ -53,26 +50,25 @@ export default function () {
|
|
|
53
50
|
});
|
|
54
51
|
}
|
|
55
52
|
|
|
56
|
-
function getDatasets (firstDataSet: Dataset, secondDataSet: Dataset) {
|
|
57
|
-
|
|
58
|
-
return getStacked;
|
|
53
|
+
function getDatasets (firstDataSet: Dataset, secondDataSet: Dataset, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], disableAccessibility: boolean) {
|
|
54
|
+
return getStackedDatasets([firstDataSet, secondDataSet], false, disableAccessibility, patternsColors, patternsList);
|
|
59
55
|
}
|
|
60
56
|
|
|
61
|
-
function getBorderColor (dataSetIndex: number, contextIndex: number, patternShifting?: number) {
|
|
57
|
+
function getBorderColor (dataSetIndex: number, contextIndex: number, patternsColors: string[], patternShifting?: number) {
|
|
62
58
|
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
|
|
63
59
|
if (displayFullOpacity(dataSetIndex, contextIndex)) {
|
|
64
60
|
return patternsColors[index];
|
|
65
61
|
} else {
|
|
66
|
-
return
|
|
62
|
+
return addAlpha(patternsColors[index],0.2);
|
|
67
63
|
}
|
|
68
64
|
}
|
|
69
65
|
|
|
70
|
-
function getPattern (dataSetIndex: number, contextIndex: number, patternShifting?: number) {
|
|
66
|
+
function getPattern (dataSetIndex: number, contextIndex: number, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], patternShifting?: number) {
|
|
71
67
|
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
|
|
72
68
|
if (displayFullOpacity(dataSetIndex, contextIndex)) {
|
|
73
|
-
return
|
|
69
|
+
return patternsList[index](false, patternsColors[index], disableAccessibility);
|
|
74
70
|
} else {
|
|
75
|
-
return
|
|
71
|
+
return patternsList[index](true, patternsColors[index], disableAccessibility);
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
74
|
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import type { Ref } from 'vue';
|
|
2
2
|
import type { HTMLLegendPlugin } from "../types/Chart";
|
|
3
3
|
import type { ChartOptions } from 'chart.js';
|
|
4
|
-
import ChartDesign from './patterns/ChartDesign';
|
|
5
4
|
import PatternFunctions from './PatternFunctions';
|
|
6
5
|
import { formatValueAndRate } from './FormatUtilities';
|
|
7
6
|
import QuestionMarkSvg from '@mozaic-ds/icons/svg/Navigation_Notification_Question_24px.svg';
|
|
8
7
|
|
|
9
|
-
const {
|
|
10
|
-
patternsColors,
|
|
11
|
-
patternsStandardList
|
|
12
|
-
} = ChartDesign();
|
|
13
8
|
const { getPatternCanvas } = PatternFunctions();
|
|
14
9
|
|
|
15
10
|
export const LEGEND_FONT_SIZE = 14;
|
|
@@ -46,7 +41,7 @@ export interface ChartItem {
|
|
|
46
41
|
index: number
|
|
47
42
|
}
|
|
48
43
|
|
|
49
|
-
export function getHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, onHoverIndex: any, maxValueToDisplay?: number, chartData?: any): HTMLLegendPlugin[] {
|
|
44
|
+
export function getHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, onHoverIndex: any, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>, maxValueToDisplay?: number, chartData?: any): HTMLLegendPlugin[] {
|
|
50
45
|
return [{
|
|
51
46
|
id: 'htmlLegend',
|
|
52
47
|
afterUpdate (chart: any) {
|
|
@@ -71,13 +66,13 @@ export function getHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolea
|
|
|
71
66
|
} else {
|
|
72
67
|
li.style.marginRight = '12px'
|
|
73
68
|
}
|
|
74
|
-
li.style.width = 'max-content';
|
|
75
|
-
li.style.cursor = 'pointer';
|
|
69
|
+
li.style.width = 'max-content';
|
|
70
|
+
li.style.cursor = 'pointer';
|
|
76
71
|
let liContent: HTMLElement;
|
|
77
72
|
if (!selectMode.value) {
|
|
78
|
-
liContent = createLegendElementWithPatterns(item, chart, onHoverIndex);
|
|
73
|
+
liContent = createLegendElementWithPatterns(item, chart, onHoverIndex, disableAccessibility.value, patternsColors.value, patternsList.value);
|
|
79
74
|
} else {
|
|
80
|
-
liContent = createLegendElementWithCheckbox(chart, item, selectMode, onHoverIndex);
|
|
75
|
+
liContent = createLegendElementWithCheckbox(chart, item, selectMode, onHoverIndex, disableAccessibility.value);
|
|
81
76
|
}
|
|
82
77
|
li.appendChild(liContent);
|
|
83
78
|
li.appendChild(createHtmlLegendItemText(item));
|
|
@@ -155,13 +150,13 @@ doughnutData.data.slice(startIndex).forEach((_ignore: any, index: number) => {
|
|
|
155
150
|
}
|
|
156
151
|
|
|
157
152
|
export function createLegendElementWithPatterns
|
|
158
|
-
(item: ChartItem, chart: Chart, onHoverIndex: any | null)
|
|
153
|
+
(item: ChartItem, chart: Chart, onHoverIndex: any | null, disableAccessibility: boolean, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[])
|
|
159
154
|
: HTMLElement {
|
|
160
155
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
161
156
|
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
162
157
|
const img: HTMLImageElement = new Image();
|
|
163
158
|
const boxSpan: HTMLElement = createHtmlLegendLine(item, chart.config.type);
|
|
164
|
-
const pattern: CanvasPattern =
|
|
159
|
+
const pattern: CanvasPattern = patternsList[index](false, patternsColors[index], disableAccessibility);
|
|
165
160
|
const patternCanvas: HTMLCanvasElement = getPatternCanvas(pattern);
|
|
166
161
|
img.src = patternCanvas.toDataURL();
|
|
167
162
|
boxSpan.style.background = `url(${img.src})`;
|
|
@@ -176,16 +171,16 @@ export function createLegendElementWithPatterns
|
|
|
176
171
|
isDoughnut ? onHoverIndex.value = null : onHoverIndex.dataSetIndex = null;
|
|
177
172
|
};
|
|
178
173
|
return boxSpan;
|
|
179
|
-
}
|
|
174
|
+
}
|
|
180
175
|
|
|
181
|
-
export function createLegendElementWithCheckbox
|
|
182
|
-
(chart: Chart, item: ChartItem, selectMode: Ref<boolean>, onHoverIndex: any | null): HTMLElement {
|
|
176
|
+
export function createLegendElementWithCheckbox
|
|
177
|
+
(chart: Chart, item: ChartItem, selectMode: Ref<boolean>, onHoverIndex: any | null, disableAccessibility: boolean): HTMLElement {
|
|
183
178
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
184
179
|
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
185
|
-
const checkbox: HTMLElement = createLegendCheckbox(chart, item);
|
|
180
|
+
const checkbox: HTMLElement = createLegendCheckbox(chart, item, disableAccessibility);
|
|
186
181
|
const labels = chart.config.data.labels;
|
|
187
|
-
const allCheckBoxesVisible: boolean =
|
|
188
|
-
|
|
182
|
+
const allCheckBoxesVisible: boolean =
|
|
183
|
+
labels.every((label: string, index: number) => chart.getDataVisibility(index));
|
|
189
184
|
if (allCheckBoxesVisible) {
|
|
190
185
|
if (isDoughnut) {
|
|
191
186
|
onHoverIndex.value = -1;
|
|
@@ -264,11 +259,11 @@ export function createHtmlLegendListElement
|
|
|
264
259
|
return li;
|
|
265
260
|
}
|
|
266
261
|
|
|
267
|
-
export function addCheckboxStyle (isDataSetVisible: boolean, item: ChartItem, checkbox: Element) {
|
|
262
|
+
export function addCheckboxStyle (isDataSetVisible: boolean, item: ChartItem, checkbox: Element, disableAccessibility: boolean) {
|
|
268
263
|
let backgroundColor = '#fff';
|
|
269
264
|
let borderColor = '#666';
|
|
270
265
|
if (isDataSetVisible) {
|
|
271
|
-
backgroundColor = item.strokeStyle;
|
|
266
|
+
backgroundColor = disableAccessibility? item.fillStyle : item.strokeStyle;
|
|
272
267
|
borderColor = item.strokeStyle;
|
|
273
268
|
}
|
|
274
269
|
checkbox.setAttribute('checked', '' + isDataSetVisible);
|
|
@@ -280,14 +275,14 @@ export function addCheckboxStyle (isDataSetVisible: boolean, item: ChartItem, ch
|
|
|
280
275
|
border-color: ${borderColor};`);
|
|
281
276
|
}
|
|
282
277
|
|
|
283
|
-
export function createLegendCheckbox (chart: Chart, item: ChartItem) {
|
|
278
|
+
export function createLegendCheckbox (chart: Chart, item: ChartItem, disableAccessibility: boolean = false) {
|
|
284
279
|
const isDoughnut: boolean = chart.config.type === 'doughnut';
|
|
285
280
|
const index: number = isDoughnut ? item.index : item.datasetIndex;
|
|
286
281
|
const checkbox = document.createElement('input');
|
|
287
282
|
checkbox.setAttribute('type', 'checkbox');
|
|
288
283
|
checkbox.setAttribute('data-test-id', `legend-checkbox-${index}`);
|
|
289
284
|
const isDataSetVisible = isDoughnut ? chart.getDataVisibility(index) : chart.isDatasetVisible(index);
|
|
290
|
-
addCheckboxStyle(isDataSetVisible, item, checkbox);
|
|
285
|
+
addCheckboxStyle(isDataSetVisible, item, checkbox, disableAccessibility);
|
|
291
286
|
return checkbox;
|
|
292
287
|
}
|
|
293
288
|
|
|
@@ -338,14 +333,14 @@ export function switchItemVisibility (chart: Chart, elementIndex: number, select
|
|
|
338
333
|
}
|
|
339
334
|
|
|
340
335
|
|
|
341
|
-
export function createLegendElementWithSquareArea (item: ChartItem) {
|
|
336
|
+
export function createLegendElementWithSquareArea (item: ChartItem, mainSerieFirstDataset?: boolean) {
|
|
342
337
|
const liContent = createHtmlLegendLine(item, '');
|
|
343
338
|
const divPoint = createHtmlLegendDatasetSquare(item);
|
|
344
339
|
const index = item.index || item.datasetIndex;
|
|
345
340
|
if (index === 0) {
|
|
346
|
-
divPoint.style.borderRadius = '25px';
|
|
341
|
+
mainSerieFirstDataset ? divPoint.style.borderRadius = '25px' : divPoint.style.transform = 'rotate(45deg)';
|
|
347
342
|
} else {
|
|
348
|
-
divPoint.style.transform = 'rotate(45deg)';
|
|
343
|
+
mainSerieFirstDataset ? divPoint.style.transform = 'rotate(45deg)' : divPoint.style.borderRadius = '25px';
|
|
349
344
|
}
|
|
350
345
|
liContent.appendChild(divPoint);
|
|
351
346
|
return liContent;
|
|
@@ -1,37 +1,43 @@
|
|
|
1
1
|
import { ref } from 'vue';
|
|
2
2
|
import type { Ref } from 'vue';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
4
|
getHtmlLegendPlugin
|
|
5
5
|
} from '../services/ChartsCommonLegend';
|
|
6
6
|
import { formatWithThousandsSeprators } from '../services/FormatUtilities';
|
|
7
7
|
|
|
8
8
|
import ChartDesign from './patterns/ChartDesign';
|
|
9
|
-
|
|
10
|
-
const {
|
|
11
|
-
patternsStandardList
|
|
12
|
-
} = ChartDesign();
|
|
13
|
-
|
|
9
|
+
import {addAlpha} from './ColorFunctions';
|
|
14
10
|
|
|
15
11
|
export default function () {
|
|
16
12
|
const doughnutRef: Ref = ref(null);
|
|
17
13
|
const onHoverIndex: Ref<number | null> = ref(null);
|
|
18
14
|
const backgroundColor: Ref<CanvasPattern[] | null> = ref(null);
|
|
19
15
|
|
|
20
|
-
function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, maxValueToDisplay: number, doughnutData: any) {
|
|
21
|
-
return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex, maxValueToDisplay, doughnutData);
|
|
16
|
+
function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>, maxValueToDisplay: number, doughnutData: any) {
|
|
17
|
+
return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex, disableAccessibility, patternsColors, patternsList, maxValueToDisplay, doughnutData);
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
20
|
+
|
|
21
|
+
function getBackgroundColor(patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], disableAccessibility: boolean) {
|
|
22
|
+
if (onHoverIndex.value !== null) {
|
|
23
|
+
return patternsList
|
|
24
|
+
.map((pattern, index) => onHoverIndex.value === index ? pattern(false, patternsColors[index], disableAccessibility) : pattern(true, patternsColors[index], disableAccessibility));
|
|
25
|
+
} else {
|
|
26
|
+
return patternsList
|
|
27
|
+
.map((pattern, index) => pattern(false, patternsColors[index], disableAccessibility),);
|
|
28
|
+
}
|
|
31
29
|
}
|
|
32
|
-
}
|
|
33
30
|
|
|
34
|
-
|
|
31
|
+
function getBorderColor(patternsColors: string[]): string[] {
|
|
32
|
+
if (onHoverIndex.value !== null) {
|
|
33
|
+
return patternsColors.map((color, index) => onHoverIndex.value === index ? color : addAlpha(color, 0.2));
|
|
34
|
+
} else {
|
|
35
|
+
return patternsColors;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
function getOnHoverOptions () {
|
|
35
41
|
return (_ignore: unknown, activeElements: Array<any>): void => {
|
|
36
42
|
if (activeElements[0] !== undefined) {
|
|
37
43
|
onHoverIndex.value = activeElements[0].element.$context.index;
|
|
@@ -83,6 +89,7 @@ function groupDataAfterNthValue (data: any, maxValues: number): any[] {
|
|
|
83
89
|
getDoughnutLabels,
|
|
84
90
|
getBackgroundColor,
|
|
85
91
|
getFormatedText,
|
|
92
|
+
getBorderColor,
|
|
86
93
|
backgroundColor,
|
|
87
94
|
doughnutRef
|
|
88
95
|
};
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import type { TooltipChartType } from '../types/TooltipChartType';
|
|
2
2
|
import { getPatternIndexWithShift } from './FormatUtilities';
|
|
3
3
|
import PatternsFunctions from '../services/PatternFunctions';
|
|
4
|
-
import ChartDesign from './patterns/ChartDesign';
|
|
5
4
|
|
|
6
5
|
const { getPatternCanvas } = PatternsFunctions();
|
|
7
|
-
const {
|
|
8
|
-
patternsStandardList
|
|
9
|
-
} = ChartDesign();
|
|
10
6
|
|
|
11
7
|
type BodyItem = {
|
|
12
8
|
after: string[];
|
|
@@ -74,7 +70,11 @@ export class GenericTooltipService {
|
|
|
74
70
|
createTooltip (
|
|
75
71
|
context: Context,
|
|
76
72
|
retrieveData : (context: Context) => string,
|
|
77
|
-
tooltipInputElements: TooltipElements
|
|
73
|
+
tooltipInputElements: TooltipElements,
|
|
74
|
+
patternsColors: string[],
|
|
75
|
+
patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[],
|
|
76
|
+
disableAccessibility: boolean = false,
|
|
77
|
+
) {
|
|
78
78
|
if (!context.tooltip.dataPoints) {
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
@@ -126,14 +126,17 @@ export class GenericTooltipService {
|
|
|
126
126
|
legendInnerStyle,
|
|
127
127
|
body,
|
|
128
128
|
style,
|
|
129
|
-
tooltipEl
|
|
129
|
+
tooltipEl,
|
|
130
|
+
patternsColors,
|
|
131
|
+
patternsList,
|
|
132
|
+
disableAccessibility
|
|
130
133
|
);
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
this.handleTooltipPosition(context, tooltipModel, tooltipEl);
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
private handleTooltipPosition
|
|
139
|
+
private handleTooltipPosition
|
|
137
140
|
(context: Context, tooltipModel: { caretX: number, caretY: number }, tooltipEl: HTMLElement) {
|
|
138
141
|
const position = context.chart.canvas.getBoundingClientRect();
|
|
139
142
|
const screenWidth = window.innerWidth;
|
|
@@ -203,26 +206,30 @@ export class GenericTooltipService {
|
|
|
203
206
|
return legendIconInnerStyle;
|
|
204
207
|
}
|
|
205
208
|
|
|
206
|
-
addLegendToDom
|
|
207
|
-
|
|
209
|
+
addLegendToDom (
|
|
210
|
+
innerHTMLtext: string,
|
|
208
211
|
legendIconStyle: string,
|
|
209
212
|
legendIconInnerStyle: string,
|
|
210
213
|
body: Array<string>,
|
|
211
214
|
style: string,
|
|
212
|
-
tooltipEl: HTMLElement
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
tooltipEl: HTMLElement,
|
|
216
|
+
patternsColors: string[],
|
|
217
|
+
patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[],
|
|
218
|
+
disableAccessibility: boolean = false
|
|
219
|
+
) {
|
|
220
|
+
let innerHtml = innerHTMLtext;
|
|
221
|
+
let legendImage = `<div class="legendIcon" style="${legendIconStyle}">`;
|
|
222
|
+
const legendSubImage = `<div style="${legendIconInnerStyle}"></div>`;
|
|
223
|
+
legendImage += `${legendSubImage}</div>`;
|
|
224
|
+
|
|
225
|
+
const innerHtmlToAdd = this.setInnerHtmlToAdd(body, style, legendImage);
|
|
226
|
+
innerHtml += innerHtmlToAdd;
|
|
227
|
+
const tableRoot = tooltipEl?.querySelector('.tooltipCtn') as HTMLElement | null;
|
|
228
|
+
|
|
229
|
+
if (tableRoot?.innerHTML != null) {
|
|
230
|
+
this.setInnerHtmlAndPattern(tableRoot, innerHtml, patternsColors, patternsList, disableAccessibility);
|
|
231
|
+
}
|
|
224
232
|
}
|
|
225
|
-
}
|
|
226
233
|
|
|
227
234
|
setInnerHtmlToAdd (body: Array<string>, style: string, legendImage: string) {
|
|
228
235
|
const legendText = body[0].split(':')[0];
|
|
@@ -245,7 +252,7 @@ export class GenericTooltipService {
|
|
|
245
252
|
doughnutHtml += `<div style="${fontProperties}; margin-left:3rem;">${this.dataToDisplay}</div>`;
|
|
246
253
|
doughnutHtml += '</div></div>';
|
|
247
254
|
return doughnutHtml;
|
|
248
|
-
}
|
|
255
|
+
}
|
|
249
256
|
|
|
250
257
|
returnRadarHtml (style: string, legendImage: string, spanText: string) {
|
|
251
258
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
@@ -256,10 +263,10 @@ export class GenericTooltipService {
|
|
|
256
263
|
radarHtml += `<div style="margin-left: 20px;">${this.dataToDisplay}</div>`;
|
|
257
264
|
radarHtml += '</div>';
|
|
258
265
|
radarHtml += '</div><div>';
|
|
259
|
-
|
|
266
|
+
|
|
260
267
|
return radarHtml;
|
|
261
268
|
}
|
|
262
|
-
|
|
269
|
+
|
|
263
270
|
returnDetailsBarchartHtml (style: string, legendImage: string, spanText: string) {
|
|
264
271
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
265
272
|
let barChartHtml = `<div style="${fontProperties}; display: flex; align-items: center;">${legendImage + spanText}</div>`;
|
|
@@ -268,23 +275,23 @@ export class GenericTooltipService {
|
|
|
268
275
|
barChartHtml += `<div>${this.xValue}</div>`;
|
|
269
276
|
barChartHtml += `<div style="margin-left: 20px;">${this.titleLines[0]}</div>`;
|
|
270
277
|
barChartHtml += '</div>';
|
|
271
|
-
|
|
278
|
+
|
|
272
279
|
barChartHtml += `<div style="${fontProperties}; ${style}; border-: none; display:flex; justify-content: space-between;">`;
|
|
273
280
|
barChartHtml += `<div>${(this.yValue)}</div>`;
|
|
274
281
|
barChartHtml += `<div style="margin-left: 20px;">${this.dataToDisplay}</div>`;
|
|
275
282
|
barChartHtml += '</div>';
|
|
276
|
-
|
|
283
|
+
|
|
277
284
|
return barChartHtml;
|
|
278
285
|
}
|
|
279
|
-
|
|
280
286
|
|
|
281
|
-
|
|
287
|
+
|
|
288
|
+
setInnerHtmlAndPattern(tableRoot: HTMLElement, innerHtml: string, patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], disableAccessibility: boolean = false) {
|
|
282
289
|
tableRoot.innerHTML = innerHtml;
|
|
283
290
|
const legendIconHtml = document.querySelector('.legendIcon') as HTMLElement;
|
|
284
291
|
const img: HTMLImageElement = new Image();
|
|
285
|
-
|
|
292
|
+
|
|
286
293
|
let index: number;
|
|
287
|
-
|
|
294
|
+
|
|
288
295
|
if (this.chartType === 'DOUGHNUT') {
|
|
289
296
|
index = this.dataIndex + 1;
|
|
290
297
|
} else {
|
|
@@ -292,7 +299,7 @@ export class GenericTooltipService {
|
|
|
292
299
|
}
|
|
293
300
|
const patternIndex = getPatternIndexWithShift(index, this.patternShifting);
|
|
294
301
|
if (this.chartType !== 'LINE_CHART' && this.chartType !== 'RADAR') {
|
|
295
|
-
const pattern: CanvasPattern =
|
|
302
|
+
const pattern: CanvasPattern = patternsList[patternIndex - 1](false, patternsColors[patternIndex - 1], disableAccessibility);
|
|
296
303
|
const patternCanvas: HTMLCanvasElement = getPatternCanvas(pattern, 22, 22);
|
|
297
304
|
img.src = patternCanvas.toDataURL();
|
|
298
305
|
legendIconHtml.style.backgroundImage = `url(${img.src})`;
|
|
@@ -13,15 +13,21 @@ export default function() {
|
|
|
13
13
|
PatternVerticalLines,
|
|
14
14
|
PatternDashedDiagonals,
|
|
15
15
|
PatternCircles
|
|
16
|
-
] as ((hover: boolean) => CanvasPattern)[];
|
|
16
|
+
] as ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[];
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
const colourSets: [string[], string[], string[], string[], string[], string[], string[]] = [
|
|
19
|
+
['#393879', '#006974', '#405D68', '#005C91', '#8C3500', '#8C0003'],
|
|
20
|
+
['#A274FF', '#143666', '#00A3B2', '#8C1551', '#F255A3', '#095359'],
|
|
21
|
+
['#00A3B2', '#143666', '#3D993D', '#8C1551', '#E56D17', '#4C3380'],
|
|
22
|
+
['#8C1551', '#E56D17', '#4C3380', '#4588E5', '#095359', '#F255A3'],
|
|
23
|
+
['#4588E5', '#4C3380', '#E56D17', '#143666', '#D94141', '#8C1551'],
|
|
24
|
+
['#143666', '#F255A3', '#095359', '#4588E5', '#8C1551', '#E56D17'],
|
|
25
|
+
['#A274FF', '#B0BBC0', '#B0BBC0', '#B0BBC0', '#B0BBC0', '#B0BBC0']
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
patternsStandardList,
|
|
30
|
+
colourSets
|
|
31
|
+
};
|
|
26
32
|
|
|
27
33
|
}
|