@mui/x-charts-pro 8.11.1 → 8.11.3
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 +181 -0
- package/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/ChartZoomSlider/internals/ChartAxisZoomSliderThumb.js +2 -2
- package/FunnelChart/FunnelPlot.js +2 -2
- package/FunnelChart/funnelAxisPlugin/computeAxisValue.js +1 -1
- package/FunnelChart/useFunnelChartProps.js +4 -3
- package/Heatmap/Heatmap.js +2 -1
- package/PieChartPro/PieChartPro.js +1 -0
- package/SankeyChart/useSankeyChartProps.js +4 -3
- package/esm/ChartDataProviderPro/ChartDataProviderPro.js +1 -1
- package/esm/ChartZoomSlider/internals/ChartAxisZoomSliderThumb.js +2 -2
- package/esm/FunnelChart/FunnelPlot.js +3 -3
- package/esm/FunnelChart/funnelAxisPlugin/computeAxisValue.js +1 -1
- package/esm/FunnelChart/useFunnelChartProps.js +4 -3
- package/esm/Heatmap/Heatmap.js +2 -1
- package/esm/PieChartPro/PieChartPro.js +1 -0
- package/esm/SankeyChart/useSankeyChartProps.js +4 -3
- package/esm/index.js +1 -1
- package/esm/internals/material/components/BasePopper.js +2 -2
- package/esm/internals/plugins/useChartProExport/common.d.ts +5 -1
- package/esm/internals/plugins/useChartProExport/common.js +13 -0
- package/esm/internals/plugins/useChartProExport/exportImage.d.ts +1 -1
- package/esm/internals/plugins/useChartProExport/exportImage.js +23 -17
- package/esm/internals/plugins/useChartProExport/print.js +2 -3
- package/esm/internals/plugins/useChartProExport/useChartProExport.js +4 -2
- package/index.js +1 -1
- package/internals/material/components/BasePopper.js +2 -2
- package/internals/plugins/useChartProExport/common.d.ts +5 -1
- package/internals/plugins/useChartProExport/common.js +14 -0
- package/internals/plugins/useChartProExport/exportImage.d.ts +1 -1
- package/internals/plugins/useChartProExport/exportImage.js +22 -16
- package/internals/plugins/useChartProExport/print.js +2 -3
- package/internals/plugins/useChartProExport/useChartProExport.js +4 -2
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,187 @@
|
|
|
5
5
|
All notable changes to this project will be documented in this file.
|
|
6
6
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
7
7
|
|
|
8
|
+
## 8.11.3
|
|
9
|
+
|
|
10
|
+
_Sep 16, 2025_
|
|
11
|
+
|
|
12
|
+
We'd like to extend a big thank you to the 11 contributors who made this release possible. Here are some highlights ✨:
|
|
13
|
+
|
|
14
|
+
- 🐞 Bugfixes
|
|
15
|
+
- 📚 Documentation improvements
|
|
16
|
+
|
|
17
|
+
Special thanks go out to the community members for their valuable contributions:
|
|
18
|
+
@sai6855
|
|
19
|
+
|
|
20
|
+
The following are all team members who have contributed to this release:
|
|
21
|
+
@alexfauquette, @bernardobelchior, @brijeshb42, @cherniavskii, @flaviendelangle, @Janpot, @JCQuintas, @LukasTy, @rita-codes, @siriwatknp
|
|
22
|
+
|
|
23
|
+
### Data Grid
|
|
24
|
+
|
|
25
|
+
#### `@mui/x-data-grid@8.11.3`
|
|
26
|
+
|
|
27
|
+
- [DataGrid] Fix numeric font size not being applied (#19552) @cherniavskii
|
|
28
|
+
- [DataGrid] Improve `operator` types to display literal values (#19529) @siriwatknp
|
|
29
|
+
|
|
30
|
+
#### `@mui/x-data-grid-pro@8.11.3` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
31
|
+
|
|
32
|
+
Same changes as in `@mui/x-data-grid@8.11.3`.
|
|
33
|
+
|
|
34
|
+
#### `@mui/x-data-grid-premium@8.11.3` [](https://mui.com/r/x-premium-svg-link "Premium plan")
|
|
35
|
+
|
|
36
|
+
Same changes as in `@mui/x-data-grid-pro@8.11.3`.
|
|
37
|
+
|
|
38
|
+
### Date and Time Pickers
|
|
39
|
+
|
|
40
|
+
#### `@mui/x-date-pickers@8.11.3`
|
|
41
|
+
|
|
42
|
+
- [pickers] Refactor `slots` and `slotProps` propagation strategy (#18867) @LukasTy
|
|
43
|
+
|
|
44
|
+
#### `@mui/x-date-pickers-pro@8.11.3` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
45
|
+
|
|
46
|
+
Same changes as in `@mui/x-date-pickers@8.11.3`.
|
|
47
|
+
|
|
48
|
+
### Charts
|
|
49
|
+
|
|
50
|
+
#### `@mui/x-charts@8.11.3`
|
|
51
|
+
|
|
52
|
+
- [charts] Add `inline-` piecewise legend options (#19382) @JCQuintas
|
|
53
|
+
- [charts] Add bar gradient example (#19174) @bernardobelchior
|
|
54
|
+
- [charts] Ignore empty tick labels in label overlap computation (#19547) @alexfauquette
|
|
55
|
+
- [charts] Rename `isBandScale` to `isDiscreteScale` (#19514) @bernardobelchior
|
|
56
|
+
- [charts] Fix legend position affecting toolbar's position (#19257) @sai6855
|
|
57
|
+
|
|
58
|
+
#### `@mui/x-charts-pro@8.11.3` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
59
|
+
|
|
60
|
+
Same changes as in `@mui/x-charts@8.11.3`, plus:
|
|
61
|
+
|
|
62
|
+
- [charts-pro] Add chart title and caption to export demo (#19524) @bernardobelchior
|
|
63
|
+
|
|
64
|
+
### Tree View
|
|
65
|
+
|
|
66
|
+
#### `@mui/x-tree-view@8.11.3`
|
|
67
|
+
|
|
68
|
+
- [tree view] Stop looping through all items to publish the `removeItem` event (#19500) @flaviendelangle
|
|
69
|
+
- [tree view] Support flat DOM structure (#19350) @flaviendelangle
|
|
70
|
+
- [tree view] Update cursor styles for disabled TreeItem (#19548) @sai6855
|
|
71
|
+
|
|
72
|
+
#### `@mui/x-tree-view-pro@8.11.3` [](https://mui.com/r/x-pro-svg-link "Pro plan")
|
|
73
|
+
|
|
74
|
+
Same changes as in `@mui/x-tree-view@8.11.3`.
|
|
75
|
+
|
|
76
|
+
### Codemod
|
|
77
|
+
|
|
78
|
+
#### `@mui/x-codemod@8.11.3`
|
|
79
|
+
|
|
80
|
+
Internal changes.
|
|
81
|
+
|
|
82
|
+
### Docs
|
|
83
|
+
|
|
84
|
+
- [docs] Add styling row group recipe (#19349) @siriwatknp
|
|
85
|
+
- [docs] Group demos data into the dataset folder (#19549) @alexfauquette
|
|
86
|
+
- [docs] Add `shiny` bar chart example at the top (#19416) @JCQuintas
|
|
87
|
+
|
|
88
|
+
### Core
|
|
89
|
+
|
|
90
|
+
- [code-infra] Axios update (#19577) @Janpot
|
|
91
|
+
- [code-infra] Remove usage of copy-files command from code-infra (#19518) @brijeshb42
|
|
92
|
+
- [internal] Fix naming to match convention @oliviertassinari
|
|
93
|
+
|
|
94
|
+
## 8.11.2
|
|
95
|
+
|
|
96
|
+
_Sep 10, 2025_
|
|
97
|
+
|
|
98
|
+
We'd like to extend a big thank you to the 13 contributors who made this release possible. Here are some highlights ✨:
|
|
99
|
+
|
|
100
|
+
- 🐞 Bugfixes
|
|
101
|
+
- 📚 Documentation improvements
|
|
102
|
+
|
|
103
|
+
Special thanks go out to the community members for their valuable contributions:
|
|
104
|
+
@ludvigeriksson, @sai6855
|
|
105
|
+
|
|
106
|
+
The following are all team members who have contributed to this release:
|
|
107
|
+
@alexfauquette, @bernardobelchior, @brijeshb42, @flaviendelangle, @Janpot, @LukasTy, @MBilalShafi, @noraleonte, @rita-codes, @romgrk, @siriwatknp
|
|
108
|
+
|
|
109
|
+
### Data Grid
|
|
110
|
+
|
|
111
|
+
#### `@mui/x-data-grid@8.11.2`
|
|
112
|
+
|
|
113
|
+
- [DataGrid] Allow opting out of the exclude row selection model (#19423) @MBilalShafi
|
|
114
|
+
- [DataGrid] Fix column dropdown menu text alignment for the "Unpin" menu item (#19462) @MBilalShafi
|
|
115
|
+
- [DataGrid] Fix indeterminate state for "Select all" checkbox with exclude model (#19466) @MBilalShafi
|
|
116
|
+
- [DataGrid] Fix styled API arguments error (#19460) @MBilalShafi
|
|
117
|
+
- [DataGrid] Fix `stringify()` for theme objects (#19427) @romgrk
|
|
118
|
+
|
|
119
|
+
#### `@mui/x-data-grid-pro@8.11.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
120
|
+
|
|
121
|
+
Same changes as in `@mui/x-data-grid@8.11.2`.
|
|
122
|
+
|
|
123
|
+
#### `@mui/x-data-grid-premium@8.11.2` [](https://mui.com/r/x-premium-svg-link 'Premium plan')
|
|
124
|
+
|
|
125
|
+
Same changes as in `@mui/x-data-grid-pro@8.11.2`, plus:
|
|
126
|
+
|
|
127
|
+
- [DataGridPremium] Fallback to the regular reorder method for plain data (#19467) @MBilalShafi
|
|
128
|
+
- [DataGridPremium] Fix showing `0` as total aggregation value when aggregation position is set to `null` for row groups (#19515) @cherniavskii
|
|
129
|
+
|
|
130
|
+
### Date and Time Pickers
|
|
131
|
+
|
|
132
|
+
#### `@mui/x-date-pickers@8.11.2`
|
|
133
|
+
|
|
134
|
+
- [pickers] Gracefully handle `textField.slotProps` (#18980) @LukasTy
|
|
135
|
+
- [pickers] Improve hour and minute placement in Date Time Picker (#19227) @MBilalShafi
|
|
136
|
+
- [pickers] Use `calendarState.currentMonth` in Month Calendar when available (#19073) @LukasTy
|
|
137
|
+
- [pickers] Improve invalid value pasting into a section (#19357) @sai6855
|
|
138
|
+
- [fields] Remove redundant `id` and `aria-labelledby` attributes from spinbuttons (#19523) @LukasTy
|
|
139
|
+
|
|
140
|
+
#### `@mui/x-date-pickers-pro@8.11.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
141
|
+
|
|
142
|
+
Same changes as in `@mui/x-date-pickers@8.11.2`.
|
|
143
|
+
|
|
144
|
+
### Charts
|
|
145
|
+
|
|
146
|
+
#### `@mui/x-charts@8.11.2`
|
|
147
|
+
|
|
148
|
+
- [charts] Fix highlight regression (#19486) @alexfauquette
|
|
149
|
+
- [charts] Improve code reuse in `ChartsXAxis` and `ChartsYAxis` (#19198) @bernardobelchior
|
|
150
|
+
- [charts] Simplify params in `getRange` and `createDateFormatter` (#19517) @bernardobelchior
|
|
151
|
+
- [charts] Handle domain edge cases with `filterMode: 'discard'` (#19199) @bernardobelchior
|
|
152
|
+
- [l10n] Add Swedish (sv-SE) locale (#19489) @ludvigeriksson
|
|
153
|
+
|
|
154
|
+
#### `@mui/x-charts-pro@8.11.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
155
|
+
|
|
156
|
+
Same changes as in `@mui/x-charts@8.11.2`.
|
|
157
|
+
|
|
158
|
+
### Tree View
|
|
159
|
+
|
|
160
|
+
#### `@mui/x-tree-view@8.11.2`
|
|
161
|
+
|
|
162
|
+
- [TreeView] Do not mutate `props.items` in the `getItemTree()` method (#19483) @flaviendelangle
|
|
163
|
+
- [TreeView] Expose a new hook to apply selection propagation on the selected items (#19402) @flaviendelangle
|
|
164
|
+
|
|
165
|
+
#### `@mui/x-tree-view-pro@8.11.2` [](https://mui.com/r/x-pro-svg-link 'Pro plan')
|
|
166
|
+
|
|
167
|
+
Same changes as in `@mui/x-tree-view@8.11.2`.
|
|
168
|
+
|
|
169
|
+
### Codemod
|
|
170
|
+
|
|
171
|
+
#### `@mui/x-codemod@8.11.2`
|
|
172
|
+
|
|
173
|
+
Internal changes.
|
|
174
|
+
|
|
175
|
+
### Docs
|
|
176
|
+
|
|
177
|
+
- [docs] Add recipe for save and manage filters from the panel (#19361) @siriwatknp
|
|
178
|
+
|
|
179
|
+
### Core
|
|
180
|
+
|
|
181
|
+
- [code-infra] Remove log when restarting dev server (#19490) @bernardobelchior
|
|
182
|
+
- [code-infra] Store test results in CI (#19507) @Janpot
|
|
183
|
+
|
|
184
|
+
### Miscellaneous
|
|
185
|
+
|
|
186
|
+
- [infra] Set nodejs versions of various CIs to 22.18 (#19503) @brijeshb42
|
|
187
|
+
- [test] Split infinitive @romgrk
|
|
188
|
+
|
|
8
189
|
## 8.11.1
|
|
9
190
|
|
|
10
191
|
_Sep 4, 2025_
|
|
@@ -18,7 +18,7 @@ var _material = require("../internals/material");
|
|
|
18
18
|
var _allPlugins = require("../internals/plugins/allPlugins");
|
|
19
19
|
var _useChartDataProviderProProps = require("./useChartDataProviderProProps");
|
|
20
20
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
21
|
-
const releaseInfo = "
|
|
21
|
+
const releaseInfo = "MTc1ODA2NzIwMDAwMA==";
|
|
22
22
|
const packageIdentifier = 'x-charts-pro';
|
|
23
23
|
/**
|
|
24
24
|
* Orchestrates the data providers for the chart components and hooks.
|
|
@@ -45,7 +45,7 @@ const ChartAxisZoomSliderThumb = exports.ChartAxisZoomSliderThumb = /*#__PURE__*
|
|
|
45
45
|
rx = 4,
|
|
46
46
|
ry = 4
|
|
47
47
|
} = _ref,
|
|
48
|
-
|
|
48
|
+
other = (0, _objectWithoutPropertiesLoose2.default)(_ref, _excluded);
|
|
49
49
|
const classes = (0, _chartAxisZoomSliderThumbClasses.useUtilityClasses)({
|
|
50
50
|
onMove,
|
|
51
51
|
orientation,
|
|
@@ -87,6 +87,6 @@ const ChartAxisZoomSliderThumb = exports.ChartAxisZoomSliderThumb = /*#__PURE__*
|
|
|
87
87
|
ref: ref,
|
|
88
88
|
rx: rx,
|
|
89
89
|
ry: ry
|
|
90
|
-
},
|
|
90
|
+
}, other));
|
|
91
91
|
});
|
|
92
92
|
if (process.env.NODE_ENV !== "production") ChartAxisZoomSliderThumb.displayName = "ChartAxisZoomSliderThumb";
|
|
@@ -57,7 +57,7 @@ const useAggregatedData = () => {
|
|
|
57
57
|
const xScale = xAxis[xAxisId].scale;
|
|
58
58
|
const yScale = yAxis[yAxisId].scale;
|
|
59
59
|
const xPosition = (value, bandIndex, bandIdentifier, stackOffset, useBand) => {
|
|
60
|
-
if ((0, _internals.
|
|
60
|
+
if ((0, _internals.isOrdinalScale)(xScale)) {
|
|
61
61
|
const position = xScale(bandIdentifier);
|
|
62
62
|
return useBand ? position + bandWidth : position;
|
|
63
63
|
}
|
|
@@ -67,7 +67,7 @@ const useAggregatedData = () => {
|
|
|
67
67
|
return xScale(value);
|
|
68
68
|
};
|
|
69
69
|
const yPosition = (value, bandIndex, bandIdentifier, stackOffset, useBand) => {
|
|
70
|
-
if ((0, _internals.
|
|
70
|
+
if ((0, _internals.isOrdinalScale)(yScale)) {
|
|
71
71
|
const position = yScale(bandIdentifier);
|
|
72
72
|
return useBand ? position + bandWidth : position;
|
|
73
73
|
}
|
|
@@ -66,7 +66,7 @@ function computeAxisValue({
|
|
|
66
66
|
}, axis.colorMap)) : (0, _internals.getColorScale)(axis.colorMap))
|
|
67
67
|
});
|
|
68
68
|
if ((0, _internals.isDateData)(axis.data)) {
|
|
69
|
-
const dateFormatter = (0, _internals.createDateFormatter)(axis, scaleRange);
|
|
69
|
+
const dateFormatter = (0, _internals.createDateFormatter)(axis.data, scaleRange, axis.tickNumber);
|
|
70
70
|
completeAxis[axis.id].valueFormatter = axis.valueFormatter ?? dateFormatter;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -93,7 +93,7 @@ const useFunnelChartProps = props => {
|
|
|
93
93
|
axisHighlight,
|
|
94
94
|
apiRef
|
|
95
95
|
} = props,
|
|
96
|
-
|
|
96
|
+
other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
|
|
97
97
|
const margin = (0, _internals.defaultizeMargin)(marginProps, _constants.DEFAULT_MARGINS);
|
|
98
98
|
const isHorizontal = series.some(s => s.layout === 'horizontal');
|
|
99
99
|
const valueAxisConfig = {
|
|
@@ -104,7 +104,7 @@ const useFunnelChartProps = props => {
|
|
|
104
104
|
};
|
|
105
105
|
const xAxis = isHorizontal ? getCategoryAxisConfig(categoryAxis, series, isHorizontal, 'x') : valueAxisConfig;
|
|
106
106
|
const yAxis = isHorizontal ? valueAxisConfig : getCategoryAxisConfig(categoryAxis, series, isHorizontal, 'y');
|
|
107
|
-
const chartContainerProps = (0, _extends2.default)({},
|
|
107
|
+
const chartContainerProps = (0, _extends2.default)({}, other, {
|
|
108
108
|
series: series.map(s => (0, _extends2.default)({
|
|
109
109
|
type: 'funnel',
|
|
110
110
|
layout: isHorizontal ? 'horizontal' : 'vertical'
|
|
@@ -143,7 +143,8 @@ const useFunnelChartProps = props => {
|
|
|
143
143
|
const chartsWrapperProps = {
|
|
144
144
|
sx,
|
|
145
145
|
legendPosition: props.slotProps?.legend?.position,
|
|
146
|
-
legendDirection: props.slotProps?.legend?.direction
|
|
146
|
+
legendDirection: props.slotProps?.legend?.direction,
|
|
147
|
+
hideLegend: props.hideLegend ?? false
|
|
147
148
|
};
|
|
148
149
|
const axisHighlightProps = (0, _extends2.default)({}, axisHighlight);
|
|
149
150
|
return {
|
package/Heatmap/Heatmap.js
CHANGED
|
@@ -98,7 +98,8 @@ const Heatmap = exports.Heatmap = /*#__PURE__*/React.forwardRef(function Heatmap
|
|
|
98
98
|
const chartsWrapperProps = {
|
|
99
99
|
sx,
|
|
100
100
|
legendPosition: props.slotProps?.legend?.position,
|
|
101
|
-
legendDirection: props.slotProps?.legend?.direction
|
|
101
|
+
legendDirection: props.slotProps?.legend?.direction,
|
|
102
|
+
hideLegend
|
|
102
103
|
};
|
|
103
104
|
const Tooltip = slots?.tooltip ?? _HeatmapTooltip.HeatmapTooltip;
|
|
104
105
|
const Toolbar = slots?.toolbar ?? _ChartsToolbarPro.ChartsToolbarPro;
|
|
@@ -74,6 +74,7 @@ const PieChartPro = exports.PieChartPro = /*#__PURE__*/React.forwardRef(function
|
|
|
74
74
|
legendPosition: props.slotProps?.legend?.position,
|
|
75
75
|
legendDirection: props.slotProps?.legend?.direction ?? 'vertical',
|
|
76
76
|
sx: sx,
|
|
77
|
+
hideLegend: hideLegend ?? false,
|
|
77
78
|
children: [showToolbar ? /*#__PURE__*/(0, _jsxRuntime.jsx)(Toolbar, {}) : null, !hideLegend && /*#__PURE__*/(0, _jsxRuntime.jsx)(_ChartsLegend.ChartsLegend, {
|
|
78
79
|
direction: props.slotProps?.legend?.direction ?? 'vertical',
|
|
79
80
|
slots: slots,
|
|
@@ -37,9 +37,9 @@ const useSankeyChartProps = props => {
|
|
|
37
37
|
onNodeClick,
|
|
38
38
|
onLinkClick
|
|
39
39
|
} = props,
|
|
40
|
-
|
|
40
|
+
other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
|
|
41
41
|
const margin = (0, _internals.defaultizeMargin)(marginProps, _constants.DEFAULT_MARGINS);
|
|
42
|
-
const chartContainerProps = (0, _extends2.default)({},
|
|
42
|
+
const chartContainerProps = (0, _extends2.default)({}, other, {
|
|
43
43
|
series: [(0, _extends2.default)({
|
|
44
44
|
type: 'sankey'
|
|
45
45
|
}, series)],
|
|
@@ -64,7 +64,8 @@ const useSankeyChartProps = props => {
|
|
|
64
64
|
loading
|
|
65
65
|
};
|
|
66
66
|
const chartsWrapperProps = {
|
|
67
|
-
sx
|
|
67
|
+
sx,
|
|
68
|
+
hideLegend: false
|
|
68
69
|
};
|
|
69
70
|
return {
|
|
70
71
|
chartContainerProps,
|
|
@@ -11,7 +11,7 @@ import { defaultSlotsMaterial } from "../internals/material/index.js";
|
|
|
11
11
|
import { DEFAULT_PLUGINS } from "../internals/plugins/allPlugins.js";
|
|
12
12
|
import { useChartDataProviderProProps } from "./useChartDataProviderProProps.js";
|
|
13
13
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
const releaseInfo = "
|
|
14
|
+
const releaseInfo = "MTc1ODA2NzIwMDAwMA==";
|
|
15
15
|
const packageIdentifier = 'x-charts-pro';
|
|
16
16
|
/**
|
|
17
17
|
* Orchestrates the data providers for the chart components and hooks.
|
|
@@ -38,7 +38,7 @@ export const ChartAxisZoomSliderThumb = /*#__PURE__*/React.forwardRef(function C
|
|
|
38
38
|
rx = 4,
|
|
39
39
|
ry = 4
|
|
40
40
|
} = _ref,
|
|
41
|
-
|
|
41
|
+
other = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
42
42
|
const classes = useUtilityClasses({
|
|
43
43
|
onMove,
|
|
44
44
|
orientation,
|
|
@@ -80,6 +80,6 @@ export const ChartAxisZoomSliderThumb = /*#__PURE__*/React.forwardRef(function C
|
|
|
80
80
|
ref: ref,
|
|
81
81
|
rx: rx,
|
|
82
82
|
ry: ry
|
|
83
|
-
},
|
|
83
|
+
}, other));
|
|
84
84
|
});
|
|
85
85
|
if (process.env.NODE_ENV !== "production") ChartAxisZoomSliderThumb.displayName = "ChartAxisZoomSliderThumb";
|
|
@@ -4,7 +4,7 @@ const _excluded = ["onItemClick"];
|
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { line as d3Line } from '@mui/x-charts-vendor/d3-shape';
|
|
7
|
-
import { cartesianSeriesTypes, useSelector, useStore,
|
|
7
|
+
import { cartesianSeriesTypes, useSelector, useStore, isOrdinalScale } from '@mui/x-charts/internals';
|
|
8
8
|
import { FunnelSection } from "./FunnelSection.js";
|
|
9
9
|
import { alignLabel, positionLabel } from "./labelUtils.js";
|
|
10
10
|
import { useFunnelSeriesContext } from "../hooks/useFunnelSeries.js";
|
|
@@ -49,7 +49,7 @@ const useAggregatedData = () => {
|
|
|
49
49
|
const xScale = xAxis[xAxisId].scale;
|
|
50
50
|
const yScale = yAxis[yAxisId].scale;
|
|
51
51
|
const xPosition = (value, bandIndex, bandIdentifier, stackOffset, useBand) => {
|
|
52
|
-
if (
|
|
52
|
+
if (isOrdinalScale(xScale)) {
|
|
53
53
|
const position = xScale(bandIdentifier);
|
|
54
54
|
return useBand ? position + bandWidth : position;
|
|
55
55
|
}
|
|
@@ -59,7 +59,7 @@ const useAggregatedData = () => {
|
|
|
59
59
|
return xScale(value);
|
|
60
60
|
};
|
|
61
61
|
const yPosition = (value, bandIndex, bandIdentifier, stackOffset, useBand) => {
|
|
62
|
-
if (
|
|
62
|
+
if (isOrdinalScale(yScale)) {
|
|
63
63
|
const position = yScale(bandIdentifier);
|
|
64
64
|
return useBand ? position + bandWidth : position;
|
|
65
65
|
}
|
|
@@ -56,7 +56,7 @@ export function computeAxisValue({
|
|
|
56
56
|
}, axis.colorMap)) : getColorScale(axis.colorMap))
|
|
57
57
|
});
|
|
58
58
|
if (isDateData(axis.data)) {
|
|
59
|
-
const dateFormatter = createDateFormatter(axis, scaleRange);
|
|
59
|
+
const dateFormatter = createDateFormatter(axis.data, scaleRange, axis.tickNumber);
|
|
60
60
|
completeAxis[axis.id].valueFormatter = axis.valueFormatter ?? dateFormatter;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
@@ -87,7 +87,7 @@ export const useFunnelChartProps = props => {
|
|
|
87
87
|
axisHighlight,
|
|
88
88
|
apiRef
|
|
89
89
|
} = props,
|
|
90
|
-
|
|
90
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
91
91
|
const margin = defaultizeMargin(marginProps, DEFAULT_MARGINS);
|
|
92
92
|
const isHorizontal = series.some(s => s.layout === 'horizontal');
|
|
93
93
|
const valueAxisConfig = {
|
|
@@ -98,7 +98,7 @@ export const useFunnelChartProps = props => {
|
|
|
98
98
|
};
|
|
99
99
|
const xAxis = isHorizontal ? getCategoryAxisConfig(categoryAxis, series, isHorizontal, 'x') : valueAxisConfig;
|
|
100
100
|
const yAxis = isHorizontal ? valueAxisConfig : getCategoryAxisConfig(categoryAxis, series, isHorizontal, 'y');
|
|
101
|
-
const chartContainerProps = _extends({},
|
|
101
|
+
const chartContainerProps = _extends({}, other, {
|
|
102
102
|
series: series.map(s => _extends({
|
|
103
103
|
type: 'funnel',
|
|
104
104
|
layout: isHorizontal ? 'horizontal' : 'vertical'
|
|
@@ -137,7 +137,8 @@ export const useFunnelChartProps = props => {
|
|
|
137
137
|
const chartsWrapperProps = {
|
|
138
138
|
sx,
|
|
139
139
|
legendPosition: props.slotProps?.legend?.position,
|
|
140
|
-
legendDirection: props.slotProps?.legend?.direction
|
|
140
|
+
legendDirection: props.slotProps?.legend?.direction,
|
|
141
|
+
hideLegend: props.hideLegend ?? false
|
|
141
142
|
};
|
|
142
143
|
const axisHighlightProps = _extends({}, axisHighlight);
|
|
143
144
|
return {
|
package/esm/Heatmap/Heatmap.js
CHANGED
|
@@ -91,7 +91,8 @@ const Heatmap = /*#__PURE__*/React.forwardRef(function Heatmap(inProps, ref) {
|
|
|
91
91
|
const chartsWrapperProps = {
|
|
92
92
|
sx,
|
|
93
93
|
legendPosition: props.slotProps?.legend?.position,
|
|
94
|
-
legendDirection: props.slotProps?.legend?.direction
|
|
94
|
+
legendDirection: props.slotProps?.legend?.direction,
|
|
95
|
+
hideLegend
|
|
95
96
|
};
|
|
96
97
|
const Tooltip = slots?.tooltip ?? HeatmapTooltip;
|
|
97
98
|
const Toolbar = slots?.toolbar ?? ChartsToolbarPro;
|
|
@@ -66,6 +66,7 @@ const PieChartPro = /*#__PURE__*/React.forwardRef(function PieChartPro(inProps,
|
|
|
66
66
|
legendPosition: props.slotProps?.legend?.position,
|
|
67
67
|
legendDirection: props.slotProps?.legend?.direction ?? 'vertical',
|
|
68
68
|
sx: sx,
|
|
69
|
+
hideLegend: hideLegend ?? false,
|
|
69
70
|
children: [showToolbar ? /*#__PURE__*/_jsx(Toolbar, {}) : null, !hideLegend && /*#__PURE__*/_jsx(ChartsLegend, {
|
|
70
71
|
direction: props.slotProps?.legend?.direction ?? 'vertical',
|
|
71
72
|
slots: slots,
|
|
@@ -31,9 +31,9 @@ export const useSankeyChartProps = props => {
|
|
|
31
31
|
onNodeClick,
|
|
32
32
|
onLinkClick
|
|
33
33
|
} = props,
|
|
34
|
-
|
|
34
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
35
35
|
const margin = defaultizeMargin(marginProps, DEFAULT_MARGINS);
|
|
36
|
-
const chartContainerProps = _extends({},
|
|
36
|
+
const chartContainerProps = _extends({}, other, {
|
|
37
37
|
series: [_extends({
|
|
38
38
|
type: 'sankey'
|
|
39
39
|
}, series)],
|
|
@@ -58,7 +58,8 @@ export const useSankeyChartProps = props => {
|
|
|
58
58
|
loading
|
|
59
59
|
};
|
|
60
60
|
const chartsWrapperProps = {
|
|
61
|
-
sx
|
|
61
|
+
sx,
|
|
62
|
+
hideLegend: false
|
|
62
63
|
};
|
|
63
64
|
return {
|
|
64
65
|
chartContainerProps,
|
package/esm/index.js
CHANGED
|
@@ -54,7 +54,7 @@ export function BasePopper(props) {
|
|
|
54
54
|
transition,
|
|
55
55
|
placement
|
|
56
56
|
} = props,
|
|
57
|
-
|
|
57
|
+
other = _objectWithoutPropertiesLoose(props, _excluded);
|
|
58
58
|
const modifiers = React.useMemo(() => {
|
|
59
59
|
const result = [{
|
|
60
60
|
name: 'preventOverflow',
|
|
@@ -116,7 +116,7 @@ export function BasePopper(props) {
|
|
|
116
116
|
transition: transition,
|
|
117
117
|
placement: placement,
|
|
118
118
|
modifiers: modifiers
|
|
119
|
-
},
|
|
119
|
+
}, other, {
|
|
120
120
|
children: content
|
|
121
121
|
}));
|
|
122
122
|
}
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export declare function createExportIframe(title?: string): HTMLIFrameElement;
|
|
1
|
+
export declare function createExportIframe(title?: string): HTMLIFrameElement;
|
|
2
|
+
/**
|
|
3
|
+
* Applies styles to an element and returns the previous styles.
|
|
4
|
+
*/
|
|
5
|
+
export declare function applyStyles(element: HTMLElement | SVGElement, styles: Record<string, string | null>): Record<string, string | null>;
|
|
@@ -5,4 +5,17 @@ export function createExportIframe(title) {
|
|
|
5
5
|
iframeEl.style.height = '0px';
|
|
6
6
|
iframeEl.title = title || document.title;
|
|
7
7
|
return iframeEl;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Applies styles to an element and returns the previous styles.
|
|
12
|
+
*/
|
|
13
|
+
export function applyStyles(element, styles) {
|
|
14
|
+
const previousStyles = {};
|
|
15
|
+
Object.entries(styles).forEach(([key, value]) => {
|
|
16
|
+
const prev = element.style.getPropertyValue(key);
|
|
17
|
+
previousStyles[key] = prev;
|
|
18
|
+
element.style.setProperty(key, value);
|
|
19
|
+
});
|
|
20
|
+
return previousStyles;
|
|
8
21
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ChartImageExportOptions } from "./useChartProExport.types.js";
|
|
2
2
|
export declare const getDrawDocument: () => Promise<typeof import("rasterizehtml").drawDocument>;
|
|
3
|
-
export declare function exportImage(element: HTMLElement | SVGElement, params?: ChartImageExportOptions): Promise<void>;
|
|
3
|
+
export declare function exportImage(element: HTMLElement | SVGElement, svg: SVGElement, params?: ChartImageExportOptions): Promise<void>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ownerDocument from '@mui/utils/ownerDocument';
|
|
2
2
|
import { loadStyleSheets } from '@mui/x-internals/export';
|
|
3
|
-
import { createExportIframe } from "./common.js";
|
|
3
|
+
import { applyStyles, createExportIframe } from "./common.js";
|
|
4
4
|
import { defaultOnBeforeExport } from "./defaults.js";
|
|
5
5
|
export const getDrawDocument = async () => {
|
|
6
6
|
try {
|
|
@@ -12,7 +12,7 @@ export const getDrawDocument = async () => {
|
|
|
12
12
|
});
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
|
-
export async function exportImage(element, params) {
|
|
15
|
+
export async function exportImage(element, svg, params) {
|
|
16
16
|
const {
|
|
17
17
|
fileName,
|
|
18
18
|
type = 'image/png',
|
|
@@ -21,18 +21,14 @@ export async function exportImage(element, params) {
|
|
|
21
21
|
copyStyles = true
|
|
22
22
|
} = params ?? {};
|
|
23
23
|
const drawDocumentPromise = getDrawDocument();
|
|
24
|
-
const {
|
|
25
|
-
width,
|
|
26
|
-
height
|
|
27
|
-
} = element.getBoundingClientRect();
|
|
28
24
|
const doc = ownerDocument(element);
|
|
29
|
-
const canvas = document.createElement('canvas');
|
|
30
|
-
const ratio = window.devicePixelRatio || 1;
|
|
31
|
-
canvas.width = width * ratio;
|
|
32
|
-
canvas.height = height * ratio;
|
|
33
|
-
canvas.style.width = `${width}px`;
|
|
34
|
-
canvas.style.height = `${height}px`;
|
|
35
25
|
const iframe = createExportIframe(fileName);
|
|
26
|
+
/* We apply the min/max width and height to ensure the SVG doesn't resize in the export.
|
|
27
|
+
* We apply to the original SVG so that the cloned tree will contain the styles and revert these
|
|
28
|
+
* styles changes after the chart is cloned. */
|
|
29
|
+
const previousStyles = applyStyles(svg, {
|
|
30
|
+
width: `${svg.getBoundingClientRect().width}px`
|
|
31
|
+
});
|
|
36
32
|
let resolve;
|
|
37
33
|
const iframeLoadPromise = new Promise(res => {
|
|
38
34
|
resolve = res;
|
|
@@ -40,10 +36,12 @@ export async function exportImage(element, params) {
|
|
|
40
36
|
iframe.onload = async () => {
|
|
41
37
|
const exportDoc = iframe.contentDocument;
|
|
42
38
|
const elementClone = element.cloneNode(true);
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
exportDoc.body.innerHTML = container.innerHTML;
|
|
39
|
+
applyStyles(svg, previousStyles);
|
|
40
|
+
exportDoc.body.replaceChildren(elementClone);
|
|
46
41
|
exportDoc.body.style.margin = '0px';
|
|
42
|
+
/* The body's parent has a width of 0, so we use fit-content to ensure that the body adjusts its width to the width
|
|
43
|
+
* of its children. */
|
|
44
|
+
exportDoc.body.style.width = 'fit-content';
|
|
47
45
|
const rootCandidate = element.getRootNode();
|
|
48
46
|
const root = rootCandidate.constructor.name === 'ShadowRoot' ? rootCandidate : doc;
|
|
49
47
|
if (copyStyles) {
|
|
@@ -55,6 +53,15 @@ export async function exportImage(element, params) {
|
|
|
55
53
|
await iframeLoadPromise;
|
|
56
54
|
await onBeforeExport(iframe);
|
|
57
55
|
const drawDocument = await drawDocumentPromise;
|
|
56
|
+
|
|
57
|
+
/* Use the size from the export body in case `onBeforeExport` adds some elements that should be in the export. */
|
|
58
|
+
const exportDocBodySize = iframe.contentDocument.body.getBoundingClientRect();
|
|
59
|
+
const canvas = document.createElement('canvas');
|
|
60
|
+
const ratio = window.devicePixelRatio || 1;
|
|
61
|
+
canvas.width = exportDocBodySize.width * ratio;
|
|
62
|
+
canvas.height = exportDocBodySize.height * ratio;
|
|
63
|
+
canvas.style.width = `${exportDocBodySize.width}px`;
|
|
64
|
+
canvas.style.height = `${exportDocBodySize.height}px`;
|
|
58
65
|
try {
|
|
59
66
|
await drawDocument(iframe.contentDocument, canvas, {
|
|
60
67
|
// Handle retina displays: https://github.com/cburgmer/rasterizeHTML.js/blob/262b3404d1c469ce4a7750a2976dec09b8ae2d6c/examples/retina.html#L71
|
|
@@ -67,9 +74,9 @@ export async function exportImage(element, params) {
|
|
|
67
74
|
const blobPromise = new Promise(res => {
|
|
68
75
|
resolveBlobPromise = res;
|
|
69
76
|
});
|
|
70
|
-
canvas.toBlob(blob => resolveBlobPromise(blob), type, quality);
|
|
71
77
|
let blob;
|
|
72
78
|
try {
|
|
79
|
+
canvas.toBlob(b => resolveBlobPromise(b), type, quality);
|
|
73
80
|
blob = await blobPromise;
|
|
74
81
|
} catch (error) {
|
|
75
82
|
throw new Error('MUI X Charts: Failed to create blob from canvas.', {
|
|
@@ -78,7 +85,6 @@ export async function exportImage(element, params) {
|
|
|
78
85
|
}
|
|
79
86
|
if (!blob) {
|
|
80
87
|
throw new Error('MUI X Charts: Failed to create blob from canvas.');
|
|
81
|
-
return;
|
|
82
88
|
}
|
|
83
89
|
const url = URL.createObjectURL(blob);
|
|
84
90
|
triggerDownload(url, fileName || document.title);
|
|
@@ -12,9 +12,8 @@ export function printChart(element, {
|
|
|
12
12
|
printWindow.onload = async () => {
|
|
13
13
|
const printDoc = printWindow.contentDocument;
|
|
14
14
|
const elementClone = element.cloneNode(true);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
printDoc.body.innerHTML = container.innerHTML;
|
|
15
|
+
printDoc.body.replaceChildren(elementClone);
|
|
16
|
+
printDoc.body.style.margin = '0px';
|
|
18
17
|
const rootCandidate = element.getRootNode();
|
|
19
18
|
const root = rootCandidate.constructor.name === 'ShadowRoot' ? rootCandidate : doc;
|
|
20
19
|
if (copyStyles) {
|
|
@@ -13,6 +13,7 @@ function waitForAnimationFrame() {
|
|
|
13
13
|
}
|
|
14
14
|
export const useChartProExport = ({
|
|
15
15
|
chartRootRef,
|
|
16
|
+
svgRef,
|
|
16
17
|
instance
|
|
17
18
|
}) => {
|
|
18
19
|
const exportAsPrint = async options => {
|
|
@@ -32,12 +33,13 @@ export const useChartProExport = ({
|
|
|
32
33
|
};
|
|
33
34
|
const exportAsImage = async options => {
|
|
34
35
|
const chartRoot = chartRootRef.current;
|
|
35
|
-
|
|
36
|
+
const svg = svgRef.current;
|
|
37
|
+
if (chartRoot && svg) {
|
|
36
38
|
const enableAnimation = instance.disableAnimation();
|
|
37
39
|
try {
|
|
38
40
|
// Wait for animation frame to ensure the animation finished
|
|
39
41
|
await waitForAnimationFrame();
|
|
40
|
-
await exportImage(chartRoot, options);
|
|
42
|
+
await exportImage(chartRoot, svg, options);
|
|
41
43
|
} catch (error) {
|
|
42
44
|
console.error('MUI X Charts: Error exporting chart as image:', error);
|
|
43
45
|
} finally {
|
package/index.js
CHANGED
|
@@ -62,7 +62,7 @@ function BasePopper(props) {
|
|
|
62
62
|
transition,
|
|
63
63
|
placement
|
|
64
64
|
} = props,
|
|
65
|
-
|
|
65
|
+
other = (0, _objectWithoutPropertiesLoose2.default)(props, _excluded);
|
|
66
66
|
const modifiers = React.useMemo(() => {
|
|
67
67
|
const result = [{
|
|
68
68
|
name: 'preventOverflow',
|
|
@@ -124,7 +124,7 @@ function BasePopper(props) {
|
|
|
124
124
|
transition: transition,
|
|
125
125
|
placement: placement,
|
|
126
126
|
modifiers: modifiers
|
|
127
|
-
},
|
|
127
|
+
}, other, {
|
|
128
128
|
children: content
|
|
129
129
|
}));
|
|
130
130
|
}
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
export declare function createExportIframe(title?: string): HTMLIFrameElement;
|
|
1
|
+
export declare function createExportIframe(title?: string): HTMLIFrameElement;
|
|
2
|
+
/**
|
|
3
|
+
* Applies styles to an element and returns the previous styles.
|
|
4
|
+
*/
|
|
5
|
+
export declare function applyStyles(element: HTMLElement | SVGElement, styles: Record<string, string | null>): Record<string, string | null>;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.applyStyles = applyStyles;
|
|
6
7
|
exports.createExportIframe = createExportIframe;
|
|
7
8
|
function createExportIframe(title) {
|
|
8
9
|
const iframeEl = document.createElement('iframe');
|
|
@@ -11,4 +12,17 @@ function createExportIframe(title) {
|
|
|
11
12
|
iframeEl.style.height = '0px';
|
|
12
13
|
iframeEl.title = title || document.title;
|
|
13
14
|
return iframeEl;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Applies styles to an element and returns the previous styles.
|
|
19
|
+
*/
|
|
20
|
+
function applyStyles(element, styles) {
|
|
21
|
+
const previousStyles = {};
|
|
22
|
+
Object.entries(styles).forEach(([key, value]) => {
|
|
23
|
+
const prev = element.style.getPropertyValue(key);
|
|
24
|
+
previousStyles[key] = prev;
|
|
25
|
+
element.style.setProperty(key, value);
|
|
26
|
+
});
|
|
27
|
+
return previousStyles;
|
|
14
28
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { ChartImageExportOptions } from "./useChartProExport.types.js";
|
|
2
2
|
export declare const getDrawDocument: () => Promise<typeof import("rasterizehtml").drawDocument>;
|
|
3
|
-
export declare function exportImage(element: HTMLElement | SVGElement, params?: ChartImageExportOptions): Promise<void>;
|
|
3
|
+
export declare function exportImage(element: HTMLElement | SVGElement, svg: SVGElement, params?: ChartImageExportOptions): Promise<void>;
|
|
@@ -22,7 +22,7 @@ const getDrawDocument = async () => {
|
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
exports.getDrawDocument = getDrawDocument;
|
|
25
|
-
async function exportImage(element, params) {
|
|
25
|
+
async function exportImage(element, svg, params) {
|
|
26
26
|
const {
|
|
27
27
|
fileName,
|
|
28
28
|
type = 'image/png',
|
|
@@ -31,18 +31,14 @@ async function exportImage(element, params) {
|
|
|
31
31
|
copyStyles = true
|
|
32
32
|
} = params ?? {};
|
|
33
33
|
const drawDocumentPromise = getDrawDocument();
|
|
34
|
-
const {
|
|
35
|
-
width,
|
|
36
|
-
height
|
|
37
|
-
} = element.getBoundingClientRect();
|
|
38
34
|
const doc = (0, _ownerDocument.default)(element);
|
|
39
|
-
const canvas = document.createElement('canvas');
|
|
40
|
-
const ratio = window.devicePixelRatio || 1;
|
|
41
|
-
canvas.width = width * ratio;
|
|
42
|
-
canvas.height = height * ratio;
|
|
43
|
-
canvas.style.width = `${width}px`;
|
|
44
|
-
canvas.style.height = `${height}px`;
|
|
45
35
|
const iframe = (0, _common.createExportIframe)(fileName);
|
|
36
|
+
/* We apply the min/max width and height to ensure the SVG doesn't resize in the export.
|
|
37
|
+
* We apply to the original SVG so that the cloned tree will contain the styles and revert these
|
|
38
|
+
* styles changes after the chart is cloned. */
|
|
39
|
+
const previousStyles = (0, _common.applyStyles)(svg, {
|
|
40
|
+
width: `${svg.getBoundingClientRect().width}px`
|
|
41
|
+
});
|
|
46
42
|
let resolve;
|
|
47
43
|
const iframeLoadPromise = new Promise(res => {
|
|
48
44
|
resolve = res;
|
|
@@ -50,10 +46,12 @@ async function exportImage(element, params) {
|
|
|
50
46
|
iframe.onload = async () => {
|
|
51
47
|
const exportDoc = iframe.contentDocument;
|
|
52
48
|
const elementClone = element.cloneNode(true);
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
exportDoc.body.innerHTML = container.innerHTML;
|
|
49
|
+
(0, _common.applyStyles)(svg, previousStyles);
|
|
50
|
+
exportDoc.body.replaceChildren(elementClone);
|
|
56
51
|
exportDoc.body.style.margin = '0px';
|
|
52
|
+
/* The body's parent has a width of 0, so we use fit-content to ensure that the body adjusts its width to the width
|
|
53
|
+
* of its children. */
|
|
54
|
+
exportDoc.body.style.width = 'fit-content';
|
|
57
55
|
const rootCandidate = element.getRootNode();
|
|
58
56
|
const root = rootCandidate.constructor.name === 'ShadowRoot' ? rootCandidate : doc;
|
|
59
57
|
if (copyStyles) {
|
|
@@ -65,6 +63,15 @@ async function exportImage(element, params) {
|
|
|
65
63
|
await iframeLoadPromise;
|
|
66
64
|
await onBeforeExport(iframe);
|
|
67
65
|
const drawDocument = await drawDocumentPromise;
|
|
66
|
+
|
|
67
|
+
/* Use the size from the export body in case `onBeforeExport` adds some elements that should be in the export. */
|
|
68
|
+
const exportDocBodySize = iframe.contentDocument.body.getBoundingClientRect();
|
|
69
|
+
const canvas = document.createElement('canvas');
|
|
70
|
+
const ratio = window.devicePixelRatio || 1;
|
|
71
|
+
canvas.width = exportDocBodySize.width * ratio;
|
|
72
|
+
canvas.height = exportDocBodySize.height * ratio;
|
|
73
|
+
canvas.style.width = `${exportDocBodySize.width}px`;
|
|
74
|
+
canvas.style.height = `${exportDocBodySize.height}px`;
|
|
68
75
|
try {
|
|
69
76
|
await drawDocument(iframe.contentDocument, canvas, {
|
|
70
77
|
// Handle retina displays: https://github.com/cburgmer/rasterizeHTML.js/blob/262b3404d1c469ce4a7750a2976dec09b8ae2d6c/examples/retina.html#L71
|
|
@@ -77,9 +84,9 @@ async function exportImage(element, params) {
|
|
|
77
84
|
const blobPromise = new Promise(res => {
|
|
78
85
|
resolveBlobPromise = res;
|
|
79
86
|
});
|
|
80
|
-
canvas.toBlob(blob => resolveBlobPromise(blob), type, quality);
|
|
81
87
|
let blob;
|
|
82
88
|
try {
|
|
89
|
+
canvas.toBlob(b => resolveBlobPromise(b), type, quality);
|
|
83
90
|
blob = await blobPromise;
|
|
84
91
|
} catch (error) {
|
|
85
92
|
throw new Error('MUI X Charts: Failed to create blob from canvas.', {
|
|
@@ -88,7 +95,6 @@ async function exportImage(element, params) {
|
|
|
88
95
|
}
|
|
89
96
|
if (!blob) {
|
|
90
97
|
throw new Error('MUI X Charts: Failed to create blob from canvas.');
|
|
91
|
-
return;
|
|
92
98
|
}
|
|
93
99
|
const url = URL.createObjectURL(blob);
|
|
94
100
|
triggerDownload(url, fileName || document.title);
|
|
@@ -19,9 +19,8 @@ function printChart(element, {
|
|
|
19
19
|
printWindow.onload = async () => {
|
|
20
20
|
const printDoc = printWindow.contentDocument;
|
|
21
21
|
const elementClone = element.cloneNode(true);
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
printDoc.body.innerHTML = container.innerHTML;
|
|
22
|
+
printDoc.body.replaceChildren(elementClone);
|
|
23
|
+
printDoc.body.style.margin = '0px';
|
|
25
24
|
const rootCandidate = element.getRootNode();
|
|
26
25
|
const root = rootCandidate.constructor.name === 'ShadowRoot' ? rootCandidate : doc;
|
|
27
26
|
if (copyStyles) {
|
|
@@ -20,6 +20,7 @@ function waitForAnimationFrame() {
|
|
|
20
20
|
}
|
|
21
21
|
const useChartProExport = ({
|
|
22
22
|
chartRootRef,
|
|
23
|
+
svgRef,
|
|
23
24
|
instance
|
|
24
25
|
}) => {
|
|
25
26
|
const exportAsPrint = async options => {
|
|
@@ -39,12 +40,13 @@ const useChartProExport = ({
|
|
|
39
40
|
};
|
|
40
41
|
const exportAsImage = async options => {
|
|
41
42
|
const chartRoot = chartRootRef.current;
|
|
42
|
-
|
|
43
|
+
const svg = svgRef.current;
|
|
44
|
+
if (chartRoot && svg) {
|
|
43
45
|
const enableAnimation = instance.disableAnimation();
|
|
44
46
|
try {
|
|
45
47
|
// Wait for animation frame to ensure the animation finished
|
|
46
48
|
await waitForAnimationFrame();
|
|
47
|
-
await (0, _exportImage.exportImage)(chartRoot, options);
|
|
49
|
+
await (0, _exportImage.exportImage)(chartRoot, svg, options);
|
|
48
50
|
} catch (error) {
|
|
49
51
|
console.error('MUI X Charts: Error exporting chart as image:', error);
|
|
50
52
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mui/x-charts-pro",
|
|
3
|
-
"version": "8.11.
|
|
3
|
+
"version": "8.11.3",
|
|
4
4
|
"author": "MUI Team",
|
|
5
5
|
"description": "The Pro plan edition of the MUI X Charts components.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@babel/runtime": "^7.28.2",
|
|
31
|
-
"@mui/utils": "^7.3.
|
|
31
|
+
"@mui/utils": "^7.3.2",
|
|
32
32
|
"clsx": "^2.1.1",
|
|
33
33
|
"prop-types": "^15.8.1",
|
|
34
|
-
"@mui/x-charts": "8.11.
|
|
35
|
-
"@mui/x-
|
|
36
|
-
"@mui/x-
|
|
37
|
-
"@mui/x-
|
|
38
|
-
"@mui/x-
|
|
34
|
+
"@mui/x-charts": "8.11.3",
|
|
35
|
+
"@mui/x-internal-gestures": "0.2.6",
|
|
36
|
+
"@mui/x-charts-vendor": "8.11.3",
|
|
37
|
+
"@mui/x-internals": "8.11.3",
|
|
38
|
+
"@mui/x-license": "8.11.3"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@emotion/react": "^11.9.0",
|