Skip to content

Commit fc61140

Browse files
authored
Merge pull request #521 from AnnMarieW/async-loading
async loading
2 parents 0d31f07 + 597ee4b commit fc61140

33 files changed

+1039
-722
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
### Changed
99
- `notification` will now automatically set its `action` to `hide` when closed, this avoids issues where a `callback` error would re-trigger the component. #523 by @BSd3v
1010
- Removed `draggable` and `speed` prop from `Carousel` since these props are not supported in Embla Carousel V8. #520 by @AnnMarieW
11+
- graphs and code highlight components now loaded async, reducing the dash_mantine_components.js file size from 2.68 MiB to 823 KiB #521 by @AnnMarieW and @emilhe
1112

1213
# 1.0.0rc2
1314

dash_mantine_components/__init__.py

+43-14
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# noinspection PyUnresolvedReferences
1212
from ._imports_ import *
1313
from ._imports_ import __all__
14-
from .theme import DEFAULT_THEME
1514
from .figure_templates import add_figure_templates
15+
from .theme import DEFAULT_THEME
1616

1717
if not hasattr(_dash, "__plotly_dash") and not hasattr(_dash, "development"):
1818
print(
@@ -35,34 +35,63 @@
3535

3636
_this_module = _sys.modules[__name__]
3737

38+
# Add async components here.
39+
async_resources = [
40+
"AreaChart",
41+
"BarChart",
42+
"LineChart",
43+
"BubbleChart",
44+
"DonutChart",
45+
"PieChart",
46+
"RadarChart",
47+
"ScatterChart",
48+
"CompositeChart",
49+
"Sparkline",
50+
"CodeHighlight",
51+
"CodeHighlightTabs",
52+
"InlineCodeHighlight",
53+
]
54+
async_chunks = [f"async-{async_resource}" for async_resource in async_resources]
55+
56+
# Add shared chunks here.
57+
shared_chunks = [
58+
f"{__name__}-shared",
59+
f"{__name__}-charts-shared",
60+
]
61+
62+
# Collect all chunks (main, async, shared).
63+
chunks = [__name__] + async_chunks + shared_chunks
64+
65+
# Add all chunks to the js_dist list.
3866
_js_dist = []
39-
4067
_js_dist.extend(
4168
[
4269
{
43-
"relative_package_path": "dash_mantine_components.js",
44-
"external_url": "https://unpkg.com/{0}@{2}/{1}/{1}.js".format(
45-
package_name, __name__, __version__
46-
),
70+
"relative_package_path": f"{chunk}.js",
71+
"external_url": f"https://unpkg.com/{package_name}@{__version__}/{__name__}/{chunk}.js",
4772
"namespace": package_name,
48-
},
73+
"async": chunk != __name__, # don't make the main bundle async
74+
}
75+
for chunk in chunks
76+
]
77+
)
78+
_js_dist.extend(
79+
[
4980
{
50-
"relative_package_path": "dash_mantine_components.js.map",
51-
"external_url": "https://unpkg.com/{0}@{2}/{1}/{1}.js.map".format(
52-
package_name, __name__, __version__
53-
),
81+
"relative_package_path": f"{chunk}.js.map",
82+
"external_url": f"https://unpkg.com/{package_name}@{__version__}/{__name__}/{chunk}.js.map",
5483
"namespace": package_name,
5584
"dynamic": True,
56-
},
85+
}
86+
for chunk in chunks
5787
]
5888
)
5989

90+
# Similarly, collect CSS.
6091
_css_dist = []
6192

62-
6393
for _component in __all__:
6494
setattr(locals()[_component], "_js_dist", _js_dist)
6595
setattr(locals()[_component], "_css_dist", _css_dist)
6696

67-
6897
__all__ += [DEFAULT_THEME, styles, add_figure_templates]

dash_mantine_components/styles.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
CAROUSEL = "https://unpkg.com/@mantine/[email protected]/styles.css"
55
NOTIFICATIONS = "https://unpkg.com/@mantine/[email protected]/styles.css"
66
NPROGRESS = "https://unpkg.com/@mantine/[email protected]/styles.css"
7-
ALL = [DATES, CODE_HIGHLIGHT, CHARTS, CAROUSEL, NOTIFICATIONS, NPROGRESS]
7+
ALL = [DATES, CODE_HIGHLIGHT, CHARTS, CAROUSEL, NOTIFICATIONS, NPROGRESS]

