Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9a3126a

Browse files
Merge pull request #372 from raheeliftikhar5/echarts-extension
Echarts extension
2 parents 4968773 + b137622 commit 9a3126a

File tree

23 files changed

+427
-25
lines changed

23 files changed

+427
-25
lines changed

‎client/packages/lowcoder-comps/package.json‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lowcoder-comps",
3-
"version": "0.0.12",
3+
"version": "0.0.13",
44
"type": "module",
55
"license": "MIT",
66
"dependencies": {
@@ -14,6 +14,7 @@
1414
"@types/react": "17",
1515
"@types/react-dom": "17",
1616
"big.js": "^6.2.1",
17+
"echarts-extension-gmap": "^1.6.0",
1718
"lowcoder-cli": "workspace:^",
1819
"lowcoder-sdk": "workspace:^",
1920
"mermaid": "^10.2.4",

‎client/packages/lowcoder-comps/src/comps/chartComp/chartComp.tsx‎

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,17 @@ import {
2626
withViewFn,
2727
ThemeContext,
2828
chartColorPalette,
29+
loadScript,
2930
} from "lowcoder-sdk";
3031
import { getEchartsLocale, trans } from "i18n/comps";
3132
import { ItemColorComp } from "comps/chartComp/chartConfigs/lineChartConfig";
3233
import {
3334
echartsConfigOmitChildren,
3435
getEchartsConfig,
3536
getSelectedPoints,
37+
loadGoogleMapsScript,
3638
} from "comps/chartComp/chartUtils";
39+
import 'echarts-extension-gmap';
3740
import log from "loglevel";
3841

3942
let ChartTmpComp = (function () {
@@ -45,6 +48,7 @@ let ChartTmpComp = (function () {
4548
ChartTmpComp = withViewFn(ChartTmpComp, (comp) => {
4649
const echartsCompRef = useRef<ReactECharts | null>();
4750
const [chartSize, setChartSize] = useState<ChartSize>();
51+
const [mapScriptLoaded, setMapScriptLoaded] = useState(false);
4852
const firstResize = useRef(true);
4953
const theme = useContext(ThemeContext);
5054
const defaultChartTheme = {
@@ -87,6 +91,34 @@ ChartTmpComp = withViewFn(ChartTmpComp, (comp) => {
8791
);
8892
}, [chartSize, ...Object.values(echartsConfigChildren)]);
8993

94+
const isMapScriptLoaded = useMemo(() => {
95+
return mapScriptLoaded || window?.google;
96+
}, [mapScriptLoaded])
97+
98+
const loadGoogleMapsData = () => {
99+
const echartsCompInstance = echartsCompRef?.current?.getEchartsInstance();
100+
if (!echartsCompInstance) {
101+
return _.noop;
102+
}
103+
echartsCompInstance.getModel().getComponent("gmap").getGoogleMap();
104+
}
105+
106+
const apiKey = comp.children.mapApiKey.getView();
107+
const mode = comp.children.mode.getView();
108+
useEffect(() => {
109+
if(mode === 'map') {
110+
const gMapScript = loadGoogleMapsScript('');
111+
if(isMapScriptLoaded) {
112+
loadGoogleMapsData();
113+
return;
114+
}
115+
gMapScript.addEventListener('load', function () {
116+
setMapScriptLoaded(true);
117+
loadGoogleMapsData();
118+
});
119+
}
120+
}, [mode, apiKey, option])
121+
90122
return (
91123
<ReactResizeDetector
92124
onResize={(w, h) => {
@@ -101,15 +133,17 @@ ChartTmpComp = withViewFn(ChartTmpComp, (comp) => {
101133
}
102134
}}
103135
>
104-
<ReactECharts
105-
ref={(e) => (echartsCompRef.current = e)}
106-
style={{ height: "100%" }}
107-
notMerge
108-
lazyUpdate
109-
opts={{ locale: getEchartsLocale() }}
110-
option={option}
111-
theme={themeConfig}
112-
/>
136+
{(mode !== 'map' || (mode === 'map' && isMapScriptLoaded)) && (
137+
<ReactECharts
138+
ref={(e) => (echartsCompRef.current = e)}
139+
style={{ height: "100%" }}
140+
notMerge
141+
lazyUpdate
142+
opts={{ locale: getEchartsLocale() }}
143+
option={option}
144+
theme={mode !== 'map' ? themeConfig : undefined}
145+
/>
146+
)}
113147
</ReactResizeDetector>
114148
);
115149
});

‎client/packages/lowcoder-comps/src/comps/chartComp/chartConfigs/chartUrls.tsx‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ const echartsUrlLocale = language === "zh" ? "zh" : "en";
44
export const optionUrl = `https://echarts.apache.org/${echartsUrlLocale}/option.html`;
55
export const examplesUrl = `https://echarts.apache.org/examples/${echartsUrlLocale}/index.html`;
66
export const xAxisTypeUrl = `${optionUrl}#xAxis.type`;
7+
export const googleMapsApiUrl = `https://maps.googleapis.com/maps/api/js`;
8+
export const mapOptionUrl = `https://github.com/plainheart/echarts-extension-gmap`;
9+
export const mapExamplesUrl = `https://codepen.io/plainheart/pen/VweLGbR`;

‎client/packages/lowcoder-comps/src/comps/chartComp/chartConstants.tsx‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { jsonControl, JSONObject, stateComp, toJSONObjectArray, toObject } from "lowcoder-sdk";
2-
import { StringControl } from "lowcoder-sdk";
2+
import { withDefault,BooleanControl,StringControl,NumberControl,JSONObjectControl } from "lowcoder-sdk";
33
import { dropdownControl } from "lowcoder-sdk";
44
import { eventHandlerControl } from "lowcoder-sdk";
55
import { valueComp, withType } from "lowcoder-sdk";
@@ -15,7 +15,6 @@ import { ScatterChartConfig } from "./chartConfigs/scatterChartConfig";
1515
import { SeriesListComp } from "./seriesComp";
1616
import { EChartsOption } from "echarts";
1717
import { i18nObjs, trans } from "i18n/comps";
18-
import { JSONValue } from "lowcoder";
1918

2019
export const ChartTypeOptions = [
2120
{
@@ -45,6 +44,10 @@ const chartModeOptions = [
4544
label: "ECharts JSON",
4645
value: "json",
4746
},
47+
{
48+
label: "Map",
49+
value: "map",
50+
},
4851
] as const;
4952

5053
export const EventOptions = [
@@ -221,6 +224,14 @@ export const chartUiModeChildren = {
221224
chartConfig: ChartOptionComp,
222225
};
223226

227+
const chartMapModeChildren = {
228+
mapApiKey: withDefault(StringControl, ''),
229+
mapZoomLevel: withDefault(NumberControl, 3),
230+
mapCenterLng: withDefault(NumberControl, 15.932644),
231+
mapCenterLat: withDefault(NumberControl, 50.942063),
232+
mapOptions: jsonControl(toObject, i18nObjs.defaultMapJsonOption),
233+
}
234+
224235
export const chartChildrenMap = {
225236
mode: dropdownControl(chartModeOptions, "ui"),
226237
echartsOption: jsonControl(toObject, i18nObjs.defaultEchartsJsonOption),
@@ -236,6 +247,7 @@ export const chartChildrenMap = {
236247
}>
237248
>([]),
238249
...chartUiModeChildren,
250+
...chartMapModeChildren,
239251
};
240252

241253
const chartUiChildrenMap = uiChildren(chartChildrenMap);

‎client/packages/lowcoder-comps/src/comps/chartComp/chartPropertyView.tsx‎

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import {
99
RedButton,
1010
Section,
1111
sectionNames,
12+
controlItem,
1213
} from "lowcoder-sdk";
1314
import { trans } from "i18n/comps";
14-
import { examplesUrl, optionUrl } from "./chartConfigs/chartUrls";
15+
import { examplesUrl, mapExamplesUrl,mapOptionUrl,optionUrl } from "./chartConfigs/chartUrls";
1516

1617
export function chartPropertyView(
1718
children: ChartCompChildrenType,
@@ -147,6 +148,58 @@ export function chartPropertyView(
147148
</>
148149
);
149150

151+
const mapModePropertyView = (
152+
<>
153+
<Section name={'Map Configuration'}>
154+
{children.mapApiKey.propertyView({
155+
label: "API Key"
156+
})}
157+
{children.mapZoomLevel.propertyView({
158+
label: "Zoom Level"
159+
})}
160+
{controlItem({}, (
161+
<b style={{marginTop: '8px'}}>
162+
{'Center Position'}
163+
</b>
164+
))}
165+
{children.mapCenterLng.propertyView({
166+
label: "Longitude"
167+
})}
168+
{children.mapCenterLat.propertyView({
169+
label: "Latitude"
170+
})}
171+
</Section>
172+
<Section name={'Map Data'}>
173+
{children.mapOptions.propertyView({
174+
label: trans("chart.echartsOptionLabel"),
175+
styleName: "higher",
176+
tooltip: (
177+
<div>
178+
<a href={mapOptionUrl} target="_blank" rel="noopener noreferrer">
179+
{trans("chart.echartsMapOptionTooltip")}
180+
</a>
181+
<br />
182+
<a href={mapExamplesUrl} target="_blank" rel="noopener noreferrer">
183+
{trans("chart.echartsMapOptionExamples")}
184+
</a>
185+
</div>
186+
),
187+
})}
188+
</Section>
189+
<Section name={sectionNames.layout}>{hiddenPropertyView(children)}</Section>
190+
</>
191+
);
192+
193+
const getChatConfigByMode = (mode: string) => {
194+
switch(mode) {
195+
case "ui":
196+
return uiModePropertyView;
197+
case "json":
198+
return jsonModePropertyView;
199+
case "map":
200+
return mapModePropertyView;
201+
}
202+
}
150203
return (
151204
<>
152205
<Section name={trans("chart.mode")}>
@@ -155,7 +208,7 @@ export function chartPropertyView(
155208
radioButton: true,
156209
})}
157210
</Section>
158-
{children.mode.getView()==="ui" ? uiModePropertyView : jsonModePropertyView}
211+
{getChatConfigByMode(children.mode.getView())}
159212
</>
160213
);
161214
}

‎client/packages/lowcoder-comps/src/comps/chartComp/chartUtils.ts‎

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ import {
66
noDataPieChartConfig,
77
} from "comps/chartComp/chartConstants";
88
import { getPieRadiusAndCenter } from "comps/chartComp/chartConfigs/pieChartConfig";
9-
import { EChartsOption } from "echarts";
9+
import { EChartsOptionWithMap } from "./reactEcharts/types";
1010
import _ from "lodash";
11-
import { chartColorPalette, isNumeric, JSONObject } from "lowcoder-sdk";
11+
import { chartColorPalette, isNumeric, JSONObject,loadScript } from "lowcoder-sdk";
1212
import { calcXYConfig } from "comps/chartComp/chartConfigs/cartesianAxisConfig";
1313
import Big from "big.js";
14+
import { googleMapsApiUrl } from "./chartConfigs/chartUrls";
1415

1516
export function transformData(
1617
originData: JSONObject[],
@@ -122,10 +123,30 @@ export function getSeriesConfig(props: EchartsConfigProps) {
122123
}
123124

124125
// https://echarts.apache.org/en/option.html
125-
export function getEchartsConfig(props: EchartsConfigProps, chartSize?: ChartSize): EChartsOption {
126+
export function getEchartsConfig(props: EchartsConfigProps, chartSize?: ChartSize): EChartsOptionWithMap {
126127
if (props.mode === "json") {
127128
return props.echartsOption ? props.echartsOption : {};
128129
}
130+
if(props.mode === "map") {
131+
const {
132+
mapZoomLevel,
133+
mapCenterLat,
134+
mapCenterLng,
135+
mapOptions,
136+
} = props;
137+
138+
const echartsOption = mapOptions ? mapOptions : {};
139+
return {
140+
gmap: {
141+
center: [mapCenterLng, mapCenterLat],
142+
zoom: mapZoomLevel,
143+
renderOnMoving: true,
144+
// echartsLayerZIndex: 2019,
145+
roam: true
146+
},
147+
...echartsOption,
148+
}
149+
}
129150
// axisChart
130151
const axisChart = isAxisChart(props.chartConfig.type);
131152
const gridPos = {
@@ -134,7 +155,7 @@ export function getEchartsConfig(props: EchartsConfigProps, chartSize?: ChartSiz
134155
top: 50,
135156
bottom: 35,
136157
};
137-
let config: EChartsOption = {
158+
let config: EChartsOptionWithMap = {
138159
title: { text: props.title, left: "center" },
139160
tooltip: {
140161
confine: true,
@@ -238,3 +259,21 @@ export function getSelectedPoints(param: any, option: any) {
238259
}
239260
return [];
240261
}
262+
263+
export function loadGoogleMapsScript(apiKey?: string) {
264+
const mapsUrl = `${googleMapsApiUrl}?key=${apiKey}`;
265+
const scripts = document.getElementsByTagName('script');
266+
const scriptIndex = _.findIndex(scripts, (script) => script.src === mapsUrl);
267+
if(scriptIndex > -1) {
268+
return scripts[scriptIndex];
269+
}
270+
271+
const script = document.createElement("script");
272+
script.type = "text/javascript";
273+
script.src = mapsUrl;
274+
script.async = true;
275+
script.defer = true;
276+
window.document.body.appendChild(script);
277+
278+
return script;
279+
}

‎client/packages/lowcoder-comps/src/comps/chartComp/reactEcharts/core.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ export default class EChartsReactCore extends PureComponent<EChartsReactProps> {
5858
if (
5959
!isEqual(prevProps.theme, this.props.theme) ||
6060
!isEqual(prevProps.opts, this.props.opts) ||
61-
!isEqual(prevProps.onEvents, this.props.onEvents)
61+
!isEqual(prevProps.onEvents, this.props.onEvents) ||
62+
this.props.option.gmap
6263
) {
6364
this.dispose();
6465

‎client/packages/lowcoder-comps/src/comps/chartComp/reactEcharts/index.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import * as echarts from "echarts";
2-
import { EChartsReactProps, EChartsOption,EChartsInstance } from "./types";
2+
import { EChartsReactProps, EChartsInstance,EChartsOptionWithMap } from "./types";
33
import EChartsReactCore from "./core";
44

55
/**
66
* reference: https://github.com/hustcc/echarts-for-react
77
* add exception-catch for setOption
88
* if query isn't successfully loaded, chart will fail to load and can't reload
99
*/
10-
export type { EChartsReactProps, EChartsOption, EChartsInstance };
10+
export type { EChartsReactProps, EChartsOptionWithMap, EChartsInstance };
1111

1212
// export the Component the echarts Object.
1313
export default class EChartsReact extends EChartsReactCore {

‎client/packages/lowcoder-comps/src/comps/chartComp/reactEcharts/types.ts‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { CSSProperties } from "react";
2+
import { EChartsOption } from "echarts";
3+
import { GoogleMapComponentOption } from "echarts-extension-gmap";
24

3-
export type EChartsOption = any;
5+
export type EChartsOptionWithMap = EChartsOption&GoogleMapComponentOption<any>;
46

57
export type EChartsInstance = any;
68

@@ -28,7 +30,7 @@ export type EChartsReactProps = {
2830
/**
2931
* echarts option
3032
*/
31-
readonly option: EChartsOption;
33+
readonly option: EChartsOptionWithMap;
3234
/**
3335
* echarts theme config, can be:
3436
* 1. theme name string

‎client/packages/lowcoder-comps/src/i18n/comps/locales/en.ts‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export const en = {
5757
echartsOptionLabel: "Option",
5858
echartsOptionTooltip: "ECharts option",
5959
echartsOptionExamples: "ECharts examples",
60+
echartsMapOptionTooltip: "ECharts Map Option",
61+
echartsMapOptionExamples: "ECharts Map Examples",
6062
selectDesc: "Triggered when the user selects part of the data in the chart",
6163
unselectDesc: "Triggered when the user unselects part of the data in the chart",
6264
selectedPointsDesc: "Selected points",

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /