@fluentui/react-charts 9.3.6 → 9.3.8
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/CHANGELOG.md +46 -2
- package/dist/index.d.ts +70 -17
- package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.js +2 -16
- package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.js.map +1 -1
- package/lib/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js.map +1 -1
- package/lib/components/AreaChart/AreaChart.js +3 -43
- package/lib/components/AreaChart/AreaChart.js.map +1 -1
- package/lib/components/AreaChart/useAreaChartStyles.styles.js +1 -2
- package/lib/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
- package/lib/components/ChartTable/ChartTable.js +8 -11
- package/lib/components/ChartTable/ChartTable.js.map +1 -1
- package/lib/components/ChartTable/ChartTable.types.js.map +1 -1
- package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.js +107 -67
- package/lib/components/CommonComponents/Annotations/ChartAnnotationLayer.js.map +1 -1
- package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js +7 -1
- package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js.map +1 -1
- package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js +7 -1
- package/lib/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js.map +1 -1
- package/lib/components/CommonComponents/CartesianChart.js +52 -32
- package/lib/components/CommonComponents/CartesianChart.js.map +1 -1
- package/lib/components/CommonComponents/CartesianChart.types.js.map +1 -1
- package/lib/components/CommonComponents/ChartPopover.js +1 -2
- package/lib/components/CommonComponents/ChartPopover.js.map +1 -1
- package/lib/components/CommonComponents/useCartesianChartStyles.styles.js +9 -7
- package/lib/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
- package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js +8 -5
- package/lib/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
- package/lib/components/CommonComponents/useChartPopoverStyles.styles.js.map +1 -1
- package/lib/components/CommonComponents/useChartPopoverStyles.styles.raw.js +0 -2
- package/lib/components/CommonComponents/useChartPopoverStyles.styles.raw.js.map +1 -1
- package/lib/components/DeclarativeChart/DeclarativeChart.js +48 -25
- package/lib/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js +309 -209
- package/lib/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib/components/DonutChart/DonutChart.js +9 -15
- package/lib/components/DonutChart/DonutChart.js.map +1 -1
- package/lib/components/DonutChart/DonutChart.types.js.map +1 -1
- package/lib/components/DonutChart/Pie/Pie.js +4 -2
- package/lib/components/DonutChart/Pie/Pie.js.map +1 -1
- package/lib/components/FunnelChart/FunnelChart.js +8 -13
- package/lib/components/FunnelChart/FunnelChart.js.map +1 -1
- package/lib/components/FunnelChart/FunnelChart.types.js.map +1 -1
- package/lib/components/GanttChart/GanttChart.js +4 -17
- package/lib/components/GanttChart/GanttChart.js.map +1 -1
- package/lib/components/GaugeChart/GaugeChart.js +8 -13
- package/lib/components/GaugeChart/GaugeChart.js.map +1 -1
- package/lib/components/GaugeChart/GaugeChart.types.js.map +1 -1
- package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +24 -36
- package/lib/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
- package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +1 -2
- package/lib/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
- package/lib/components/HeatMapChart/HeatMapChart.js +3 -16
- package/lib/components/HeatMapChart/HeatMapChart.js.map +1 -1
- package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +5 -25
- package/lib/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
- package/lib/components/Legends/Legends.js +3 -4
- package/lib/components/Legends/Legends.js.map +1 -1
- package/lib/components/Legends/Legends.types.js.map +1 -1
- package/lib/components/Legends/OverflowMenu.js.map +1 -1
- package/lib/components/Legends/useLegendsStyles.styles.raw.js.map +1 -1
- package/lib/components/LineChart/LineChart.js +68 -75
- package/lib/components/LineChart/LineChart.js.map +1 -1
- package/lib/components/LineChart/LineChart.types.js +1 -1
- package/lib/components/LineChart/LineChart.types.js.map +1 -1
- package/lib/components/LineChart/eventAnnotation/EventAnnotation.js +3 -4
- package/lib/components/LineChart/eventAnnotation/EventAnnotation.js.map +1 -1
- package/lib/components/LineChart/useLineChartStyles.styles.js +1 -2
- package/lib/components/LineChart/useLineChartStyles.styles.js.map +1 -1
- package/lib/components/SankeyChart/SankeyChart.js +4 -10
- package/lib/components/SankeyChart/SankeyChart.js.map +1 -1
- package/lib/components/SankeyChart/SankeyChart.types.js.map +1 -1
- package/lib/components/SankeyChart/useSankeyChartStyles.styles.js +1 -2
- package/lib/components/SankeyChart/useSankeyChartStyles.styles.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.js +41 -49
- package/lib/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib/components/ScatterChart/ScatterChart.types.js.map +1 -1
- package/lib/components/ScatterChart/useScatterChartStyles.styles.js +1 -2
- package/lib/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
- package/lib/components/Sparkline/Sparkline.js +11 -7
- package/lib/components/Sparkline/Sparkline.js.map +1 -1
- package/lib/components/VerticalBarChart/VerticalBarChart.js +15 -92
- package/lib/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
- package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +1 -2
- package/lib/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js +28 -49
- package/lib/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +1 -2
- package/lib/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
- package/lib/types/ChartAnnotation.js.map +1 -1
- package/lib/types/DataPoint.js.map +1 -1
- package/lib/utilities/Common.styles.js +0 -1
- package/lib/utilities/Common.styles.js.map +1 -1
- package/lib/utilities/Common.styles.raw.js +0 -1
- package/lib/utilities/Common.styles.raw.js.map +1 -1
- package/lib/utilities/FocusableTooltipText.js +1 -1
- package/lib/utilities/FocusableTooltipText.js.map +1 -1
- package/lib/utilities/getWindow.js +0 -1
- package/lib/utilities/getWindow.js.map +1 -1
- package/lib/utilities/hooks.js +34 -0
- package/lib/utilities/hooks.js.map +1 -0
- package/lib/utilities/image-export-utils.js +118 -78
- package/lib/utilities/image-export-utils.js.map +1 -1
- package/lib/utilities/utilities.js +243 -102
- package/lib/utilities/utilities.js.map +1 -1
- package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.js +2 -16
- package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.js.map +1 -1
- package/lib-commonjs/components/AnnotationOnlyChart/AnnotationOnlyChart.types.js.map +1 -1
- package/lib-commonjs/components/AreaChart/AreaChart.js +2 -41
- package/lib-commonjs/components/AreaChart/AreaChart.js.map +1 -1
- package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.js +0 -2
- package/lib-commonjs/components/AreaChart/useAreaChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/ChartTable/ChartTable.js +9 -11
- package/lib-commonjs/components/ChartTable/ChartTable.js.map +1 -1
- package/lib-commonjs/components/ChartTable/ChartTable.types.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.js +107 -67
- package/lib-commonjs/components/CommonComponents/Annotations/ChartAnnotationLayer.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js +7 -1
- package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js +7 -1
- package/lib-commonjs/components/CommonComponents/Annotations/useChartAnnotationLayer.styles.raw.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/CartesianChart.js +51 -31
- package/lib-commonjs/components/CommonComponents/CartesianChart.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/CartesianChart.types.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/ChartPopover.js +1 -2
- package/lib-commonjs/components/CommonComponents/ChartPopover.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js +7 -6
- package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js +7 -4
- package/lib-commonjs/components/CommonComponents/useCartesianChartStyles.styles.raw.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/useChartPopoverStyles.styles.js.map +1 -1
- package/lib-commonjs/components/CommonComponents/useChartPopoverStyles.styles.raw.js +0 -2
- package/lib-commonjs/components/CommonComponents/useChartPopoverStyles.styles.raw.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js +48 -25
- package/lib-commonjs/components/DeclarativeChart/DeclarativeChart.js.map +1 -1
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js +309 -208
- package/lib-commonjs/components/DeclarativeChart/PlotlySchemaAdapter.js.map +1 -1
- package/lib-commonjs/components/DonutChart/DonutChart.js +7 -13
- package/lib-commonjs/components/DonutChart/DonutChart.js.map +1 -1
- package/lib-commonjs/components/DonutChart/DonutChart.types.js.map +1 -1
- package/lib-commonjs/components/DonutChart/Pie/Pie.js +4 -2
- package/lib-commonjs/components/DonutChart/Pie/Pie.js.map +1 -1
- package/lib-commonjs/components/FunnelChart/FunnelChart.js +7 -12
- package/lib-commonjs/components/FunnelChart/FunnelChart.js.map +1 -1
- package/lib-commonjs/components/FunnelChart/FunnelChart.types.js.map +1 -1
- package/lib-commonjs/components/GanttChart/GanttChart.js +3 -16
- package/lib-commonjs/components/GanttChart/GanttChart.js.map +1 -1
- package/lib-commonjs/components/GaugeChart/GaugeChart.js +7 -12
- package/lib-commonjs/components/GaugeChart/GaugeChart.js.map +1 -1
- package/lib-commonjs/components/GaugeChart/GaugeChart.types.js.map +1 -1
- package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js +22 -34
- package/lib-commonjs/components/GroupedVerticalBarChart/GroupedVerticalBarChart.js.map +1 -1
- package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js +0 -2
- package/lib-commonjs/components/GroupedVerticalBarChart/useGroupedVerticalBarChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/HeatMapChart/HeatMapChart.js +2 -15
- package/lib-commonjs/components/HeatMapChart/HeatMapChart.js.map +1 -1
- package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js +4 -23
- package/lib-commonjs/components/HorizontalBarChartWithAxis/HorizontalBarChartWithAxis.js.map +1 -1
- package/lib-commonjs/components/Legends/Legends.js +3 -4
- package/lib-commonjs/components/Legends/Legends.js.map +1 -1
- package/lib-commonjs/components/Legends/Legends.types.js.map +1 -1
- package/lib-commonjs/components/Legends/OverflowMenu.js.map +1 -1
- package/lib-commonjs/components/Legends/useLegendsStyles.styles.raw.js.map +1 -1
- package/lib-commonjs/components/LineChart/LineChart.js +67 -74
- package/lib-commonjs/components/LineChart/LineChart.js.map +1 -1
- package/lib-commonjs/components/LineChart/LineChart.types.js +1 -1
- package/lib-commonjs/components/LineChart/LineChart.types.js.map +1 -1
- package/lib-commonjs/components/LineChart/eventAnnotation/EventAnnotation.js +2 -2
- package/lib-commonjs/components/LineChart/eventAnnotation/EventAnnotation.js.map +1 -1
- package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js +0 -2
- package/lib-commonjs/components/LineChart/useLineChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/SankeyChart/SankeyChart.js +4 -10
- package/lib-commonjs/components/SankeyChart/SankeyChart.js.map +1 -1
- package/lib-commonjs/components/SankeyChart/SankeyChart.types.js.map +1 -1
- package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.js +0 -2
- package/lib-commonjs/components/SankeyChart/useSankeyChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.js +38 -46
- package/lib-commonjs/components/ScatterChart/ScatterChart.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/ScatterChart.types.js.map +1 -1
- package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js +0 -2
- package/lib-commonjs/components/ScatterChart/useScatterChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/Sparkline/Sparkline.js +11 -7
- package/lib-commonjs/components/Sparkline/Sparkline.js.map +1 -1
- package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js +14 -91
- package/lib-commonjs/components/VerticalBarChart/VerticalBarChart.js.map +1 -1
- package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js +0 -2
- package/lib-commonjs/components/VerticalBarChart/useVerticalBarChartStyles.styles.js.map +1 -1
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js +26 -47
- package/lib-commonjs/components/VerticalStackedBarChart/VerticalStackedBarChart.js.map +1 -1
- package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js +0 -2
- package/lib-commonjs/components/VerticalStackedBarChart/useVerticalStackedBarChartStyles.styles.js.map +1 -1
- package/lib-commonjs/types/ChartAnnotation.js.map +1 -1
- package/lib-commonjs/types/DataPoint.js.map +1 -1
- package/lib-commonjs/utilities/Common.styles.js +0 -1
- package/lib-commonjs/utilities/Common.styles.js.map +1 -1
- package/lib-commonjs/utilities/Common.styles.raw.js +0 -1
- package/lib-commonjs/utilities/Common.styles.raw.js.map +1 -1
- package/lib-commonjs/utilities/FocusableTooltipText.js.map +1 -1
- package/lib-commonjs/utilities/getWindow.js +0 -1
- package/lib-commonjs/utilities/getWindow.js.map +1 -1
- package/lib-commonjs/utilities/hooks.js +45 -0
- package/lib-commonjs/utilities/hooks.js.map +1 -0
- package/lib-commonjs/utilities/image-export-utils.js +119 -79
- package/lib-commonjs/utilities/image-export-utils.js.map +1 -1
- package/lib-commonjs/utilities/utilities.js +253 -101
- package/lib-commonjs/utilities/utilities.js.map +1 -1
- package/package.json +9 -9
- package/lib/components/DeclarativeChart/imageExporter.js +0 -223
- package/lib/components/DeclarativeChart/imageExporter.js.map +0 -1
- package/lib-commonjs/components/DeclarativeChart/imageExporter.js +0 -233
- package/lib-commonjs/components/DeclarativeChart/imageExporter.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui/react-charts",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.8",
|
|
4
4
|
"description": "React web chart controls for Microsoft fluentui v9 system.",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"@fluentui/scripts-api-extractor": "*"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@fluentui/chart-utilities": "^1.1.
|
|
31
|
-
"@fluentui/react-button": "^9.
|
|
32
|
-
"@fluentui/react-jsx-runtime": "^9.3.
|
|
33
|
-
"@fluentui/react-overflow": "^9.6.
|
|
34
|
-
"@fluentui/react-popover": "^9.12.
|
|
30
|
+
"@fluentui/chart-utilities": "^1.1.38",
|
|
31
|
+
"@fluentui/react-button": "^9.7.1",
|
|
32
|
+
"@fluentui/react-jsx-runtime": "^9.3.4",
|
|
33
|
+
"@fluentui/react-overflow": "^9.6.6",
|
|
34
|
+
"@fluentui/react-popover": "^9.12.13",
|
|
35
35
|
"@fluentui/react-shared-contexts": "^9.26.0",
|
|
36
|
-
"@fluentui/react-tabster": "^9.26.
|
|
36
|
+
"@fluentui/react-tabster": "^9.26.11",
|
|
37
37
|
"@fluentui/react-theme": "^9.2.0",
|
|
38
|
-
"@fluentui/react-tooltip": "^9.8.
|
|
39
|
-
"@fluentui/react-utilities": "^9.
|
|
38
|
+
"@fluentui/react-tooltip": "^9.8.12",
|
|
39
|
+
"@fluentui/react-utilities": "^9.26.0",
|
|
40
40
|
"@griffel/react": "^1.5.32",
|
|
41
41
|
"@swc/helpers": "^0.5.1",
|
|
42
42
|
"@types/d3-array": "^3.0.0",
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
import { create as d3Create, select as d3Select } from 'd3-selection';
|
|
3
|
-
import { resolveCSSVariables } from '../../utilities/index';
|
|
4
|
-
export function toImage(chartContainer, opts = {}) {
|
|
5
|
-
return new Promise((resolve, reject)=>{
|
|
6
|
-
if (!chartContainer) {
|
|
7
|
-
return reject(new Error('Chart container is not defined'));
|
|
8
|
-
}
|
|
9
|
-
try {
|
|
10
|
-
const background = typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent';
|
|
11
|
-
const svg = toSVG(chartContainer, background);
|
|
12
|
-
const svgData = new XMLSerializer().serializeToString(svg.node);
|
|
13
|
-
const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));
|
|
14
|
-
svgToPng(svgDataUrl, {
|
|
15
|
-
width: opts.width || svg.width,
|
|
16
|
-
height: opts.height || svg.height,
|
|
17
|
-
scale: opts.scale
|
|
18
|
-
}).then(resolve).catch(reject);
|
|
19
|
-
} catch (err) {
|
|
20
|
-
return reject(err);
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
const SVG_STYLE_PROPERTIES = [
|
|
25
|
-
'display',
|
|
26
|
-
'fill',
|
|
27
|
-
'fill-opacity',
|
|
28
|
-
'opacity',
|
|
29
|
-
'stroke',
|
|
30
|
-
'stroke-width',
|
|
31
|
-
'transform'
|
|
32
|
-
];
|
|
33
|
-
const SVG_TEXT_STYLE_PROPERTIES = [
|
|
34
|
-
'font-family',
|
|
35
|
-
'font-size',
|
|
36
|
-
'font-weight',
|
|
37
|
-
'text-anchor'
|
|
38
|
-
];
|
|
39
|
-
function toSVG(chartContainer, background) {
|
|
40
|
-
const svg = chartContainer.querySelector('svg');
|
|
41
|
-
if (!svg) {
|
|
42
|
-
throw new Error('SVG not found');
|
|
43
|
-
}
|
|
44
|
-
const clonedSvg = d3Select(svg.cloneNode(true)).attr('width', null).attr('height', null).attr('viewBox', null);
|
|
45
|
-
const svgElements = svg.getElementsByTagName('*');
|
|
46
|
-
const clonedSvgElements = clonedSvg.node().getElementsByTagName('*');
|
|
47
|
-
for(let i = 0; i < svgElements.length; i++){
|
|
48
|
-
if (svgElements[i].tagName.toLowerCase() === 'text') {
|
|
49
|
-
copyStyle([
|
|
50
|
-
...SVG_STYLE_PROPERTIES,
|
|
51
|
-
...SVG_TEXT_STYLE_PROPERTIES
|
|
52
|
-
], svgElements[i], clonedSvgElements[i]);
|
|
53
|
-
} else {
|
|
54
|
-
copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();
|
|
58
|
-
const legendGroup = cloneLegendsToSVG(chartContainer, svgWidth, svgHeight);
|
|
59
|
-
const w1 = Math.max(svgWidth, legendGroup.width);
|
|
60
|
-
const h1 = svgHeight + legendGroup.height;
|
|
61
|
-
if (legendGroup.node) {
|
|
62
|
-
clonedSvg.append(()=>legendGroup.node);
|
|
63
|
-
}
|
|
64
|
-
clonedSvg.insert('rect', ':first-child').attr('x', 0).attr('y', 0).attr('width', w1).attr('height', h1).attr('fill', background);
|
|
65
|
-
clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`);
|
|
66
|
-
return {
|
|
67
|
-
node: clonedSvg.node(),
|
|
68
|
-
width: w1,
|
|
69
|
-
height: h1
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
const LEGEND_RECT_STYLE_PROPERTIES_MAP = {
|
|
73
|
-
'background-color': 'fill',
|
|
74
|
-
'border-color': 'stroke'
|
|
75
|
-
};
|
|
76
|
-
const LEGEND_TEXT_STYLE_PROPERTIES_MAP = {
|
|
77
|
-
color: 'fill',
|
|
78
|
-
'font-family': 'font-family',
|
|
79
|
-
'font-size': 'font-size',
|
|
80
|
-
'font-weight': 'font-weight',
|
|
81
|
-
opacity: 'opacity'
|
|
82
|
-
};
|
|
83
|
-
function cloneLegendsToSVG(chartContainer, svgWidth, svgHeight) {
|
|
84
|
-
const legendButtons = chartContainer.querySelectorAll(`
|
|
85
|
-
button.fui-legend__legend:not([data-overflowing]),
|
|
86
|
-
.fui-donut__legendContainer button.fui-MenuButton,
|
|
87
|
-
.fui-cart__legendContainer button.fui-MenuButton
|
|
88
|
-
`);
|
|
89
|
-
if (legendButtons.length === 0) {
|
|
90
|
-
return {
|
|
91
|
-
node: null,
|
|
92
|
-
width: 0,
|
|
93
|
-
height: 0
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
const legendGroup = d3Create('svg:g');
|
|
97
|
-
let legendX = 0;
|
|
98
|
-
let legendY = 8;
|
|
99
|
-
let legendLine = [];
|
|
100
|
-
const legendLines = [];
|
|
101
|
-
const legendLineWidths = [];
|
|
102
|
-
for(let i = 0; i < legendButtons.length; i++){
|
|
103
|
-
const { width: legendWidth } = legendButtons[i].getBoundingClientRect();
|
|
104
|
-
const legendItem = legendGroup.append('g');
|
|
105
|
-
legendLine.push(legendItem);
|
|
106
|
-
if (legendX + legendWidth > svgWidth && legendLine.length > 1) {
|
|
107
|
-
legendLine.pop();
|
|
108
|
-
legendLines.push(legendLine);
|
|
109
|
-
legendLineWidths.push(legendX);
|
|
110
|
-
legendLine = [
|
|
111
|
-
legendItem
|
|
112
|
-
];
|
|
113
|
-
legendX = 0;
|
|
114
|
-
legendY += 32;
|
|
115
|
-
}
|
|
116
|
-
let legendText;
|
|
117
|
-
let textOffset = 0;
|
|
118
|
-
if (!legendButtons[i].hasAttribute('data-overflow-menu')) {
|
|
119
|
-
const legendRect = legendButtons[i].querySelector('.fui-legend__rect');
|
|
120
|
-
legendText = legendButtons[i].querySelector('.fui-legend__text');
|
|
121
|
-
legendItem.append('rect').attr('x', legendX + 8).attr('y', svgHeight + legendY + 8).attr('width', 12).attr('height', 12).attr('stroke-width', 1).call((selection)=>copyStyle(LEGEND_RECT_STYLE_PROPERTIES_MAP, legendRect, selection.node()));
|
|
122
|
-
textOffset = 28;
|
|
123
|
-
} else {
|
|
124
|
-
legendText = legendButtons[i];
|
|
125
|
-
// eslint-disable-next-line no-console
|
|
126
|
-
console.log(legendText.textContent);
|
|
127
|
-
textOffset = 8;
|
|
128
|
-
}
|
|
129
|
-
legendItem.append('text').attr('x', legendX + textOffset).attr('y', svgHeight + legendY + 8).attr('dominant-baseline', 'hanging').text(legendText.textContent).call((selection)=>copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText, selection.node()));
|
|
130
|
-
legendX += legendWidth;
|
|
131
|
-
}
|
|
132
|
-
legendLines.push(legendLine);
|
|
133
|
-
legendLineWidths.push(legendX);
|
|
134
|
-
legendY += 32;
|
|
135
|
-
const centerLegends = true;
|
|
136
|
-
if (centerLegends) {
|
|
137
|
-
legendLines.forEach((ln, idx)=>{
|
|
138
|
-
const offsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);
|
|
139
|
-
ln.forEach((item)=>{
|
|
140
|
-
item.attr('transform', `translate(${offsetX}, 0)`);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
return {
|
|
145
|
-
node: legendGroup.node(),
|
|
146
|
-
width: Math.max(...legendLineWidths),
|
|
147
|
-
height: legendY
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
function svgToPng(svgDataUrl, opts = {}) {
|
|
151
|
-
return new Promise((resolve, reject)=>{
|
|
152
|
-
const scale = opts.scale || 1;
|
|
153
|
-
const w0 = opts.width || 300;
|
|
154
|
-
const h0 = opts.height || 150;
|
|
155
|
-
const w1 = scale * w0;
|
|
156
|
-
const h1 = scale * h0;
|
|
157
|
-
const canvas = document.createElement('canvas');
|
|
158
|
-
const img = new Image();
|
|
159
|
-
canvas.width = w1;
|
|
160
|
-
canvas.height = h1;
|
|
161
|
-
img.onload = function() {
|
|
162
|
-
const ctx = canvas.getContext('2d');
|
|
163
|
-
if (!ctx) {
|
|
164
|
-
return reject(new Error('Canvas context is null'));
|
|
165
|
-
}
|
|
166
|
-
ctx.clearRect(0, 0, w1, h1);
|
|
167
|
-
ctx.drawImage(img, 0, 0, w1, h1);
|
|
168
|
-
const imgData = canvas.toDataURL('image/png');
|
|
169
|
-
resolve(imgData);
|
|
170
|
-
};
|
|
171
|
-
img.onerror = function(err) {
|
|
172
|
-
reject(err);
|
|
173
|
-
};
|
|
174
|
-
img.src = svgDataUrl;
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
const hex2 = /^[\da-f]{2}$/i;
|
|
178
|
-
const hex4 = /^[\da-f]{4}$/i;
|
|
179
|
-
/**
|
|
180
|
-
* A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.
|
|
181
|
-
*
|
|
182
|
-
* Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}
|
|
183
|
-
*/ function unescapePonyfill(str) {
|
|
184
|
-
let result = '';
|
|
185
|
-
const length = str.length;
|
|
186
|
-
let index = 0;
|
|
187
|
-
let chr;
|
|
188
|
-
let part;
|
|
189
|
-
while(index < length){
|
|
190
|
-
chr = str.charAt(index++);
|
|
191
|
-
if (chr === '%') {
|
|
192
|
-
if (str.charAt(index) === 'u') {
|
|
193
|
-
part = str.slice(index + 1, index + 5);
|
|
194
|
-
if (hex4.exec(part)) {
|
|
195
|
-
result += String.fromCharCode(parseInt(part, 16));
|
|
196
|
-
index += 5;
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
} else {
|
|
200
|
-
part = str.slice(index, index + 2);
|
|
201
|
-
if (hex2.exec(part)) {
|
|
202
|
-
result += String.fromCharCode(parseInt(part, 16));
|
|
203
|
-
index += 2;
|
|
204
|
-
continue;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
result += chr;
|
|
209
|
-
}
|
|
210
|
-
return result;
|
|
211
|
-
}
|
|
212
|
-
function copyStyle(properties, fromEl, toEl) {
|
|
213
|
-
const styles = getComputedStyle(fromEl);
|
|
214
|
-
if (Array.isArray(properties)) {
|
|
215
|
-
properties.forEach((prop)=>{
|
|
216
|
-
d3Select(toEl).style(prop, styles.getPropertyValue(prop));
|
|
217
|
-
});
|
|
218
|
-
} else {
|
|
219
|
-
Object.entries(properties).forEach(([fromProp, toProp])=>{
|
|
220
|
-
d3Select(toEl).style(toProp, styles.getPropertyValue(fromProp));
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/DeclarativeChart/imageExporter.ts"],"sourcesContent":["'use client';\n\nimport { create as d3Create, select as d3Select, Selection } from 'd3-selection';\nimport { resolveCSSVariables } from '../../utilities/index';\n\n/**\n * {@docCategory DeclarativeChart}\n */\nexport interface ImageExportOptions {\n width?: number;\n height?: number;\n scale?: number;\n background?: string;\n}\n\nexport function toImage(chartContainer?: HTMLElement | null, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n if (!chartContainer) {\n return reject(new Error('Chart container is not defined'));\n }\n\n try {\n const background =\n typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent';\n const svg = toSVG(chartContainer, background);\n\n const svgData = new XMLSerializer().serializeToString(svg.node);\n const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));\n\n svgToPng(svgDataUrl, {\n width: opts.width || svg.width,\n height: opts.height || svg.height,\n scale: opts.scale,\n })\n .then(resolve)\n .catch(reject);\n } catch (err) {\n return reject(err);\n }\n });\n}\n\nconst SVG_STYLE_PROPERTIES = ['display', 'fill', 'fill-opacity', 'opacity', 'stroke', 'stroke-width', 'transform'];\nconst SVG_TEXT_STYLE_PROPERTIES = ['font-family', 'font-size', 'font-weight', 'text-anchor'];\n\nfunction toSVG(chartContainer: HTMLElement, background: string) {\n const svg = chartContainer.querySelector<SVGSVGElement>('svg');\n if (!svg) {\n throw new Error('SVG not found');\n }\n\n const clonedSvg = d3Select(svg.cloneNode(true) as SVGSVGElement)\n .attr('width', null)\n .attr('height', null)\n .attr('viewBox', null);\n const svgElements = svg.getElementsByTagName('*');\n const clonedSvgElements = clonedSvg.node()!.getElementsByTagName('*');\n\n for (let i = 0; i < svgElements.length; i++) {\n if (svgElements[i].tagName.toLowerCase() === 'text') {\n copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], svgElements[i], clonedSvgElements[i]);\n } else {\n copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);\n }\n }\n\n const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();\n const legendGroup = cloneLegendsToSVG(chartContainer, svgWidth, svgHeight);\n const w1 = Math.max(svgWidth, legendGroup.width);\n const h1 = svgHeight + legendGroup.height;\n\n if (legendGroup.node) {\n clonedSvg.append(() => legendGroup.node);\n }\n clonedSvg\n .insert('rect', ':first-child')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', w1)\n .attr('height', h1)\n .attr('fill', background);\n clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`);\n\n return {\n node: clonedSvg.node()!,\n width: w1,\n height: h1,\n };\n}\n\nconst LEGEND_RECT_STYLE_PROPERTIES_MAP = {\n 'background-color': 'fill',\n 'border-color': 'stroke',\n};\nconst LEGEND_TEXT_STYLE_PROPERTIES_MAP = {\n color: 'fill',\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n opacity: 'opacity',\n};\n\nfunction cloneLegendsToSVG(chartContainer: HTMLElement, svgWidth: number, svgHeight: number) {\n const legendButtons = chartContainer.querySelectorAll<HTMLElement>(`\n button.fui-legend__legend:not([data-overflowing]),\n .fui-donut__legendContainer button.fui-MenuButton,\n .fui-cart__legendContainer button.fui-MenuButton\n `);\n if (legendButtons.length === 0) {\n return {\n node: null,\n width: 0,\n height: 0,\n };\n }\n\n const legendGroup = d3Create<SVGGElement>('svg:g');\n let legendX = 0;\n let legendY = 8;\n let legendLine: Selection<SVGGElement, unknown, null, undefined>[] = [];\n const legendLines: (typeof legendLine)[] = [];\n const legendLineWidths: number[] = [];\n\n for (let i = 0; i < legendButtons.length; i++) {\n const { width: legendWidth } = legendButtons[i].getBoundingClientRect();\n const legendItem = legendGroup.append('g');\n\n legendLine.push(legendItem);\n if (legendX + legendWidth > svgWidth && legendLine.length > 1) {\n legendLine.pop();\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n\n legendLine = [legendItem];\n legendX = 0;\n legendY += 32;\n }\n\n let legendText: HTMLDivElement | HTMLButtonElement | null;\n let textOffset = 0;\n\n if (!legendButtons[i].hasAttribute('data-overflow-menu')) {\n const legendRect = legendButtons[i].querySelector<HTMLDivElement>('.fui-legend__rect');\n\n legendText = legendButtons[i].querySelector<HTMLDivElement>('.fui-legend__text');\n legendItem\n .append('rect')\n .attr('x', legendX + 8)\n .attr('y', svgHeight + legendY + 8)\n .attr('width', 12)\n .attr('height', 12)\n .attr('stroke-width', 1)\n .call(selection => copyStyle(LEGEND_RECT_STYLE_PROPERTIES_MAP, legendRect!, selection.node()!));\n textOffset = 28;\n } else {\n legendText = legendButtons[i] as HTMLButtonElement;\n // eslint-disable-next-line no-console\n console.log(legendText!.textContent);\n textOffset = 8;\n }\n\n legendItem\n .append('text')\n .attr('x', legendX + textOffset)\n .attr('y', svgHeight + legendY + 8)\n .attr('dominant-baseline', 'hanging')\n .text(legendText!.textContent)\n .call(selection => copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText!, selection.node()!));\n legendX += legendWidth;\n }\n\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n legendY += 32;\n\n const centerLegends = true;\n if (centerLegends) {\n legendLines.forEach((ln, idx) => {\n const offsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);\n ln.forEach(item => {\n item.attr('transform', `translate(${offsetX}, 0)`);\n });\n });\n }\n\n return {\n node: legendGroup.node(),\n width: Math.max(...legendLineWidths),\n height: legendY,\n };\n}\n\nfunction svgToPng(svgDataUrl: string, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const scale = opts.scale || 1;\n const w0 = opts.width || 300;\n const h0 = opts.height || 150;\n const w1 = scale * w0;\n const h1 = scale * h0;\n\n const canvas = document.createElement('canvas');\n const img = new Image();\n\n canvas.width = w1;\n canvas.height = h1;\n\n img.onload = function () {\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return reject(new Error('Canvas context is null'));\n }\n\n ctx.clearRect(0, 0, w1, h1);\n ctx.drawImage(img, 0, 0, w1, h1);\n\n const imgData = canvas.toDataURL('image/png');\n resolve(imgData);\n };\n\n img.onerror = function (err) {\n reject(err);\n };\n\n img.src = svgDataUrl;\n });\n}\n\nconst hex2 = /^[\\da-f]{2}$/i;\nconst hex4 = /^[\\da-f]{4}$/i;\n\n/**\n * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.\n *\n * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}\n */\nfunction unescapePonyfill(str: string) {\n let result = '';\n const length = str.length;\n let index = 0;\n let chr;\n let part;\n while (index < length) {\n chr = str.charAt(index++);\n if (chr === '%') {\n if (str.charAt(index) === 'u') {\n part = str.slice(index + 1, index + 5);\n if (hex4.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 5;\n continue;\n }\n } else {\n part = str.slice(index, index + 2);\n if (hex2.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 2;\n continue;\n }\n }\n }\n result += chr;\n }\n return result;\n}\n\nfunction copyStyle(properties: string[] | Record<string, string>, fromEl: Element, toEl: Element) {\n const styles = getComputedStyle(fromEl);\n if (Array.isArray(properties)) {\n properties.forEach(prop => {\n d3Select(toEl).style(prop, styles.getPropertyValue(prop));\n });\n } else {\n Object.entries(properties).forEach(([fromProp, toProp]) => {\n d3Select(toEl).style(toProp, styles.getPropertyValue(fromProp));\n });\n }\n}\n"],"names":["create","d3Create","select","d3Select","resolveCSSVariables","toImage","chartContainer","opts","Promise","resolve","reject","Error","background","svg","toSVG","svgData","XMLSerializer","serializeToString","node","svgDataUrl","btoa","unescapePonyfill","encodeURIComponent","svgToPng","width","height","scale","then","catch","err","SVG_STYLE_PROPERTIES","SVG_TEXT_STYLE_PROPERTIES","querySelector","clonedSvg","cloneNode","attr","svgElements","getElementsByTagName","clonedSvgElements","i","length","tagName","toLowerCase","copyStyle","svgWidth","svgHeight","getBoundingClientRect","legendGroup","cloneLegendsToSVG","w1","Math","max","h1","append","insert","LEGEND_RECT_STYLE_PROPERTIES_MAP","LEGEND_TEXT_STYLE_PROPERTIES_MAP","color","opacity","legendButtons","querySelectorAll","legendX","legendY","legendLine","legendLines","legendLineWidths","legendWidth","legendItem","push","pop","legendText","textOffset","hasAttribute","legendRect","call","selection","console","log","textContent","text","centerLegends","forEach","ln","idx","offsetX","item","w0","h0","canvas","document","createElement","img","Image","onload","ctx","getContext","clearRect","drawImage","imgData","toDataURL","onerror","src","hex2","hex4","str","result","index","chr","part","charAt","slice","exec","String","fromCharCode","parseInt","properties","fromEl","toEl","styles","getComputedStyle","Array","isArray","prop","style","getPropertyValue","Object","entries","fromProp","toProp"],"mappings":"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"}
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
"use strict";
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
Object.defineProperty(exports, "toImage", {
|
|
7
|
-
enumerable: true,
|
|
8
|
-
get: function() {
|
|
9
|
-
return toImage;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
const _d3selection = require("d3-selection");
|
|
13
|
-
const _index = require("../../utilities/index");
|
|
14
|
-
function toImage(chartContainer, opts = {}) {
|
|
15
|
-
return new Promise((resolve, reject)=>{
|
|
16
|
-
if (!chartContainer) {
|
|
17
|
-
return reject(new Error('Chart container is not defined'));
|
|
18
|
-
}
|
|
19
|
-
try {
|
|
20
|
-
const background = typeof opts.background === 'string' ? (0, _index.resolveCSSVariables)(chartContainer, opts.background) : 'transparent';
|
|
21
|
-
const svg = toSVG(chartContainer, background);
|
|
22
|
-
const svgData = new XMLSerializer().serializeToString(svg.node);
|
|
23
|
-
const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));
|
|
24
|
-
svgToPng(svgDataUrl, {
|
|
25
|
-
width: opts.width || svg.width,
|
|
26
|
-
height: opts.height || svg.height,
|
|
27
|
-
scale: opts.scale
|
|
28
|
-
}).then(resolve).catch(reject);
|
|
29
|
-
} catch (err) {
|
|
30
|
-
return reject(err);
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
const SVG_STYLE_PROPERTIES = [
|
|
35
|
-
'display',
|
|
36
|
-
'fill',
|
|
37
|
-
'fill-opacity',
|
|
38
|
-
'opacity',
|
|
39
|
-
'stroke',
|
|
40
|
-
'stroke-width',
|
|
41
|
-
'transform'
|
|
42
|
-
];
|
|
43
|
-
const SVG_TEXT_STYLE_PROPERTIES = [
|
|
44
|
-
'font-family',
|
|
45
|
-
'font-size',
|
|
46
|
-
'font-weight',
|
|
47
|
-
'text-anchor'
|
|
48
|
-
];
|
|
49
|
-
function toSVG(chartContainer, background) {
|
|
50
|
-
const svg = chartContainer.querySelector('svg');
|
|
51
|
-
if (!svg) {
|
|
52
|
-
throw new Error('SVG not found');
|
|
53
|
-
}
|
|
54
|
-
const clonedSvg = (0, _d3selection.select)(svg.cloneNode(true)).attr('width', null).attr('height', null).attr('viewBox', null);
|
|
55
|
-
const svgElements = svg.getElementsByTagName('*');
|
|
56
|
-
const clonedSvgElements = clonedSvg.node().getElementsByTagName('*');
|
|
57
|
-
for(let i = 0; i < svgElements.length; i++){
|
|
58
|
-
if (svgElements[i].tagName.toLowerCase() === 'text') {
|
|
59
|
-
copyStyle([
|
|
60
|
-
...SVG_STYLE_PROPERTIES,
|
|
61
|
-
...SVG_TEXT_STYLE_PROPERTIES
|
|
62
|
-
], svgElements[i], clonedSvgElements[i]);
|
|
63
|
-
} else {
|
|
64
|
-
copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();
|
|
68
|
-
const legendGroup = cloneLegendsToSVG(chartContainer, svgWidth, svgHeight);
|
|
69
|
-
const w1 = Math.max(svgWidth, legendGroup.width);
|
|
70
|
-
const h1 = svgHeight + legendGroup.height;
|
|
71
|
-
if (legendGroup.node) {
|
|
72
|
-
clonedSvg.append(()=>legendGroup.node);
|
|
73
|
-
}
|
|
74
|
-
clonedSvg.insert('rect', ':first-child').attr('x', 0).attr('y', 0).attr('width', w1).attr('height', h1).attr('fill', background);
|
|
75
|
-
clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`);
|
|
76
|
-
return {
|
|
77
|
-
node: clonedSvg.node(),
|
|
78
|
-
width: w1,
|
|
79
|
-
height: h1
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
const LEGEND_RECT_STYLE_PROPERTIES_MAP = {
|
|
83
|
-
'background-color': 'fill',
|
|
84
|
-
'border-color': 'stroke'
|
|
85
|
-
};
|
|
86
|
-
const LEGEND_TEXT_STYLE_PROPERTIES_MAP = {
|
|
87
|
-
color: 'fill',
|
|
88
|
-
'font-family': 'font-family',
|
|
89
|
-
'font-size': 'font-size',
|
|
90
|
-
'font-weight': 'font-weight',
|
|
91
|
-
opacity: 'opacity'
|
|
92
|
-
};
|
|
93
|
-
function cloneLegendsToSVG(chartContainer, svgWidth, svgHeight) {
|
|
94
|
-
const legendButtons = chartContainer.querySelectorAll(`
|
|
95
|
-
button.fui-legend__legend:not([data-overflowing]),
|
|
96
|
-
.fui-donut__legendContainer button.fui-MenuButton,
|
|
97
|
-
.fui-cart__legendContainer button.fui-MenuButton
|
|
98
|
-
`);
|
|
99
|
-
if (legendButtons.length === 0) {
|
|
100
|
-
return {
|
|
101
|
-
node: null,
|
|
102
|
-
width: 0,
|
|
103
|
-
height: 0
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
const legendGroup = (0, _d3selection.create)('svg:g');
|
|
107
|
-
let legendX = 0;
|
|
108
|
-
let legendY = 8;
|
|
109
|
-
let legendLine = [];
|
|
110
|
-
const legendLines = [];
|
|
111
|
-
const legendLineWidths = [];
|
|
112
|
-
for(let i = 0; i < legendButtons.length; i++){
|
|
113
|
-
const { width: legendWidth } = legendButtons[i].getBoundingClientRect();
|
|
114
|
-
const legendItem = legendGroup.append('g');
|
|
115
|
-
legendLine.push(legendItem);
|
|
116
|
-
if (legendX + legendWidth > svgWidth && legendLine.length > 1) {
|
|
117
|
-
legendLine.pop();
|
|
118
|
-
legendLines.push(legendLine);
|
|
119
|
-
legendLineWidths.push(legendX);
|
|
120
|
-
legendLine = [
|
|
121
|
-
legendItem
|
|
122
|
-
];
|
|
123
|
-
legendX = 0;
|
|
124
|
-
legendY += 32;
|
|
125
|
-
}
|
|
126
|
-
let legendText;
|
|
127
|
-
let textOffset = 0;
|
|
128
|
-
if (!legendButtons[i].hasAttribute('data-overflow-menu')) {
|
|
129
|
-
const legendRect = legendButtons[i].querySelector('.fui-legend__rect');
|
|
130
|
-
legendText = legendButtons[i].querySelector('.fui-legend__text');
|
|
131
|
-
legendItem.append('rect').attr('x', legendX + 8).attr('y', svgHeight + legendY + 8).attr('width', 12).attr('height', 12).attr('stroke-width', 1).call((selection)=>copyStyle(LEGEND_RECT_STYLE_PROPERTIES_MAP, legendRect, selection.node()));
|
|
132
|
-
textOffset = 28;
|
|
133
|
-
} else {
|
|
134
|
-
legendText = legendButtons[i];
|
|
135
|
-
// eslint-disable-next-line no-console
|
|
136
|
-
console.log(legendText.textContent);
|
|
137
|
-
textOffset = 8;
|
|
138
|
-
}
|
|
139
|
-
legendItem.append('text').attr('x', legendX + textOffset).attr('y', svgHeight + legendY + 8).attr('dominant-baseline', 'hanging').text(legendText.textContent).call((selection)=>copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText, selection.node()));
|
|
140
|
-
legendX += legendWidth;
|
|
141
|
-
}
|
|
142
|
-
legendLines.push(legendLine);
|
|
143
|
-
legendLineWidths.push(legendX);
|
|
144
|
-
legendY += 32;
|
|
145
|
-
const centerLegends = true;
|
|
146
|
-
if (centerLegends) {
|
|
147
|
-
legendLines.forEach((ln, idx)=>{
|
|
148
|
-
const offsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);
|
|
149
|
-
ln.forEach((item)=>{
|
|
150
|
-
item.attr('transform', `translate(${offsetX}, 0)`);
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
return {
|
|
155
|
-
node: legendGroup.node(),
|
|
156
|
-
width: Math.max(...legendLineWidths),
|
|
157
|
-
height: legendY
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
function svgToPng(svgDataUrl, opts = {}) {
|
|
161
|
-
return new Promise((resolve, reject)=>{
|
|
162
|
-
const scale = opts.scale || 1;
|
|
163
|
-
const w0 = opts.width || 300;
|
|
164
|
-
const h0 = opts.height || 150;
|
|
165
|
-
const w1 = scale * w0;
|
|
166
|
-
const h1 = scale * h0;
|
|
167
|
-
const canvas = document.createElement('canvas');
|
|
168
|
-
const img = new Image();
|
|
169
|
-
canvas.width = w1;
|
|
170
|
-
canvas.height = h1;
|
|
171
|
-
img.onload = function() {
|
|
172
|
-
const ctx = canvas.getContext('2d');
|
|
173
|
-
if (!ctx) {
|
|
174
|
-
return reject(new Error('Canvas context is null'));
|
|
175
|
-
}
|
|
176
|
-
ctx.clearRect(0, 0, w1, h1);
|
|
177
|
-
ctx.drawImage(img, 0, 0, w1, h1);
|
|
178
|
-
const imgData = canvas.toDataURL('image/png');
|
|
179
|
-
resolve(imgData);
|
|
180
|
-
};
|
|
181
|
-
img.onerror = function(err) {
|
|
182
|
-
reject(err);
|
|
183
|
-
};
|
|
184
|
-
img.src = svgDataUrl;
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
const hex2 = /^[\da-f]{2}$/i;
|
|
188
|
-
const hex4 = /^[\da-f]{4}$/i;
|
|
189
|
-
/**
|
|
190
|
-
* A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.
|
|
191
|
-
*
|
|
192
|
-
* Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}
|
|
193
|
-
*/ function unescapePonyfill(str) {
|
|
194
|
-
let result = '';
|
|
195
|
-
const length = str.length;
|
|
196
|
-
let index = 0;
|
|
197
|
-
let chr;
|
|
198
|
-
let part;
|
|
199
|
-
while(index < length){
|
|
200
|
-
chr = str.charAt(index++);
|
|
201
|
-
if (chr === '%') {
|
|
202
|
-
if (str.charAt(index) === 'u') {
|
|
203
|
-
part = str.slice(index + 1, index + 5);
|
|
204
|
-
if (hex4.exec(part)) {
|
|
205
|
-
result += String.fromCharCode(parseInt(part, 16));
|
|
206
|
-
index += 5;
|
|
207
|
-
continue;
|
|
208
|
-
}
|
|
209
|
-
} else {
|
|
210
|
-
part = str.slice(index, index + 2);
|
|
211
|
-
if (hex2.exec(part)) {
|
|
212
|
-
result += String.fromCharCode(parseInt(part, 16));
|
|
213
|
-
index += 2;
|
|
214
|
-
continue;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
result += chr;
|
|
219
|
-
}
|
|
220
|
-
return result;
|
|
221
|
-
}
|
|
222
|
-
function copyStyle(properties, fromEl, toEl) {
|
|
223
|
-
const styles = getComputedStyle(fromEl);
|
|
224
|
-
if (Array.isArray(properties)) {
|
|
225
|
-
properties.forEach((prop)=>{
|
|
226
|
-
(0, _d3selection.select)(toEl).style(prop, styles.getPropertyValue(prop));
|
|
227
|
-
});
|
|
228
|
-
} else {
|
|
229
|
-
Object.entries(properties).forEach(([fromProp, toProp])=>{
|
|
230
|
-
(0, _d3selection.select)(toEl).style(toProp, styles.getPropertyValue(fromProp));
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/DeclarativeChart/imageExporter.ts"],"sourcesContent":["'use client';\n\nimport { create as d3Create, select as d3Select, Selection } from 'd3-selection';\nimport { resolveCSSVariables } from '../../utilities/index';\n\n/**\n * {@docCategory DeclarativeChart}\n */\nexport interface ImageExportOptions {\n width?: number;\n height?: number;\n scale?: number;\n background?: string;\n}\n\nexport function toImage(chartContainer?: HTMLElement | null, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n if (!chartContainer) {\n return reject(new Error('Chart container is not defined'));\n }\n\n try {\n const background =\n typeof opts.background === 'string' ? resolveCSSVariables(chartContainer, opts.background) : 'transparent';\n const svg = toSVG(chartContainer, background);\n\n const svgData = new XMLSerializer().serializeToString(svg.node);\n const svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));\n\n svgToPng(svgDataUrl, {\n width: opts.width || svg.width,\n height: opts.height || svg.height,\n scale: opts.scale,\n })\n .then(resolve)\n .catch(reject);\n } catch (err) {\n return reject(err);\n }\n });\n}\n\nconst SVG_STYLE_PROPERTIES = ['display', 'fill', 'fill-opacity', 'opacity', 'stroke', 'stroke-width', 'transform'];\nconst SVG_TEXT_STYLE_PROPERTIES = ['font-family', 'font-size', 'font-weight', 'text-anchor'];\n\nfunction toSVG(chartContainer: HTMLElement, background: string) {\n const svg = chartContainer.querySelector<SVGSVGElement>('svg');\n if (!svg) {\n throw new Error('SVG not found');\n }\n\n const clonedSvg = d3Select(svg.cloneNode(true) as SVGSVGElement)\n .attr('width', null)\n .attr('height', null)\n .attr('viewBox', null);\n const svgElements = svg.getElementsByTagName('*');\n const clonedSvgElements = clonedSvg.node()!.getElementsByTagName('*');\n\n for (let i = 0; i < svgElements.length; i++) {\n if (svgElements[i].tagName.toLowerCase() === 'text') {\n copyStyle([...SVG_STYLE_PROPERTIES, ...SVG_TEXT_STYLE_PROPERTIES], svgElements[i], clonedSvgElements[i]);\n } else {\n copyStyle(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);\n }\n }\n\n const { width: svgWidth, height: svgHeight } = svg.getBoundingClientRect();\n const legendGroup = cloneLegendsToSVG(chartContainer, svgWidth, svgHeight);\n const w1 = Math.max(svgWidth, legendGroup.width);\n const h1 = svgHeight + legendGroup.height;\n\n if (legendGroup.node) {\n clonedSvg.append(() => legendGroup.node);\n }\n clonedSvg\n .insert('rect', ':first-child')\n .attr('x', 0)\n .attr('y', 0)\n .attr('width', w1)\n .attr('height', h1)\n .attr('fill', background);\n clonedSvg.attr('width', w1).attr('height', h1).attr('viewBox', `0 0 ${w1} ${h1}`);\n\n return {\n node: clonedSvg.node()!,\n width: w1,\n height: h1,\n };\n}\n\nconst LEGEND_RECT_STYLE_PROPERTIES_MAP = {\n 'background-color': 'fill',\n 'border-color': 'stroke',\n};\nconst LEGEND_TEXT_STYLE_PROPERTIES_MAP = {\n color: 'fill',\n 'font-family': 'font-family',\n 'font-size': 'font-size',\n 'font-weight': 'font-weight',\n opacity: 'opacity',\n};\n\nfunction cloneLegendsToSVG(chartContainer: HTMLElement, svgWidth: number, svgHeight: number) {\n const legendButtons = chartContainer.querySelectorAll<HTMLElement>(`\n button.fui-legend__legend:not([data-overflowing]),\n .fui-donut__legendContainer button.fui-MenuButton,\n .fui-cart__legendContainer button.fui-MenuButton\n `);\n if (legendButtons.length === 0) {\n return {\n node: null,\n width: 0,\n height: 0,\n };\n }\n\n const legendGroup = d3Create<SVGGElement>('svg:g');\n let legendX = 0;\n let legendY = 8;\n let legendLine: Selection<SVGGElement, unknown, null, undefined>[] = [];\n const legendLines: (typeof legendLine)[] = [];\n const legendLineWidths: number[] = [];\n\n for (let i = 0; i < legendButtons.length; i++) {\n const { width: legendWidth } = legendButtons[i].getBoundingClientRect();\n const legendItem = legendGroup.append('g');\n\n legendLine.push(legendItem);\n if (legendX + legendWidth > svgWidth && legendLine.length > 1) {\n legendLine.pop();\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n\n legendLine = [legendItem];\n legendX = 0;\n legendY += 32;\n }\n\n let legendText: HTMLDivElement | HTMLButtonElement | null;\n let textOffset = 0;\n\n if (!legendButtons[i].hasAttribute('data-overflow-menu')) {\n const legendRect = legendButtons[i].querySelector<HTMLDivElement>('.fui-legend__rect');\n\n legendText = legendButtons[i].querySelector<HTMLDivElement>('.fui-legend__text');\n legendItem\n .append('rect')\n .attr('x', legendX + 8)\n .attr('y', svgHeight + legendY + 8)\n .attr('width', 12)\n .attr('height', 12)\n .attr('stroke-width', 1)\n .call(selection => copyStyle(LEGEND_RECT_STYLE_PROPERTIES_MAP, legendRect!, selection.node()!));\n textOffset = 28;\n } else {\n legendText = legendButtons[i] as HTMLButtonElement;\n // eslint-disable-next-line no-console\n console.log(legendText!.textContent);\n textOffset = 8;\n }\n\n legendItem\n .append('text')\n .attr('x', legendX + textOffset)\n .attr('y', svgHeight + legendY + 8)\n .attr('dominant-baseline', 'hanging')\n .text(legendText!.textContent)\n .call(selection => copyStyle(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText!, selection.node()!));\n legendX += legendWidth;\n }\n\n legendLines.push(legendLine);\n legendLineWidths.push(legendX);\n legendY += 32;\n\n const centerLegends = true;\n if (centerLegends) {\n legendLines.forEach((ln, idx) => {\n const offsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);\n ln.forEach(item => {\n item.attr('transform', `translate(${offsetX}, 0)`);\n });\n });\n }\n\n return {\n node: legendGroup.node(),\n width: Math.max(...legendLineWidths),\n height: legendY,\n };\n}\n\nfunction svgToPng(svgDataUrl: string, opts: ImageExportOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const scale = opts.scale || 1;\n const w0 = opts.width || 300;\n const h0 = opts.height || 150;\n const w1 = scale * w0;\n const h1 = scale * h0;\n\n const canvas = document.createElement('canvas');\n const img = new Image();\n\n canvas.width = w1;\n canvas.height = h1;\n\n img.onload = function () {\n const ctx = canvas.getContext('2d');\n if (!ctx) {\n return reject(new Error('Canvas context is null'));\n }\n\n ctx.clearRect(0, 0, w1, h1);\n ctx.drawImage(img, 0, 0, w1, h1);\n\n const imgData = canvas.toDataURL('image/png');\n resolve(imgData);\n };\n\n img.onerror = function (err) {\n reject(err);\n };\n\n img.src = svgDataUrl;\n });\n}\n\nconst hex2 = /^[\\da-f]{2}$/i;\nconst hex4 = /^[\\da-f]{4}$/i;\n\n/**\n * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.\n *\n * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}\n */\nfunction unescapePonyfill(str: string) {\n let result = '';\n const length = str.length;\n let index = 0;\n let chr;\n let part;\n while (index < length) {\n chr = str.charAt(index++);\n if (chr === '%') {\n if (str.charAt(index) === 'u') {\n part = str.slice(index + 1, index + 5);\n if (hex4.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 5;\n continue;\n }\n } else {\n part = str.slice(index, index + 2);\n if (hex2.exec(part)) {\n result += String.fromCharCode(parseInt(part, 16));\n index += 2;\n continue;\n }\n }\n }\n result += chr;\n }\n return result;\n}\n\nfunction copyStyle(properties: string[] | Record<string, string>, fromEl: Element, toEl: Element) {\n const styles = getComputedStyle(fromEl);\n if (Array.isArray(properties)) {\n properties.forEach(prop => {\n d3Select(toEl).style(prop, styles.getPropertyValue(prop));\n });\n } else {\n Object.entries(properties).forEach(([fromProp, toProp]) => {\n d3Select(toEl).style(toProp, styles.getPropertyValue(fromProp));\n });\n }\n}\n"],"names":["create","d3Create","select","d3Select","resolveCSSVariables","toImage","chartContainer","opts","Promise","resolve","reject","Error","background","svg","toSVG","svgData","XMLSerializer","serializeToString","node","svgDataUrl","btoa","unescapePonyfill","encodeURIComponent","svgToPng","width","height","scale","then","catch","err","SVG_STYLE_PROPERTIES","SVG_TEXT_STYLE_PROPERTIES","querySelector","clonedSvg","cloneNode","attr","svgElements","getElementsByTagName","clonedSvgElements","i","length","tagName","toLowerCase","copyStyle","svgWidth","svgHeight","getBoundingClientRect","legendGroup","cloneLegendsToSVG","w1","Math","max","h1","append","insert","LEGEND_RECT_STYLE_PROPERTIES_MAP","LEGEND_TEXT_STYLE_PROPERTIES_MAP","color","opacity","legendButtons","querySelectorAll","legendX","legendY","legendLine","legendLines","legendLineWidths","legendWidth","legendItem","push","pop","legendText","textOffset","hasAttribute","legendRect","call","selection","console","log","textContent","text","centerLegends","forEach","ln","idx","offsetX","item","w0","h0","canvas","document","createElement","img","Image","onload","ctx","getContext","clearRect","drawImage","imgData","toDataURL","onerror","src","hex2","hex4","str","result","index","chr","part","charAt","slice","exec","String","fromCharCode","parseInt","properties","fromEl","toEl","styles","getComputedStyle","Array","isArray","prop","style","getPropertyValue","Object","entries","fromProp","toProp"],"mappings":"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"}
|