@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
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import { ref } from
|
|
2
|
-
import type { Ref } from
|
|
3
|
-
import { getHtmlLegendPlugin } from
|
|
4
|
-
import { formatWithThousandsSeprators } from
|
|
1
|
+
import { ref } from 'vue';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
import { getHtmlLegendPlugin } from '@/services/ChartsCommonLegend';
|
|
4
|
+
import { formatWithThousandsSeprators } from '@/services/FormatUtilities';
|
|
5
5
|
|
|
6
|
-
import { addAlpha } from
|
|
6
|
+
import { addAlpha } from './ColorFunctions';
|
|
7
|
+
import { DoughnutData, DoughnutPlugin } from '@/types/DoughnutData';
|
|
7
8
|
|
|
8
9
|
export default function () {
|
|
9
10
|
const doughnutRef: Ref = ref(null);
|
|
10
11
|
const onHoverIndex: Ref<number | null> = ref(null);
|
|
11
12
|
const backgroundColor: Ref<CanvasPattern[] | null> = ref(null);
|
|
13
|
+
const centeredLabel: Ref = ref(null);
|
|
12
14
|
|
|
13
15
|
function privateGetHtmlLegendPlugin(
|
|
14
16
|
legendContainer: Ref,
|
|
@@ -62,7 +64,10 @@ export default function () {
|
|
|
62
64
|
}
|
|
63
65
|
}
|
|
64
66
|
|
|
65
|
-
function getBorderColor(
|
|
67
|
+
function getBorderColor(
|
|
68
|
+
patternsColors: string[],
|
|
69
|
+
enableHoverFeature: boolean
|
|
70
|
+
): string[] {
|
|
66
71
|
if (onHoverIndex.value !== null && enableHoverFeature) {
|
|
67
72
|
return patternsColors.map((color, index) =>
|
|
68
73
|
onHoverIndex.value === index ? color : addAlpha(color, 0.2)
|
|
@@ -86,9 +91,34 @@ export default function () {
|
|
|
86
91
|
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
87
92
|
};
|
|
88
93
|
|
|
94
|
+
function getCenteredLabelPlugin(
|
|
95
|
+
doughnutData: DoughnutData[]
|
|
96
|
+
): DoughnutPlugin {
|
|
97
|
+
return {
|
|
98
|
+
id: 'centeredLabelPlugin',
|
|
99
|
+
afterDatasetDraw: (chart) => {
|
|
100
|
+
const selectedIndexes: Number[] = [];
|
|
101
|
+
const arcElements = chart.getDatasetMeta(0).data;
|
|
102
|
+
|
|
103
|
+
arcElements.forEach((arcElement: any, index: Number) => {
|
|
104
|
+
if (arcElement.startAngle !== arcElement.endAngle) {
|
|
105
|
+
selectedIndexes.push(index);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const total = (chart as any)._metasets[0]?._dataset?.raw_value
|
|
110
|
+
?.filter((_: any, index: Number) => selectedIndexes.includes(index))
|
|
111
|
+
.reduce((acc: number, currentValue: any) => acc + currentValue, 0);
|
|
112
|
+
|
|
113
|
+
const unit = doughnutData[0].unit ?? '';
|
|
114
|
+
centeredLabel.value = `${formatWithThousandsSeprators(total)}${unit}`;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
89
119
|
function getDoughnutLabels(
|
|
90
120
|
labels: string[],
|
|
91
|
-
data:
|
|
121
|
+
data: DoughnutData[],
|
|
92
122
|
maxValues: number,
|
|
93
123
|
othersLabel: string
|
|
94
124
|
) {
|
|
@@ -107,7 +137,7 @@ export default function () {
|
|
|
107
137
|
);
|
|
108
138
|
}
|
|
109
139
|
|
|
110
|
-
function groupDataAfterNthValue(data:
|
|
140
|
+
function groupDataAfterNthValue(data: DoughnutData[], maxValues: number) {
|
|
111
141
|
if (maxValues < 1) {
|
|
112
142
|
return data;
|
|
113
143
|
}
|
|
@@ -115,15 +145,12 @@ export default function () {
|
|
|
115
145
|
if (data.length > maxValues) {
|
|
116
146
|
truncatedData = truncatedData.slice(0, maxValues);
|
|
117
147
|
truncatedData[maxValues - 1] = data.slice(maxValues).reduce(
|
|
118
|
-
(result
|
|
148
|
+
(result, current) => {
|
|
119
149
|
result.rate += current.rate;
|
|
120
150
|
result.value += current.value;
|
|
121
151
|
return result;
|
|
122
152
|
},
|
|
123
|
-
{
|
|
124
|
-
rate: data[maxValues - 1].rate,
|
|
125
|
-
value: data[maxValues - 1].value,
|
|
126
|
-
}
|
|
153
|
+
{ ...data[maxValues - 1] }
|
|
127
154
|
);
|
|
128
155
|
}
|
|
129
156
|
return truncatedData;
|
|
@@ -140,5 +167,7 @@ export default function () {
|
|
|
140
167
|
getBorderColor,
|
|
141
168
|
backgroundColor,
|
|
142
169
|
doughnutRef,
|
|
170
|
+
getCenteredLabelPlugin,
|
|
171
|
+
centeredLabel
|
|
143
172
|
};
|
|
144
173
|
}
|
|
@@ -1,30 +1,44 @@
|
|
|
1
|
-
export function formatTicks
|
|
1
|
+
export function formatTicks(val: number, unit?: string): string {
|
|
2
2
|
const fixedValue = parseInt(val.toFixed());
|
|
3
3
|
return `${new Intl.NumberFormat().format(fixedValue)}${unit ? ' ' + unit : ''}`;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
export function formatWithThousandsSeprators
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
export function formatWithThousandsSeprators(value: number) {
|
|
7
|
+
if (Math.abs(Number(value)) >= 1.0e6) {
|
|
8
|
+
return formatDecimalNumber(value / 1.0e6) + ' M';
|
|
9
|
+
} else if (Math.abs(Number(value)) >= 1.0e3) {
|
|
10
|
+
return formatDecimalNumber(value / 1.0e3) + ' K';
|
|
11
|
+
} else {
|
|
12
|
+
return formatDecimalNumber(value);
|
|
13
|
+
}
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
|
|
16
|
+
function formatDecimalNumber(value: number) {
|
|
17
|
+
return new Intl.NumberFormat(
|
|
18
|
+
new Intl.NumberFormat().resolvedOptions().locale,
|
|
19
|
+
{
|
|
20
|
+
style: 'decimal',
|
|
21
|
+
minimumFractionDigits: 2,
|
|
22
|
+
maximumFractionDigits: 2
|
|
23
|
+
}
|
|
24
|
+
).format(value);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Not used in the codebase
|
|
28
|
+
export function numberWithThousandSeparators(value: string, unit?: string) {
|
|
15
29
|
const x = parseFloat(value).toFixed(2);
|
|
16
30
|
const formattedValue = x.replace(/\B(?=(\d{3}){1,5}(?!\d))/g, ' ');
|
|
17
31
|
return unit ? formattedValue + ' ' + unit : formattedValue;
|
|
18
32
|
}
|
|
19
33
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
34
|
+
export function getPatternIndexWithShift(
|
|
35
|
+
dataSetIndex: number,
|
|
36
|
+
patternShifting?: number
|
|
37
|
+
) {
|
|
38
|
+
return patternShifting ? (dataSetIndex + patternShifting) % 6 : dataSetIndex;
|
|
25
39
|
}
|
|
26
40
|
|
|
27
|
-
export function formatValueAndRate
|
|
41
|
+
export function formatValueAndRate(doughnutData: any, dataIndex: number) {
|
|
28
42
|
const textValue = `${formatWithThousandsSeprators(doughnutData.data[dataIndex].value)} (${formatWithThousandsSeprators(doughnutData.data[dataIndex].rate)}%)`;
|
|
29
43
|
return textValue;
|
|
30
44
|
}
|
|
@@ -11,42 +11,42 @@ type BodyItem = {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
export type TooltipElements = {
|
|
14
|
-
chartType: TooltipChartType
|
|
15
|
-
firstLineLabel?: string
|
|
16
|
-
secondLineLabel?: string
|
|
17
|
-
patternShifting?: number
|
|
18
|
-
}
|
|
14
|
+
chartType: TooltipChartType;
|
|
15
|
+
firstLineLabel?: string;
|
|
16
|
+
secondLineLabel?: string;
|
|
17
|
+
patternShifting?: number;
|
|
18
|
+
};
|
|
19
19
|
|
|
20
20
|
type LabelColors = {
|
|
21
21
|
backgroundColor: unknown;
|
|
22
22
|
borderColor: unknown;
|
|
23
|
-
}
|
|
23
|
+
};
|
|
24
24
|
|
|
25
25
|
type PointStyle = {
|
|
26
26
|
pointStyle: unknown;
|
|
27
27
|
rotation: number;
|
|
28
|
-
}
|
|
28
|
+
};
|
|
29
29
|
|
|
30
30
|
// ../..ts-ignore
|
|
31
31
|
export type Context = {
|
|
32
32
|
chart: {
|
|
33
33
|
canvas: HTMLElement;
|
|
34
|
-
tooltip?:{
|
|
35
|
-
x: number
|
|
36
|
-
y: number
|
|
37
|
-
}
|
|
34
|
+
tooltip?: {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
};
|
|
38
38
|
};
|
|
39
39
|
replay?: unknown;
|
|
40
40
|
tooltip: {
|
|
41
41
|
dataPoints: {
|
|
42
42
|
dataset?: {
|
|
43
|
-
type?: string
|
|
44
|
-
}
|
|
45
|
-
dataIndex?: number
|
|
46
|
-
datasetIndex?: number
|
|
47
|
-
raw: any
|
|
43
|
+
type?: string;
|
|
44
|
+
};
|
|
45
|
+
dataIndex?: number;
|
|
46
|
+
datasetIndex?: number;
|
|
47
|
+
raw: any;
|
|
48
48
|
}[];
|
|
49
|
-
opacity
|
|
49
|
+
opacity: number;
|
|
50
50
|
body: {
|
|
51
51
|
after: string[];
|
|
52
52
|
before: string[];
|
|
@@ -58,10 +58,9 @@ export type Context = {
|
|
|
58
58
|
caretX: number;
|
|
59
59
|
caretY: number;
|
|
60
60
|
};
|
|
61
|
-
}
|
|
61
|
+
};
|
|
62
62
|
|
|
63
63
|
export class GenericTooltipService {
|
|
64
|
-
|
|
65
64
|
chartType = '';
|
|
66
65
|
datasetIndex = 0;
|
|
67
66
|
dataIndex = 0;
|
|
@@ -71,14 +70,18 @@ export class GenericTooltipService {
|
|
|
71
70
|
yValue = '';
|
|
72
71
|
patternShifting = 0;
|
|
73
72
|
|
|
74
|
-
createTooltip
|
|
73
|
+
createTooltip(
|
|
75
74
|
context: Context,
|
|
76
|
-
retrieveData
|
|
75
|
+
retrieveData: (context: Context) => string,
|
|
77
76
|
tooltipInputElements: TooltipElements,
|
|
78
77
|
patternsColors: string[],
|
|
79
|
-
patternsList: ((
|
|
80
|
-
|
|
81
|
-
|
|
78
|
+
patternsList: ((
|
|
79
|
+
hover: boolean,
|
|
80
|
+
color: string,
|
|
81
|
+
disableAccessibility: boolean
|
|
82
|
+
) => CanvasPattern)[],
|
|
83
|
+
disableAccessibility: boolean = false
|
|
84
|
+
) {
|
|
82
85
|
if (!context.tooltip.dataPoints) {
|
|
83
86
|
return;
|
|
84
87
|
}
|
|
@@ -89,7 +92,9 @@ export class GenericTooltipService {
|
|
|
89
92
|
this.chartType = tooltipInputElements.chartType;
|
|
90
93
|
this.dataToDisplay = retrieveData(context);
|
|
91
94
|
this.patternShifting = tooltipInputElements.patternShifting || 0;
|
|
92
|
-
let tooltipEl = document.querySelector(
|
|
95
|
+
let tooltipEl = document.querySelector(
|
|
96
|
+
'#chartjs-tooltip'
|
|
97
|
+
) as HTMLElement | null;
|
|
93
98
|
|
|
94
99
|
if (!tooltipEl) {
|
|
95
100
|
tooltipEl = this.createNewTooltipElement();
|
|
@@ -111,7 +116,10 @@ export class GenericTooltipService {
|
|
|
111
116
|
style += 'padding: 10px 20px';
|
|
112
117
|
|
|
113
118
|
const innerHtml = `<div style="${style}" class="tooltipTitle">`;
|
|
114
|
-
const body =
|
|
119
|
+
const body =
|
|
120
|
+
this.chartType === 'DOUGHNUT'
|
|
121
|
+
? [tooltipModel.title[0].split('(')[0].trim()]
|
|
122
|
+
: bodyLines[0];
|
|
115
123
|
let legendIconStyle = '';
|
|
116
124
|
let legendInnerStyle = '';
|
|
117
125
|
const datasetType = context.tooltip?.dataPoints[0]?.dataset?.type;
|
|
@@ -119,9 +127,11 @@ export class GenericTooltipService {
|
|
|
119
127
|
if (this.chartType === 'RADAR' || this.chartType === 'LINE_CHART') {
|
|
120
128
|
legendIconStyle = this.createLegendStyle(context);
|
|
121
129
|
legendInnerStyle = this.createLegendInnerStyle(context);
|
|
122
|
-
} else if (
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
} else if (
|
|
131
|
+
this.chartType === 'BAR_CHART' ||
|
|
132
|
+
this.chartType === 'DETAILS_BAR_CHART' ||
|
|
133
|
+
this.chartType === 'DOUGHNUT'
|
|
134
|
+
) {
|
|
125
135
|
legendIconStyle = this.createPatternLegendStyle(context);
|
|
126
136
|
} else if (this.chartType === 'MIXED_BAR_LINE_CHART') {
|
|
127
137
|
if (datasetType === 'bar') {
|
|
@@ -149,12 +159,15 @@ export class GenericTooltipService {
|
|
|
149
159
|
this.handleTooltipPosition(context, tooltipModel, tooltipEl);
|
|
150
160
|
}
|
|
151
161
|
|
|
152
|
-
protected handleTooltipPosition
|
|
153
|
-
|
|
162
|
+
protected handleTooltipPosition(
|
|
163
|
+
context: Context,
|
|
164
|
+
tooltipModel: { caretX: number; caretY: number },
|
|
165
|
+
tooltipEl: HTMLElement
|
|
166
|
+
) {
|
|
154
167
|
const position = context.chart.canvas.getBoundingClientRect();
|
|
155
168
|
const screenWidth = window.innerWidth;
|
|
156
|
-
const left = position.left + window.
|
|
157
|
-
const top = position.top + window.
|
|
169
|
+
const left = position.left + window.scrollX + tooltipModel.caretX;
|
|
170
|
+
const top = position.top + window.scrollY + tooltipModel.caretY;
|
|
158
171
|
|
|
159
172
|
tooltipEl.style.left = left + 'px';
|
|
160
173
|
tooltipEl.style.top = top + 'px';
|
|
@@ -167,11 +180,12 @@ export class GenericTooltipService {
|
|
|
167
180
|
tooltipEl.style.pointerEvents = 'none';
|
|
168
181
|
|
|
169
182
|
if (tooltipEl.getBoundingClientRect().width + left > screenWidth) {
|
|
170
|
-
tooltipEl.style.left =
|
|
183
|
+
tooltipEl.style.left =
|
|
184
|
+
left - tooltipEl.getBoundingClientRect().width + 'px';
|
|
171
185
|
}
|
|
172
186
|
}
|
|
173
187
|
|
|
174
|
-
protected createNewTooltipElement
|
|
188
|
+
protected createNewTooltipElement() {
|
|
175
189
|
const tooltipEl = document.createElement('div');
|
|
176
190
|
tooltipEl.id = 'chartjs-tooltip';
|
|
177
191
|
tooltipEl.style.backgroundColor = 'white';
|
|
@@ -183,17 +197,17 @@ export class GenericTooltipService {
|
|
|
183
197
|
return tooltipEl;
|
|
184
198
|
}
|
|
185
199
|
|
|
186
|
-
createPatternLegendStyle
|
|
200
|
+
createPatternLegendStyle(context: Context) {
|
|
187
201
|
return this.createCommonLegendSquareStyle(context);
|
|
188
202
|
}
|
|
189
203
|
|
|
190
|
-
createLegendStyle
|
|
204
|
+
createLegendStyle(context: Context) {
|
|
191
205
|
let legendIconStyle = `background-color:${context.tooltip.labelColors[0].backgroundColor}`;
|
|
192
206
|
legendIconStyle += this.createCommonLegendSquareStyle(context);
|
|
193
207
|
return legendIconStyle;
|
|
194
208
|
}
|
|
195
209
|
|
|
196
|
-
private createCommonLegendSquareStyle
|
|
210
|
+
private createCommonLegendSquareStyle(context: Context) {
|
|
197
211
|
let style = `;border: 2px solid ${context.tooltip.labelColors[0].borderColor}`;
|
|
198
212
|
style += ';min-height: 20px';
|
|
199
213
|
style += ';min-width: 20px';
|
|
@@ -206,7 +220,7 @@ export class GenericTooltipService {
|
|
|
206
220
|
return style;
|
|
207
221
|
}
|
|
208
222
|
|
|
209
|
-
createLegendInnerStyle
|
|
223
|
+
createLegendInnerStyle(context: Context) {
|
|
210
224
|
let legendIconInnerStyle = 'height: 12px';
|
|
211
225
|
legendIconInnerStyle += ';width: 12px';
|
|
212
226
|
legendIconInnerStyle += ';background-color: #FFF';
|
|
@@ -220,7 +234,7 @@ export class GenericTooltipService {
|
|
|
220
234
|
return legendIconInnerStyle;
|
|
221
235
|
}
|
|
222
236
|
|
|
223
|
-
addLegendToDom
|
|
237
|
+
addLegendToDom(
|
|
224
238
|
innerHTMLtext: string,
|
|
225
239
|
legendIconStyle: string,
|
|
226
240
|
legendIconInnerStyle: string,
|
|
@@ -228,25 +242,45 @@ export class GenericTooltipService {
|
|
|
228
242
|
style: string,
|
|
229
243
|
tooltipEl: HTMLElement,
|
|
230
244
|
patternsColors: string[],
|
|
231
|
-
patternsList: ((
|
|
245
|
+
patternsList: ((
|
|
246
|
+
hover: boolean,
|
|
247
|
+
color: string,
|
|
248
|
+
disableAccessibility: boolean
|
|
249
|
+
) => CanvasPattern)[],
|
|
232
250
|
disableAccessibility: boolean = false,
|
|
233
251
|
datasetType?: string
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
252
|
+
) {
|
|
253
|
+
let innerHtml = innerHTMLtext;
|
|
254
|
+
let legendImage = `<div class="legendIcon" style="${legendIconStyle}">`;
|
|
255
|
+
const legendSubImage = `<div style="${legendIconInnerStyle}"></div>`;
|
|
256
|
+
legendImage += `${legendSubImage}</div>`;
|
|
257
|
+
|
|
258
|
+
const innerHtmlToAdd = this.setInnerHtmlToAdd(body, style, legendImage);
|
|
259
|
+
innerHtml += innerHtmlToAdd;
|
|
260
|
+
const tableRoot = tooltipEl?.querySelector(
|
|
261
|
+
'.tooltipCtn'
|
|
262
|
+
) as HTMLElement | null;
|
|
263
|
+
if (tableRoot?.innerHTML != null) {
|
|
264
|
+
datasetType
|
|
265
|
+
? this.setInnerHtmlAndPattern(
|
|
266
|
+
tableRoot,
|
|
267
|
+
innerHtml,
|
|
268
|
+
patternsColors,
|
|
269
|
+
patternsList,
|
|
270
|
+
disableAccessibility,
|
|
271
|
+
datasetType
|
|
272
|
+
)
|
|
273
|
+
: this.setInnerHtmlAndPattern(
|
|
274
|
+
tableRoot,
|
|
275
|
+
innerHtml,
|
|
276
|
+
patternsColors,
|
|
277
|
+
patternsList,
|
|
278
|
+
disableAccessibility
|
|
279
|
+
);
|
|
247
280
|
}
|
|
281
|
+
}
|
|
248
282
|
|
|
249
|
-
setInnerHtmlToAdd
|
|
283
|
+
setInnerHtmlToAdd(body: Array<string>, style: string, legendImage: string) {
|
|
250
284
|
const legendText = body[0].split(':')[0];
|
|
251
285
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
252
286
|
const spanText = `<span style="${fontProperties}">${legendText}</span>`;
|
|
@@ -259,7 +293,7 @@ export class GenericTooltipService {
|
|
|
259
293
|
}
|
|
260
294
|
}
|
|
261
295
|
|
|
262
|
-
returnDoughnutHtml
|
|
296
|
+
returnDoughnutHtml(legendImage: string, spanText: string) {
|
|
263
297
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
264
298
|
const legendText = `<span style="${fontProperties}">${spanText.split('(')[0]}</span>`;
|
|
265
299
|
let doughnutHtml = `<div style="${fontProperties}; display: flex; align-items: center; justify-content: space-between">`;
|
|
@@ -269,7 +303,7 @@ export class GenericTooltipService {
|
|
|
269
303
|
return doughnutHtml;
|
|
270
304
|
}
|
|
271
305
|
|
|
272
|
-
returnRadarHtml
|
|
306
|
+
returnRadarHtml(style: string, legendImage: string, spanText: string) {
|
|
273
307
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
274
308
|
let radarHtml = `<div style="${fontProperties}; display: flex; align-items: center;">${legendImage + spanText}</div>`;
|
|
275
309
|
radarHtml += '</div>';
|
|
@@ -282,7 +316,11 @@ export class GenericTooltipService {
|
|
|
282
316
|
return radarHtml;
|
|
283
317
|
}
|
|
284
318
|
|
|
285
|
-
returnDetailsBarchartHtml
|
|
319
|
+
returnDetailsBarchartHtml(
|
|
320
|
+
style: string,
|
|
321
|
+
legendImage: string,
|
|
322
|
+
spanText: string
|
|
323
|
+
) {
|
|
286
324
|
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
287
325
|
let barChartHtml = `<div style="${fontProperties}; display: flex; align-items: center;">${legendImage + spanText}</div>`;
|
|
288
326
|
barChartHtml += '</div>';
|
|
@@ -292,15 +330,25 @@ export class GenericTooltipService {
|
|
|
292
330
|
barChartHtml += '</div>';
|
|
293
331
|
|
|
294
332
|
barChartHtml += `<div style="${fontProperties}; ${style}; border-: none; display:flex; justify-content: space-between;">`;
|
|
295
|
-
barChartHtml += `<div>${
|
|
333
|
+
barChartHtml += `<div>${this.yValue}</div>`;
|
|
296
334
|
barChartHtml += `<div style="margin-left: 20px;">${this.dataToDisplay}</div>`;
|
|
297
335
|
barChartHtml += '</div>';
|
|
298
336
|
|
|
299
337
|
return barChartHtml;
|
|
300
338
|
}
|
|
301
339
|
|
|
302
|
-
|
|
303
|
-
|
|
340
|
+
setInnerHtmlAndPattern(
|
|
341
|
+
tableRoot: HTMLElement,
|
|
342
|
+
innerHtml: string,
|
|
343
|
+
patternsColors: string[],
|
|
344
|
+
patternsList: ((
|
|
345
|
+
hover: boolean,
|
|
346
|
+
color: string,
|
|
347
|
+
disableAccessibility: boolean
|
|
348
|
+
) => CanvasPattern)[],
|
|
349
|
+
disableAccessibility: boolean = false,
|
|
350
|
+
datasetType?: string
|
|
351
|
+
) {
|
|
304
352
|
tableRoot.innerHTML = innerHtml;
|
|
305
353
|
const legendIconHtml = document.querySelector('.legendIcon') as HTMLElement;
|
|
306
354
|
const img: HTMLImageElement = new Image();
|
|
@@ -313,15 +361,27 @@ export class GenericTooltipService {
|
|
|
313
361
|
index = this.datasetIndex + 1;
|
|
314
362
|
}
|
|
315
363
|
const patternIndex = getPatternIndexWithShift(index, this.patternShifting);
|
|
316
|
-
if (
|
|
317
|
-
|
|
318
|
-
|
|
364
|
+
if (
|
|
365
|
+
this.chartType !== 'LINE_CHART' &&
|
|
366
|
+
this.chartType !== 'RADAR' &&
|
|
367
|
+
datasetType !== 'line'
|
|
368
|
+
) {
|
|
369
|
+
const pattern: CanvasPattern = patternsList[patternIndex - 1](
|
|
370
|
+
false,
|
|
371
|
+
patternsColors[patternIndex - 1],
|
|
372
|
+
disableAccessibility
|
|
373
|
+
);
|
|
374
|
+
const patternCanvas: HTMLCanvasElement = getPatternCanvas(
|
|
375
|
+
pattern,
|
|
376
|
+
22,
|
|
377
|
+
22
|
|
378
|
+
);
|
|
319
379
|
img.src = patternCanvas.toDataURL();
|
|
320
380
|
legendIconHtml.style.backgroundImage = `url(${img.src})`;
|
|
321
381
|
}
|
|
322
382
|
}
|
|
323
383
|
|
|
324
|
-
getBody
|
|
384
|
+
getBody(bodyItem: BodyItem) {
|
|
325
385
|
return bodyItem.lines;
|
|
326
386
|
}
|
|
327
387
|
}
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
createLegendElementWithCheckbox,
|
|
10
10
|
createHtmlLegendItemText,
|
|
11
11
|
createLegendElementWithSquareArea,
|
|
12
|
-
type ChartItem
|
|
12
|
+
type ChartItem
|
|
13
13
|
} from './ChartsCommonLegend';
|
|
14
14
|
|
|
15
15
|
const { getPatternIndexWithShift } = PatternFunctions();
|
|
@@ -18,7 +18,7 @@ export default function () {
|
|
|
18
18
|
const borderWidth = ref(2);
|
|
19
19
|
const onHoverIndex: { dataSetIndex: number; columnIndex: number } = reactive({
|
|
20
20
|
dataSetIndex: -1,
|
|
21
|
-
columnIndex: -1
|
|
21
|
+
columnIndex: -1
|
|
22
22
|
});
|
|
23
23
|
|
|
24
24
|
interface Dataset {
|
|
@@ -60,46 +60,48 @@ export default function () {
|
|
|
60
60
|
}
|
|
61
61
|
const items: ChartItem[] =
|
|
62
62
|
chart.options.plugins.legend.labels.generateLabels(chart);
|
|
63
|
-
items
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
63
|
+
items
|
|
64
|
+
.sort((a, b) => b.datasetIndex - a.datasetIndex)
|
|
65
|
+
.forEach((item: ChartItem): void => {
|
|
66
|
+
const li: HTMLElement = createHtmlLegendListElement(
|
|
67
|
+
chart,
|
|
68
|
+
selectMode,
|
|
69
|
+
item.datasetIndex
|
|
70
|
+
);
|
|
71
|
+
let liContent: HTMLElement;
|
|
72
|
+
if (!selectMode.value) {
|
|
73
|
+
if (item?.lineCap) {
|
|
74
|
+
liContent = createLegendElementWithSquareArea(item);
|
|
75
|
+
} else {
|
|
76
|
+
liContent = createLegendElementWithPatterns(
|
|
77
|
+
item,
|
|
78
|
+
chart,
|
|
79
|
+
{ datasetIndex: -1 },
|
|
80
|
+
disableAccessibility.value,
|
|
81
|
+
patternsColors.value,
|
|
82
|
+
patternsList.value,
|
|
83
|
+
false
|
|
84
|
+
);
|
|
85
|
+
}
|
|
73
86
|
} else {
|
|
74
|
-
liContent =
|
|
75
|
-
item,
|
|
87
|
+
liContent = createLegendElementWithCheckbox(
|
|
76
88
|
chart,
|
|
89
|
+
item,
|
|
90
|
+
selectMode,
|
|
77
91
|
{ datasetIndex: -1 },
|
|
78
|
-
disableAccessibility.value,
|
|
79
92
|
patternsColors.value,
|
|
80
|
-
patternsList.value,
|
|
81
93
|
false
|
|
82
94
|
);
|
|
83
95
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
liContent.style.boxSizing = 'border-box';
|
|
95
|
-
li.style.marginRight = '10px';
|
|
96
|
-
li.style.marginBottom = '2px';
|
|
97
|
-
li.appendChild(liContent);
|
|
98
|
-
li.appendChild(createHtmlLegendItemText(item));
|
|
99
|
-
ul.appendChild(li);
|
|
100
|
-
});
|
|
101
|
-
},
|
|
102
|
-
},
|
|
96
|
+
liContent.style.boxSizing = 'border-box';
|
|
97
|
+
li.style.marginRight = '10px';
|
|
98
|
+
li.style.marginBottom = '2px';
|
|
99
|
+
li.appendChild(liContent);
|
|
100
|
+
li.appendChild(createHtmlLegendItemText(item));
|
|
101
|
+
ul.appendChild(li);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
103
105
|
];
|
|
104
106
|
}
|
|
105
107
|
|
|
@@ -151,13 +153,13 @@ export default function () {
|
|
|
151
153
|
return disableAccessibility && isBarChart
|
|
152
154
|
? '#00000000'
|
|
153
155
|
: isBarChart
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
? getBorderColor(
|
|
157
|
+
index,
|
|
158
|
+
context.index,
|
|
159
|
+
patternsColors,
|
|
160
|
+
patternShifting
|
|
161
|
+
)
|
|
162
|
+
: patternsColors[index % patternsColors.length];
|
|
161
163
|
},
|
|
162
164
|
backgroundColor: function (context: any) {
|
|
163
165
|
return getPattern(
|
|
@@ -175,7 +177,7 @@ export default function () {
|
|
|
175
177
|
label: dataset.label,
|
|
176
178
|
pointBackgroundColor: '#FFFFFF',
|
|
177
179
|
pointRadius: 5,
|
|
178
|
-
order: dataset.type === 'line' ? 0 : 1
|
|
180
|
+
order: dataset.type === 'line' ? 0 : 1
|
|
179
181
|
};
|
|
180
182
|
});
|
|
181
183
|
}
|
|
@@ -255,6 +257,6 @@ export default function () {
|
|
|
255
257
|
getMixedDatasets,
|
|
256
258
|
getBorderColor,
|
|
257
259
|
getPattern,
|
|
258
|
-
onHoverIndex
|
|
260
|
+
onHoverIndex
|
|
259
261
|
};
|
|
260
262
|
}
|