package-lock.json

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"homepage": "https://github.com/snehilvj/dash-mantine-components",
1414
"scripts": {
1515
"build:js::dev": "webpack --mode development",
16-
"build:js": "webpack",
16+
"build:js": "webpack --mode production",
1717
"build:backends": "dash-generate-components ./src/ts/components dash_mantine_components -p package-info.json --r-prefix '' --jl-prefix '' --ignore \\.test\\.",
1818
"build": "npm run build:js && npm run build:backends",
1919
"watch": "npm run build:js::dev -- --watch",
@@ -23,6 +23,7 @@
2323
"@braintree/sanitize-url": "^7.1.0",
2424
"@types/ramda": "^0.30.1",
2525
"@types/react": "^18.2.55",
26+
"@plotly/webpack-dash-dynamic-import": "^1.3.0",
2627
"css-loader": "^6.10.0",
2728
"dash-extensions-js": "^0.0.8",
2829
"npm-run-all": "^2.1.0",

src/ts/components/charts/AreaChart.tsx

+10-116
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AreaChart as MantineAreaChart } from "@mantine/charts";
1+
import React, { Suspense } from 'react';
22
import {
33
AreaChartCurveType,
44
AreaChartSeries,
@@ -9,11 +9,12 @@ import { BoxProps } from "props/box";
99
import { GridChartBaseProps } from "props/charts";
1010
import { DashBaseProps } from "props/dash";
1111
import { StylesApiProps } from "props/styles";
12-
import React, { useState, useRef } from "react";
13-
import { getClickData, isEventValid } from "../../utils/charts";
14-
import { getLoadingState } from "../../utils/dash3";
1512

16-
interface Props
13+
// eslint-disable-next-line no-inline-comments
14+
const LazyAreaChart = React.lazy(() => import(/* webpackChunkName: "AreaChart" */ './fragments/AreaChart'));
15+
16+
17+
export interface Props
1718
extends BoxProps,
1819
GridChartBaseProps,
1920
StylesApiProps,
@@ -65,118 +66,11 @@ interface Props
6566
}
6667

6768
/** AreaChart */
68-
const AreaChart = ({
69-
setProps,
70-
loading_state,
71-
clickData,
72-
hoverData,
73-
clickSeriesName,
74-
hoverSeriesName,
75-
series,
76-
highlightHover = false,
77-
areaChartProps,
78-
activeDotProps,
79-
areaProps,
80-
...others }: Props) => {
81-
82-
const [highlightedArea, setHighlightedArea] = useState(null);
83-
const shouldHighlight = highlightHover && highlightedArea !== null;
84-
85-
const seriesName = useRef(null);
86-
87-
const onClick = (ev) => {
88-
if (isEventValid(ev)) {
89-
setProps({
90-
clickSeriesName: seriesName.current,
91-
clickData: getClickData(ev)
92-
});
93-
}
94-
seriesName.current = null;
95-
};
96-
97-
const onMouseOver = (ev) => {
98-
if (isEventValid(ev)) {
99-
setProps({
100-
hoverSeriesName: seriesName.current,
101-
hoverData: getClickData(ev)
102-
});
103-
}
104-
seriesName.current = null;
105-
106-
};
107-
108-
const handleSeriesClick= (ev) => {
109-
if (isEventValid(ev)) {
110-
seriesName.current = ev["name"];
111-
}
112-
};
113-
114-
const handleSeriesHover = (ev) => {
115-
if (isEventValid(ev)) {
116-
const hoveredSeriesName = ev["name"];
117-
118-
seriesName.current = hoveredSeriesName;
119-
setHighlightedArea(hoveredSeriesName);
120-
}
121-
};
122-
123-
const handleDotClick = (ev, payload) => {
124-
if (isEventValid(ev)) {
125-
seriesName.current = payload["dataKey"];
126-
}
127-
}
128-
129-
const handleDotHover = (ev, payload) => {
130-
if (isEventValid(ev)) {
131-
const hoveredSeriesName = payload["dataKey"];
132-
seriesName.current = hoveredSeriesName;
133-
setHighlightedArea(hoveredSeriesName);
134-
}
135-
};
136-
137-
138-
const handleHoverEnd = () => {
139-
setHighlightedArea(null); // Reset highlighted area
140-
};
141-
142-
const areaPropsFunction = (item) => {
143-
const dimmed = shouldHighlight && highlightedArea !== item.name;
144-
145-
const returnProps : any = {
146-
...areaProps,
147-
onClick: handleSeriesClick,
148-
onMouseOver: handleSeriesHover,
149-
onMouseOut: handleHoverEnd,
150-
};
151-
152-
/**if not dimmed, default behavior of Opacity will be triggered, including Hover over chart legend (BarChart.mjs)
153-
fillOpacity: dimmed ? 0.1 : fillOpacity,
154-
strokeOpacity: dimmed ? 0.2 : 0,
155-
*/
156-
if (dimmed) {
157-
returnProps.fillOpacity = 0.1;
158-
returnProps.strokeOpacity = 0.2;
159-
}
160-
161-
return returnProps;
162-
};
163-
164-
const newProps = { ...areaChartProps, onClick, onMouseOver };
165-
69+
const AreaChart = (props: Props) => {
16670
return (
167-
<MantineAreaChart
168-
data-dash-is-loading={getLoadingState(loading_state) || undefined}
169-
areaChartProps={newProps}
170-
series={series}
171-
activeDotProps={{
172-
...activeDotProps,
173-
onClick: handleDotClick,
174-
onMouseOver: handleDotHover,
175-
onMouseOut: handleHoverEnd,
176-
}}
177-
areaProps={areaPropsFunction}
178-
{...others}
179-
/>
71+
<Suspense fallback={null}>
72+
<LazyAreaChart {...props} />
73+
</Suspense>
18074
);
18175
}
18276

0 commit comments

Comments
 (0)