@mozaic-ds/chart 0.1.0-beta.0
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/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/mozaic-chart.js +9858 -0
- package/dist/mozaic-chart.umd.cjs +22 -0
- package/dist/style.css +1 -0
- package/dist/vite.svg +1 -0
- package/package.json +79 -0
- package/src/assets/base.css +2 -0
- package/src/components/bar/BarChart.stories.ts +298 -0
- package/src/components/bar/BarChart.vue +247 -0
- package/src/components/doughnut/DoughnutChart.stories.ts +80 -0
- package/src/components/doughnut/DoughnutChart.vue +208 -0
- package/src/components/line/LineChart.stories.ts +60 -0
- package/src/components/line/LineChart.vue +245 -0
- package/src/components/radar/RadarChart.stories.ts +346 -0
- package/src/components/radar/RadarChart.vue +265 -0
- package/src/main.ts +6 -0
- package/src/services/BarChartFunctions.ts +126 -0
- package/src/services/ChartsCommonLegend.ts +366 -0
- package/src/services/DoughnutChartFunctions.ts +89 -0
- package/src/services/FormatUtilities.ts +30 -0
- package/src/services/GenericTooltipService.ts +305 -0
- package/src/services/PatternFunctions.ts +25 -0
- package/src/services/RadarChartFunctions.ts +70 -0
- package/src/services/patterns/ChartDesign.ts +27 -0
- package/src/services/patterns/patternCircles.ts +82 -0
- package/src/services/patterns/patternDashedDiagonals.ts +66 -0
- package/src/services/patterns/patternDiagonals.ts +101 -0
- package/src/services/patterns/patternSquares.ts +76 -0
- package/src/services/patterns/patternVerticalLines.ts +61 -0
- package/src/services/patterns/patternZigzag.ts +88 -0
- package/src/types/BarData.ts +11 -0
- package/src/types/ButtonName.ts +7 -0
- package/src/types/Chart.ts +10 -0
- package/src/types/DoughnutData.ts +6 -0
- package/src/types/GenericData.ts +11 -0
- package/src/types/LineChart.ts +5 -0
- package/src/types/RadarData.ts +36 -0
- package/src/types/TooltipChartType.ts +7 -0
- package/src/vite-env.d.ts +7 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import type { TooltipChartType } from '../types/TooltipChartType';
|
|
2
|
+
import { getPatternIndexWithShift } from './FormatUtilities';
|
|
3
|
+
import PatternsFunctions from '../services/PatternFunctions';
|
|
4
|
+
import ChartDesign from './patterns/ChartDesign';
|
|
5
|
+
|
|
6
|
+
const { getPatternCanvas } = PatternsFunctions();
|
|
7
|
+
const {
|
|
8
|
+
patternsStandardList
|
|
9
|
+
} = ChartDesign();
|
|
10
|
+
|
|
11
|
+
type BodyItem = {
|
|
12
|
+
after: string[];
|
|
13
|
+
before: string[];
|
|
14
|
+
lines: string[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type TooltipElements = {
|
|
18
|
+
chartType: TooltipChartType,
|
|
19
|
+
firstLineLabel?: string,
|
|
20
|
+
secondLineLabel?: string,
|
|
21
|
+
patternShifting?: number
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type LabelColors = {
|
|
25
|
+
backgroundColor: unknown;
|
|
26
|
+
borderColor: unknown;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
type PointStyle = {
|
|
30
|
+
pointStyle: unknown;
|
|
31
|
+
rotation: number;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ../..ts-ignore
|
|
35
|
+
export type Context = {
|
|
36
|
+
chart: {
|
|
37
|
+
canvas: HTMLElement;
|
|
38
|
+
tooltip?:{
|
|
39
|
+
x: number,
|
|
40
|
+
y: number
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
replay?: unknown;
|
|
44
|
+
tooltip: {
|
|
45
|
+
dataPoints: {
|
|
46
|
+
dataIndex?: number,
|
|
47
|
+
datasetIndex?: number
|
|
48
|
+
}[];
|
|
49
|
+
opacity : number;
|
|
50
|
+
body: {
|
|
51
|
+
after: string[];
|
|
52
|
+
before: string[];
|
|
53
|
+
lines: string[];
|
|
54
|
+
}[];
|
|
55
|
+
title: string[];
|
|
56
|
+
labelColors: Array<LabelColors>;
|
|
57
|
+
labelPointStyles: Array<PointStyle>;
|
|
58
|
+
caretX: number;
|
|
59
|
+
caretY: number;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class GenericTooltipService {
|
|
64
|
+
|
|
65
|
+
chartType = '';
|
|
66
|
+
datasetIndex = 0;
|
|
67
|
+
dataIndex = 0;
|
|
68
|
+
titleLines = [''];
|
|
69
|
+
dataToDisplay = '';
|
|
70
|
+
xValue = '';
|
|
71
|
+
yValue = '';
|
|
72
|
+
patternShifting = 0;
|
|
73
|
+
|
|
74
|
+
createTooltip (
|
|
75
|
+
context: Context,
|
|
76
|
+
retrieveData : (context: Context) => string,
|
|
77
|
+
tooltipInputElements: TooltipElements) {
|
|
78
|
+
if (!context.tooltip.dataPoints) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
this.datasetIndex = context.tooltip?.dataPoints[0].datasetIndex || 0;
|
|
82
|
+
this.dataIndex = context.tooltip.dataPoints[0].dataIndex || 0;
|
|
83
|
+
this.xValue = tooltipInputElements.firstLineLabel || '';
|
|
84
|
+
this.yValue = tooltipInputElements.secondLineLabel || '';
|
|
85
|
+
this.chartType = tooltipInputElements.chartType;
|
|
86
|
+
this.dataToDisplay = retrieveData(context);
|
|
87
|
+
this.patternShifting = tooltipInputElements.patternShifting || 0;
|
|
88
|
+
let tooltipEl = document.querySelector('#chartjs-tooltip') as HTMLElement | null;
|
|
89
|
+
|
|
90
|
+
if (!tooltipEl) {
|
|
91
|
+
tooltipEl = this.createNewTooltipElement();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const tooltipModel = context.tooltip;
|
|
95
|
+
|
|
96
|
+
if (tooltipModel.opacity === 0) {
|
|
97
|
+
tooltipEl.style.opacity = '0';
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (tooltipModel.body) {
|
|
102
|
+
this.titleLines = tooltipModel.title || [];
|
|
103
|
+
const bodyLines = tooltipModel.body.map(this.getBody);
|
|
104
|
+
let style = 'background: white;';
|
|
105
|
+
style += 'border-bottom: 1px solid #CCCCCC;';
|
|
106
|
+
style += 'border-radius: 5px;';
|
|
107
|
+
style += 'padding: 10px 20px';
|
|
108
|
+
|
|
109
|
+
const innerHtml = `<div style="${style}" class="tooltipTitle">`;
|
|
110
|
+
const body = this.chartType === 'DOUGHNUT' ? [tooltipModel.title[0].split('(')[0].trim()]: bodyLines[0];
|
|
111
|
+
let legendIconStyle = '';
|
|
112
|
+
let legendInnerStyle = '';
|
|
113
|
+
|
|
114
|
+
if (this.chartType === 'RADAR' || this.chartType === 'LINE_CHART') {
|
|
115
|
+
legendIconStyle = this.createLegendStyle(context);
|
|
116
|
+
legendInnerStyle = this.createLegendInnerStyle(context);
|
|
117
|
+
} else if (this.chartType === 'BAR_CHART' ||
|
|
118
|
+
this.chartType === 'DETAILS_BAR_CHART' ||
|
|
119
|
+
this.chartType === 'DOUGHNUT') {
|
|
120
|
+
legendIconStyle = this.createPatternLegendStyle(context);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.addLegendToDom(
|
|
124
|
+
innerHtml,
|
|
125
|
+
legendIconStyle,
|
|
126
|
+
legendInnerStyle,
|
|
127
|
+
body,
|
|
128
|
+
style,
|
|
129
|
+
tooltipEl
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
this.handleTooltipPosition(context, tooltipModel, tooltipEl);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private handleTooltipPosition
|
|
137
|
+
(context: Context, tooltipModel: { caretX: number, caretY: number }, tooltipEl: HTMLElement) {
|
|
138
|
+
const position = context.chart.canvas.getBoundingClientRect();
|
|
139
|
+
const screenWidth = window.innerWidth;
|
|
140
|
+
const left = position.left + window.pageXOffset + tooltipModel.caretX;
|
|
141
|
+
const top = position.top + window.pageYOffset + tooltipModel.caretY;
|
|
142
|
+
|
|
143
|
+
tooltipEl.style.left = left + 'px';
|
|
144
|
+
tooltipEl.style.top = top + 'px';
|
|
145
|
+
tooltipEl.style.height = 'auto';
|
|
146
|
+
tooltipEl.style.minWidth = '17rem';
|
|
147
|
+
tooltipEl.style.opacity = '1';
|
|
148
|
+
tooltipEl.style.position = 'absolute';
|
|
149
|
+
tooltipEl.style.zIndex = '99';
|
|
150
|
+
tooltipEl.style.backgroundColor = 'white';
|
|
151
|
+
tooltipEl.style.pointerEvents = 'none';
|
|
152
|
+
|
|
153
|
+
if (tooltipEl.getBoundingClientRect().width + left > screenWidth) {
|
|
154
|
+
tooltipEl.style.left = left - tooltipEl.getBoundingClientRect().width + 'px';
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
private createNewTooltipElement () {
|
|
159
|
+
const tooltipEl = document.createElement('div');
|
|
160
|
+
tooltipEl.id = 'chartjs-tooltip';
|
|
161
|
+
tooltipEl.style.backgroundColor = 'white';
|
|
162
|
+
tooltipEl.style.borderRadius = '5px';
|
|
163
|
+
tooltipEl.style.transition = 'opacity .5s';
|
|
164
|
+
tooltipEl.style.boxShadow = '0px 1px 5px rgba(0, 0, 0, 0.2)';
|
|
165
|
+
tooltipEl.innerHTML = '<div class="tooltipCtn"></div>';
|
|
166
|
+
document.body.appendChild(tooltipEl);
|
|
167
|
+
return tooltipEl;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
createPatternLegendStyle (context: Context) {
|
|
171
|
+
return this.createCommonLegendSquareStyle(context);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
createLegendStyle (context: Context) {
|
|
175
|
+
let legendIconStyle = `background-color:${context.tooltip.labelColors[0].backgroundColor}`;
|
|
176
|
+
legendIconStyle += this.createCommonLegendSquareStyle(context);
|
|
177
|
+
return legendIconStyle;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private createCommonLegendSquareStyle (context: Context) {
|
|
181
|
+
let style = `;border: 2px solid ${context.tooltip.labelColors[0].borderColor}`;
|
|
182
|
+
style += ';min-height: 20px';
|
|
183
|
+
style += ';min-width: 20px';
|
|
184
|
+
style += ';border-radius: 5px';
|
|
185
|
+
style += ';margin-right: 10px';
|
|
186
|
+
style += ';display: flex';
|
|
187
|
+
style += ';align-items: center';
|
|
188
|
+
style += ';justify-content: center;';
|
|
189
|
+
return style;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
createLegendInnerStyle (context: Context) {
|
|
193
|
+
let legendIconInnerStyle = 'height: 12px';
|
|
194
|
+
legendIconInnerStyle += ';width: 12px';
|
|
195
|
+
legendIconInnerStyle += ';background-color: #FFF';
|
|
196
|
+
legendIconInnerStyle += `;border: 2px solid ${context.tooltip.labelColors[0].borderColor};`;
|
|
197
|
+
|
|
198
|
+
if (context.tooltip.labelPointStyles[0].pointStyle === 'circle') {
|
|
199
|
+
legendIconInnerStyle += 'border-radius: 25px;';
|
|
200
|
+
} else if (context.tooltip.labelPointStyles[0].pointStyle === 'rectRot') {
|
|
201
|
+
legendIconInnerStyle += 'transform: rotate(45deg);';
|
|
202
|
+
}
|
|
203
|
+
return legendIconInnerStyle;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
addLegendToDom
|
|
207
|
+
(innerHTMLtext: string,
|
|
208
|
+
legendIconStyle: string,
|
|
209
|
+
legendIconInnerStyle: string,
|
|
210
|
+
body: Array<string>,
|
|
211
|
+
style: string,
|
|
212
|
+
tooltipEl: HTMLElement) {
|
|
213
|
+
let innerHtml = innerHTMLtext;
|
|
214
|
+
let legendImage = `<div class="legendIcon" style="${legendIconStyle}">`;
|
|
215
|
+
const legendSubImage = `<div style="${legendIconInnerStyle}"></div>`;
|
|
216
|
+
legendImage += `${legendSubImage}</div>`;
|
|
217
|
+
|
|
218
|
+
const innerHtmlToAdd = this.setInnerHtmlToAdd(body, style, legendImage);
|
|
219
|
+
innerHtml += innerHtmlToAdd;
|
|
220
|
+
const tableRoot = tooltipEl?.querySelector('.tooltipCtn') as HTMLElement | null;
|
|
221
|
+
|
|
222
|
+
if (tableRoot?.innerHTML != null) {
|
|
223
|
+
this.setInnerHtmlAndPattern(tableRoot, innerHtml);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
setInnerHtmlToAdd (body: Array<string>, style: string, legendImage: string) {
|
|
228
|
+
const legendText = body[0].split(':')[0];
|
|
229
|
+
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
230
|
+
const spanText = `<span style="${fontProperties}">${legendText}</span>`;
|
|
231
|
+
if (this.chartType === 'RADAR') {
|
|
232
|
+
return this.returnRadarHtml(style, legendImage, spanText);
|
|
233
|
+
} else if (this.chartType === 'DOUGHNUT') {
|
|
234
|
+
return this.returnDoughnutHtml(legendImage, spanText);
|
|
235
|
+
} else {
|
|
236
|
+
return this.returnDetailsBarchartHtml(style, legendImage, spanText);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
returnDoughnutHtml (legendImage: string, spanText: string) {
|
|
241
|
+
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
242
|
+
const legendText = `<span style="${fontProperties}">${spanText.split('(')[0]}</span>`;
|
|
243
|
+
let doughnutHtml = `<div style="${fontProperties}; display: flex; align-items: center; justify-content: space-between">`;
|
|
244
|
+
doughnutHtml += `<div style="display:flex; align-items: center;" >${legendImage + legendText}</div>`;
|
|
245
|
+
doughnutHtml += `<div style="${fontProperties}; margin-left:3rem;">${this.dataToDisplay}</div>`;
|
|
246
|
+
doughnutHtml += '</div></div>';
|
|
247
|
+
return doughnutHtml;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
returnRadarHtml (style: string, legendImage: string, spanText: string) {
|
|
251
|
+
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
252
|
+
let radarHtml = `<div style="${fontProperties}; display: flex; align-items: center;">${legendImage + spanText}</div>`;
|
|
253
|
+
radarHtml += '</div>';
|
|
254
|
+
radarHtml += `<div style="${fontProperties}; ${style}; border: none; display:flex; justify-content: space-between;">`;
|
|
255
|
+
radarHtml += `<div>${this.titleLines[0]}</div>`;
|
|
256
|
+
radarHtml += `<div style="margin-left: 20px;">${this.dataToDisplay}</div>`;
|
|
257
|
+
radarHtml += '</div>';
|
|
258
|
+
radarHtml += '</div><div>';
|
|
259
|
+
|
|
260
|
+
return radarHtml;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
returnDetailsBarchartHtml (style: string, legendImage: string, spanText: string) {
|
|
264
|
+
const fontProperties = 'font-family: Arial; font-size: 16px';
|
|
265
|
+
let barChartHtml = `<div style="${fontProperties}; display: flex; align-items: center;">${legendImage + spanText}</div>`;
|
|
266
|
+
barChartHtml += '</div>';
|
|
267
|
+
barChartHtml += `<div style="${fontProperties}; ${style}; display:flex; justify-content: space-between;">`;
|
|
268
|
+
barChartHtml += `<div>${this.xValue}</div>`;
|
|
269
|
+
barChartHtml += `<div style="margin-left: 20px;">${this.titleLines[0]}</div>`;
|
|
270
|
+
barChartHtml += '</div>';
|
|
271
|
+
|
|
272
|
+
barChartHtml += `<div style="${fontProperties}; ${style}; border-: none; display:flex; justify-content: space-between;">`;
|
|
273
|
+
barChartHtml += `<div>${(this.yValue)}</div>`;
|
|
274
|
+
barChartHtml += `<div style="margin-left: 20px;">${this.dataToDisplay}</div>`;
|
|
275
|
+
barChartHtml += '</div>';
|
|
276
|
+
|
|
277
|
+
return barChartHtml;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
setInnerHtmlAndPattern(tableRoot: HTMLElement, innerHtml: string) {
|
|
282
|
+
tableRoot.innerHTML = innerHtml;
|
|
283
|
+
const legendIconHtml = document.querySelector('.legendIcon') as HTMLElement;
|
|
284
|
+
const img: HTMLImageElement = new Image();
|
|
285
|
+
|
|
286
|
+
let index: number;
|
|
287
|
+
|
|
288
|
+
if (this.chartType === 'DOUGHNUT') {
|
|
289
|
+
index = this.dataIndex + 1;
|
|
290
|
+
} else {
|
|
291
|
+
index = this.datasetIndex + 1;
|
|
292
|
+
}
|
|
293
|
+
const patternIndex = getPatternIndexWithShift(index, this.patternShifting);
|
|
294
|
+
if (this.chartType !== 'LINE_CHART' && this.chartType !== 'RADAR') {
|
|
295
|
+
const pattern: CanvasPattern = patternsStandardList[patternIndex - 1](false);
|
|
296
|
+
const patternCanvas: HTMLCanvasElement = getPatternCanvas(pattern, 22, 22);
|
|
297
|
+
img.src = patternCanvas.toDataURL();
|
|
298
|
+
legendIconHtml.style.backgroundImage = `url(${img.src})`;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
getBody (bodyItem :BodyItem) {
|
|
303
|
+
return bodyItem.lines;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export default function () {
|
|
2
|
+
function getPatternCanvas(pattern: CanvasPattern, width = 50, height = 50): HTMLCanvasElement {
|
|
3
|
+
const canvas: HTMLCanvasElement = document.createElement('canvas');
|
|
4
|
+
const ctx: CanvasRenderingContext2D | null = canvas.getContext('2d');
|
|
5
|
+
if (!ctx) {
|
|
6
|
+
return canvas;
|
|
7
|
+
}
|
|
8
|
+
canvas.width = width;
|
|
9
|
+
canvas.height = height;
|
|
10
|
+
ctx.fillStyle = pattern;
|
|
11
|
+
ctx.fillRect(0, 0, width, height);
|
|
12
|
+
return canvas;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getPatternIndexWithShift (dataSetIndex: number, patternShifting?: number) {
|
|
16
|
+
return patternShifting
|
|
17
|
+
? (dataSetIndex + patternShifting) % 6
|
|
18
|
+
: dataSetIndex;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
getPatternCanvas,
|
|
23
|
+
getPatternIndexWithShift
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Chart, RadialLinearScale } from 'chart.js';
|
|
2
|
+
|
|
3
|
+
export function drawLabels (chart: Chart, props: any) {
|
|
4
|
+
const ctx = chart.ctx;
|
|
5
|
+
const scale = chart.scales.r as RadialLinearScale;
|
|
6
|
+
const labels = chart.data.labels as string[][];
|
|
7
|
+
|
|
8
|
+
if (!ctx || !scale || !labels) {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
ctx.save();
|
|
13
|
+
labels.forEach((label: string[], index: number) => {
|
|
14
|
+
const angle = (scale.getIndexAngle(index) - Math.PI / 2) % (2 * Math.PI);
|
|
15
|
+
const position = scale.getPointPositionForValue(index, scale.max);
|
|
16
|
+
|
|
17
|
+
ctx.textAlign = angle <= Math.PI / 2 || angle > 3 * Math.PI / 2 ? 'left' : 'right';
|
|
18
|
+
let xOffset = angle <= Math.PI / 2 || angle > 3 * Math.PI / 2 ? 15 : -15;
|
|
19
|
+
|
|
20
|
+
let yOffset;
|
|
21
|
+
//top or bottom labels
|
|
22
|
+
if ( angle < 0 || angle > Math.PI) {
|
|
23
|
+
yOffset = -15;
|
|
24
|
+
} else {
|
|
25
|
+
yOffset = 15;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//bottom labels
|
|
29
|
+
if ( angle > Math.PI / 4 && angle < 3 * Math.PI / 4) {
|
|
30
|
+
yOffset *= 3;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//top labels left and right
|
|
34
|
+
if ( angle < -Math.PI / 4 || angle > 5 * Math.PI / 4) {
|
|
35
|
+
yOffset *= 3;
|
|
36
|
+
xOffset = 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// full top label
|
|
40
|
+
if ( angle > 11 * Math.PI / 8 || angle < -3 * Math.PI / 8){
|
|
41
|
+
ctx.textAlign = 'center';
|
|
42
|
+
}
|
|
43
|
+
const yPos = position.y + yOffset * (label.length - 1) / 2;
|
|
44
|
+
ctx.font = '15px Arial';
|
|
45
|
+
|
|
46
|
+
label.forEach((text, i) => {
|
|
47
|
+
const color = i === label.length - 1 ? buildColorArray(props)[index] : '#000000';
|
|
48
|
+
ctx.fillStyle = color;
|
|
49
|
+
|
|
50
|
+
const x = position.x + xOffset;
|
|
51
|
+
const y = yPos + 15 * i;
|
|
52
|
+
|
|
53
|
+
ctx.fillText(text, x, y);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
ctx.restore();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const buildColorArray = (props: any): string[]=> {
|
|
60
|
+
return props.areas[0].areaData.map((x: { color: string }) => {
|
|
61
|
+
switch (x.color) {
|
|
62
|
+
case 'red':
|
|
63
|
+
return '#C61112';
|
|
64
|
+
case 'green':
|
|
65
|
+
return '#46A610';
|
|
66
|
+
default:
|
|
67
|
+
return '#000000';
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import PatternSquares from './patternSquares';
|
|
2
|
+
import PatternDiagonals from './patternDiagonals';
|
|
3
|
+
import PatternZigzag from './patternZigzag';
|
|
4
|
+
import PatternVerticalLines from './patternVerticalLines';
|
|
5
|
+
import PatternDashedDiagonals from './patternDashedDiagonals';
|
|
6
|
+
import PatternCircles from './patternCircles';
|
|
7
|
+
|
|
8
|
+
export default function() {
|
|
9
|
+
const patternsStandardList = [
|
|
10
|
+
PatternSquares,
|
|
11
|
+
PatternDiagonals,
|
|
12
|
+
PatternZigzag,
|
|
13
|
+
PatternVerticalLines,
|
|
14
|
+
PatternDashedDiagonals,
|
|
15
|
+
PatternCircles
|
|
16
|
+
] as ((hover: boolean) => CanvasPattern)[];
|
|
17
|
+
|
|
18
|
+
const patternsColors: string[] = ['#393879b3', '#006974b3', '#405d68b3', '#005c91b3', '#8c3500b3', '#8c0003b3'];
|
|
19
|
+
const patternsColorsLowerOpacity: string[] = ['#3938794d', '#0069744d', '#405d684d', '#005c914d', '#8c35004d', '#8c00034d'];
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
patternsStandardList,
|
|
23
|
+
patternsColors,
|
|
24
|
+
patternsColorsLowerOpacity,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export default function PatternCircles(hover: boolean): CanvasPattern {
|
|
2
|
+
const canvasPattern: HTMLCanvasElement = document.createElement('canvas');
|
|
3
|
+
const ctx: CanvasRenderingContext2D | null = canvasPattern.getContext('2d');
|
|
4
|
+
|
|
5
|
+
if (!ctx) {
|
|
6
|
+
return new CanvasPattern;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const patternSize = 50;
|
|
10
|
+
const lineWidthPattern = 0.04 * patternSize;
|
|
11
|
+
|
|
12
|
+
canvasPattern.width = patternSize;
|
|
13
|
+
canvasPattern.height = patternSize;
|
|
14
|
+
|
|
15
|
+
// #rect1258
|
|
16
|
+
ctx.beginPath();
|
|
17
|
+
ctx.fillStyle = 'rgb(253, 234, 234)';
|
|
18
|
+
ctx.lineWidth = 0.1005 * patternSize;
|
|
19
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
20
|
+
ctx.fill();
|
|
21
|
+
|
|
22
|
+
// #circle4
|
|
23
|
+
ctx.beginPath();
|
|
24
|
+
ctx.globalAlpha = 0.3;
|
|
25
|
+
ctx.strokeStyle = 'rgb(140, 0, 3)';
|
|
26
|
+
ctx.lineWidth = lineWidthPattern;
|
|
27
|
+
ctx.arc(lineWidthPattern + 0.06 * patternSize,
|
|
28
|
+
lineWidthPattern + 0.06 * patternSize, 0.06 * patternSize, 0, 2 * Math.PI);
|
|
29
|
+
ctx.stroke();
|
|
30
|
+
|
|
31
|
+
// #circle6
|
|
32
|
+
ctx.beginPath();
|
|
33
|
+
ctx.globalAlpha = 0.7;
|
|
34
|
+
ctx.strokeStyle = 'rgb(140, 0, 3)';
|
|
35
|
+
ctx.lineWidth = lineWidthPattern;
|
|
36
|
+
ctx.arc(lineWidthPattern + 0.56 * patternSize,
|
|
37
|
+
lineWidthPattern + 0.06 * patternSize, 0.06 * patternSize, 0, 2 * Math.PI);
|
|
38
|
+
ctx.stroke();
|
|
39
|
+
|
|
40
|
+
// #circle104
|
|
41
|
+
ctx.beginPath();
|
|
42
|
+
ctx.globalAlpha = 0.3;
|
|
43
|
+
ctx.strokeStyle = 'rgb(140, 0, 3)';
|
|
44
|
+
ctx.lineWidth = 0.04 * patternSize;
|
|
45
|
+
ctx.arc(-lineWidthPattern + 0.44 * patternSize,
|
|
46
|
+
lineWidthPattern + 0.56 * patternSize, 0.06 * patternSize, 0, 2 * Math.PI);
|
|
47
|
+
ctx.stroke();
|
|
48
|
+
|
|
49
|
+
// #circle106
|
|
50
|
+
ctx.beginPath();
|
|
51
|
+
ctx.globalAlpha = 0.7;
|
|
52
|
+
ctx.strokeStyle = 'rgb(140, 0, 3)';
|
|
53
|
+
ctx.lineWidth = 0.04 * patternSize;
|
|
54
|
+
ctx.arc(-lineWidthPattern + 0.94 * patternSize,
|
|
55
|
+
lineWidthPattern + 0.56 * patternSize, 0.06 * patternSize, 0, 2 * Math.PI);
|
|
56
|
+
ctx.stroke();
|
|
57
|
+
|
|
58
|
+
// Hover Style
|
|
59
|
+
if (hover) {
|
|
60
|
+
ctx.beginPath();
|
|
61
|
+
0.5;
|
|
62
|
+
ctx.fillStyle = '#FFFFFF';
|
|
63
|
+
ctx.lineWidth = 0.006 * patternSize;
|
|
64
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
65
|
+
ctx.fill();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const canvas: HTMLCanvasElement = document.createElement('canvas');
|
|
69
|
+
const context: CanvasRenderingContext2D | null = canvas.getContext('2d');
|
|
70
|
+
if (!context) {
|
|
71
|
+
return new CanvasPattern;
|
|
72
|
+
}
|
|
73
|
+
const pattern: CanvasPattern | null = context.createPattern(canvasPattern, 'repeat');
|
|
74
|
+
if (!pattern) {
|
|
75
|
+
return new CanvasPattern;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
context.fillStyle = pattern;
|
|
79
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
80
|
+
|
|
81
|
+
return pattern;
|
|
82
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export default function PatternDashedDiagonals(hover: boolean): CanvasPattern {
|
|
2
|
+
const canvasPattern: HTMLCanvasElement = document.createElement('canvas');
|
|
3
|
+
const ctx: CanvasRenderingContext2D | null = canvasPattern.getContext('2d');
|
|
4
|
+
|
|
5
|
+
if (!ctx) {
|
|
6
|
+
return new CanvasPattern;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const matrix = new DOMMatrix();
|
|
10
|
+
|
|
11
|
+
const patternSize = 21;
|
|
12
|
+
const lineWidth = 0.1 * patternSize;
|
|
13
|
+
|
|
14
|
+
canvasPattern.width = patternSize;
|
|
15
|
+
canvasPattern.height = patternSize;
|
|
16
|
+
|
|
17
|
+
// #rect1258
|
|
18
|
+
ctx.beginPath();
|
|
19
|
+
ctx.fillStyle = 'rgb(253, 241, 232)';
|
|
20
|
+
ctx.lineWidth = 0.005 * patternSize;
|
|
21
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
22
|
+
ctx.fill();
|
|
23
|
+
|
|
24
|
+
// #path991
|
|
25
|
+
ctx.beginPath();
|
|
26
|
+
ctx.globalAlpha = 0.3;
|
|
27
|
+
ctx.strokeStyle = 'rgb(140, 53, 0)';
|
|
28
|
+
ctx.lineWidth = lineWidth;
|
|
29
|
+
ctx.moveTo(lineWidth, 0);
|
|
30
|
+
ctx.lineTo(lineWidth, 0.5 * patternSize);
|
|
31
|
+
ctx.stroke();
|
|
32
|
+
|
|
33
|
+
// #path991
|
|
34
|
+
ctx.beginPath();
|
|
35
|
+
ctx.globalAlpha = 0.7;
|
|
36
|
+
ctx.strokeStyle = 'rgb(140, 53, 0)';
|
|
37
|
+
ctx.lineWidth = lineWidth;
|
|
38
|
+
ctx.moveTo(patternSize / 2 + lineWidth, 0);
|
|
39
|
+
ctx.lineTo(patternSize / 2 + lineWidth, 0.5 * patternSize);
|
|
40
|
+
ctx.stroke();
|
|
41
|
+
|
|
42
|
+
// Hover Style
|
|
43
|
+
if (hover) {
|
|
44
|
+
ctx.beginPath();
|
|
45
|
+
ctx.fillStyle = '#FFFFFF';
|
|
46
|
+
ctx.lineWidth = 0.006 * patternSize;
|
|
47
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
48
|
+
ctx.fill();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const canvas: HTMLCanvasElement = document.createElement('canvas');
|
|
52
|
+
const context: CanvasRenderingContext2D | null = canvas.getContext('2d');
|
|
53
|
+
if (!context) {
|
|
54
|
+
return new CanvasPattern;
|
|
55
|
+
}
|
|
56
|
+
const pattern: CanvasPattern | null = context.createPattern(canvasPattern, 'repeat');
|
|
57
|
+
if (!pattern) {
|
|
58
|
+
return new CanvasPattern;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
context.fillStyle = pattern;
|
|
62
|
+
context.fillRect(0, 0, canvas.width, canvas.height);
|
|
63
|
+
pattern.setTransform(matrix.rotate(45));
|
|
64
|
+
|
|
65
|
+
return pattern;
|
|
66
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export default function PatternDiagonals(hover: boolean): CanvasPattern {
|
|
2
|
+
const patternCanvas: HTMLCanvasElement = document.createElement('canvas');
|
|
3
|
+
const ctx: CanvasRenderingContext2D | null = patternCanvas.getContext('2d');
|
|
4
|
+
if (!ctx) {
|
|
5
|
+
return new CanvasPattern;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const patternSize = 50;
|
|
9
|
+
|
|
10
|
+
patternCanvas.width = patternSize;
|
|
11
|
+
patternCanvas.height = patternSize;
|
|
12
|
+
|
|
13
|
+
ctx.beginPath();
|
|
14
|
+
ctx.fillStyle = 'rgb(217, 240, 243)';
|
|
15
|
+
ctx.lineWidth = 0.005 * patternSize;
|
|
16
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
17
|
+
ctx.fill();
|
|
18
|
+
|
|
19
|
+
// #rect2744
|
|
20
|
+
ctx.save();
|
|
21
|
+
ctx.beginPath();
|
|
22
|
+
ctx.transform(0.708293, 0.705919, -0.666352, 0.745637, 0.000000, 0.000000);
|
|
23
|
+
ctx.globalAlpha = 0.7;
|
|
24
|
+
ctx.fillStyle = 'rgb(0, 105, 116)';
|
|
25
|
+
ctx.lineWidth = 0.075 * patternSize;
|
|
26
|
+
ctx.miterLimit = 4;
|
|
27
|
+
ctx.rect(- patternSize * 0.03, - 0.01 * patternSize, patternSize + patternSize / 2, 0.04 * patternSize);
|
|
28
|
+
ctx.fill();
|
|
29
|
+
ctx.restore();
|
|
30
|
+
|
|
31
|
+
// #rect2744-5
|
|
32
|
+
ctx.save();
|
|
33
|
+
ctx.beginPath();
|
|
34
|
+
ctx.transform(0.708293, 0.705919, -0.666352, 0.745637, 0.000000, 0.000000);
|
|
35
|
+
ctx.globalAlpha = 0.3;
|
|
36
|
+
ctx.fillStyle = 'rgb(0, 105, 116)';
|
|
37
|
+
ctx.lineWidth = 0.075 * patternSize;
|
|
38
|
+
ctx.miterLimit = 4;
|
|
39
|
+
ctx.rect(0.29 * patternSize, 0.33 * patternSize, patternSize + patternSize / 2, 0.04 * patternSize);
|
|
40
|
+
ctx.fill();
|
|
41
|
+
ctx.restore();
|
|
42
|
+
|
|
43
|
+
// #rect2744-5-3
|
|
44
|
+
ctx.save();
|
|
45
|
+
ctx.beginPath();
|
|
46
|
+
ctx.transform(0.708293, 0.705919, -0.666352, 0.745637, 0.000000, 0.000000);
|
|
47
|
+
ctx.globalAlpha = 0.7;
|
|
48
|
+
ctx.fillStyle = 'rgb(0, 105, 116)';
|
|
49
|
+
ctx.lineWidth = 0.075 * patternSize;
|
|
50
|
+
ctx.miterLimit = 4;
|
|
51
|
+
ctx.rect(0.63 * patternSize, 0.69 * patternSize, patternSize + patternSize / 2, 0.04 * patternSize);
|
|
52
|
+
ctx.fill();
|
|
53
|
+
ctx.restore();
|
|
54
|
+
|
|
55
|
+
// #rect2744-6
|
|
56
|
+
ctx.save();
|
|
57
|
+
ctx.beginPath();
|
|
58
|
+
ctx.transform(0.708293, 0.705919, -0.666352, 0.745637, 0.000000, 0.000000);
|
|
59
|
+
ctx.globalAlpha = 0.3;
|
|
60
|
+
ctx.fillStyle = 'rgb(0, 105, 116)';
|
|
61
|
+
ctx.lineWidth = 0.075 * patternSize;
|
|
62
|
+
ctx.miterLimit = 4;
|
|
63
|
+
ctx.rect(0.33 * patternSize, -0.37 * patternSize, patternSize + patternSize / 2, 0.04 * patternSize);
|
|
64
|
+
ctx.fill();
|
|
65
|
+
ctx.restore();
|
|
66
|
+
|
|
67
|
+
// #rect2744-6-7
|
|
68
|
+
ctx.save();
|
|
69
|
+
ctx.beginPath();
|
|
70
|
+
ctx.transform(0.708293, 0.705919, -0.666352, 0.745637, 0.000000, 0.000000);
|
|
71
|
+
ctx.globalAlpha = 0.7;
|
|
72
|
+
ctx.fillStyle = 'rgb(0, 105, 116)';
|
|
73
|
+
ctx.lineWidth = 0.075 * patternSize;
|
|
74
|
+
ctx.miterLimit = 4;
|
|
75
|
+
ctx.rect(0.71 * patternSize, - 0.72 * patternSize, patternSize + patternSize / 2, 0.04 * patternSize);
|
|
76
|
+
ctx.fill();
|
|
77
|
+
ctx.restore();
|
|
78
|
+
|
|
79
|
+
// Hover Style
|
|
80
|
+
if (hover) {
|
|
81
|
+
ctx.beginPath();
|
|
82
|
+
ctx.globalAlpha = 0.5;
|
|
83
|
+
ctx.fillStyle = '#FFFFFF';
|
|
84
|
+
ctx.lineWidth = 0.006 * patternSize;
|
|
85
|
+
ctx.rect(0.000000, 0.000000, patternSize, patternSize);
|
|
86
|
+
ctx.fill();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Create our primary canvas and fill it with the pattern
|
|
90
|
+
const canvas: HTMLCanvasElement = document.createElement('canvas');
|
|
91
|
+
const context: CanvasRenderingContext2D | null = canvas.getContext('2d');
|
|
92
|
+
if (!context) {
|
|
93
|
+
return new CanvasPattern;
|
|
94
|
+
}
|
|
95
|
+
const pattern: CanvasPattern | null = context.createPattern(patternCanvas, 'repeat');
|
|
96
|
+
if (!pattern) {
|
|
97
|
+
return new CanvasPattern;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return pattern;
|
|
101
|
+
}
|