Skip to content

Commit 3a7838e

Browse files
committed
Update widget code.
1 parent b8eb033 commit 3a7838e

File tree

7 files changed

+169
-69
lines changed

7 files changed

+169
-69
lines changed

code/exb-2025/widgets/chart-demo/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Demo Charting Widget
22

3-
A Experience Builder apps and widgets repository for demonstrational purposes that uses a 3rd party dependency.
3+
A Experience Builder apps and widgets repository for demonstrational purposes that uses a 3rd party dependency (Apache ECharts).
44

55
## Get Started
66

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
{}
1+
{
2+
"sampleCensusCountyData": "Sample Census County Data"
3+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type ImmutableObject } from 'seamless-immutable'
22

33
export interface Config {
4-
exampleConfigProperty: string
4+
sampleCensusCountyData: string
55
}
66

77
export type IMConfig = ImmutableObject<Config>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
pleaseSelectDataSource: 'Please select a data source.'
3+
}

code/exb-2025/widgets/chart-demo/src/runtime/widget.tsx

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,38 @@ import {
33
React,
44
type AllWidgetProps,
55
DataSourceComponent,
6-
type FeatureLayerDataSource
6+
type FeatureLayerDataSource,
7+
FormattedMessage,
8+
hooks
79
} from 'jimu-core'
810
import { type FeatureDataRecord } from 'jimu-arcgis'
911
import * as echarts from 'echarts'
12+
13+
/**********************************LOCAL IMPORTS*********************************/
1014
import { type IMConfig } from '../config'
15+
import defaultI18nMessages from './translations/default'
1116

12-
// DataSource: https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2
17+
// DataSource FeatureLayer: https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2
18+
// DataSource WebMap: 019fa672af30459e95ae088c650d745b
1319

1420
/******************************WIDGET FUNCTION********************************/
1521
const Widget = (props: AllWidgetProps<IMConfig>) => {
1622
/******************************LOCAL STATE********************************/
17-
// Extract the useDataSources and id from the widget's props
18-
const { useDataSources, id } = props
19-
// Create a ref for the chart div
20-
const chartRef = React.useRef<HTMLDivElement>(null)
23+
const { useDataSources, id, config } = props // Extract the useDataSources and id from the widget's props
24+
const chartRef = React.useRef<HTMLDivElement>(null) // Create a ref for the chart div
2125
// Create state variables for the data source, chart, series array, fips array, and countyState array
2226
const [dataSource, setDataSource] = React.useState<FeatureLayerDataSource>()
2327
const [chart, setChart] = React.useState<echarts.ECharts>()
2428
const [seriesArray, setSeriesArray] = React.useState<
25-
Array<{ name: string, type: string, stack: string, data: number[] }>
29+
Array<{ name: string, type: string, stack: string, data: number[], emphasize: { focus: string } }>
2630
>([])
2731
const [fipsArray, setFipsArray] = React.useState<string[]>([])
2832
const [countyStateArray, setCountyStateArray] = React.useState<string[]>([])
2933

30-
/******************************DATASOURCE FUNCTIONS********************************/
34+
// USE THE TRANSLATION HOOK
35+
const t = hooks.useTranslation(defaultI18nMessages)
3136

37+
/******************************DATASOURCE FUNCTIONS********************************/
3238
/**
3339
* Set the data source once it is created
3440
* @param dataSource - The data source set in builder configuration
@@ -54,40 +60,68 @@ const Widget = (props: AllWidgetProps<IMConfig>) => {
5460
const createChart = () => {
5561
const option = {
5662
title: {
57-
text: 'Sample Census county data'
63+
text: `${config.sampleCensusCountyData}`,
64+
textAlign: 'left',
65+
textVerticalAlign: 'top'
5866
},
5967
tooltip: {
60-
trigger: 'axis'
68+
trigger: 'axis',
69+
axisPointer: {
70+
type: 'shadow'
71+
}
6172
},
6273
legend: {
6374
data: seriesArray.map((x) => x.name),
6475
type: 'scroll',
6576
orient: 'horizontal',
66-
top: 'bottom'
77+
itemGap: 5,
78+
width: 500,
79+
left: 'center',
80+
bottom: 0
6781
},
6882
dataZoom: [
6983
{
70-
show: true,
71-
realtime: true,
72-
start: 65,
73-
end: 85
84+
type: 'slider',
85+
xAxisIndex: 0,
86+
bottom: 40,
87+
start: 0,
88+
end: 10,
89+
minSpan: 10,
90+
height: 24,
91+
fillerColor: '#d467a7',
92+
moveHandleSize: 8,
93+
moveHandleStyle: { color: '#c90076' },
94+
dataBackground: { areaStyle: { color: '#d467a7' } },
95+
selectedDataBackground: '#b30369'
96+
},
97+
{
98+
type: 'inside',
99+
xAxisIndex: 0,
100+
start: 0,
101+
end: 100,
102+
minSpan: 10
74103
},
75104
{
76105
type: 'inside',
77-
realtime: true,
78-
start: 65,
79-
end: 85
106+
yAxisIndex: 0,
107+
start: 0,
108+
end: 100,
109+
minSpan: 10
80110
}
81111
],
82112
grid: {
83113
left: '3%',
84114
right: '4%',
85-
bottom: '3%',
115+
bottom: '10%',
116+
top: '10%',
86117
containLabel: true
87118
},
88119
toolbox: {
120+
show: true,
89121
feature: {
90-
saveAsImage: {}
122+
mark: { show: true },
123+
restore: { show: true },
124+
saveAsImage: { show: true }
91125
}
92126
},
93127
xAxis: {
@@ -126,12 +160,11 @@ const Widget = (props: AllWidgetProps<IMConfig>) => {
126160
.catch((err) => {
127161
console.error(err)
128162
})
129-
// Get the max record count (page size) for the data source
130-
const pageSize = dataSource.restLayer.layerDefinition.maxRecordCount
131-
let allRecords: FeatureDataRecord[] = []
132-
let page = 1
163+
const pageSize = dataSource.restLayer.layerDefinition.maxRecordCount // Get the max record count (page size) for the data source
164+
let allRecords: FeatureDataRecord[] = [] // Create an array to hold all records
165+
let page = 1 // Set the initial page to 1
133166

134-
// Fetch all records from the data source using pagination
167+
// Fetch all records from the data source using pagination while the allRecords array is less than the record count
135168
while (allRecords.length < recordCount) {
136169
await dataSource
137170
.load(
@@ -153,7 +186,7 @@ const Widget = (props: AllWidgetProps<IMConfig>) => {
153186
})
154187
}
155188

156-
// Create arrays for the chart
189+
// Create arrays for the chart | TODO: Refactor this to be more dynamic
157190
const ageUnder5 = allRecords.map((x) => x.feature.attributes.AGE_UNDER5)
158191
const ageFive17 = allRecords.map((x) => x.feature.attributes.AGE_5_17)
159192
const ageEighteen21 = allRecords.map((x) => x.feature.attributes.AGE_18_21)
@@ -175,49 +208,91 @@ const Widget = (props: AllWidgetProps<IMConfig>) => {
175208
name: 'Age under 5',
176209
type: 'bar',
177210
stack: 'Total',
178-
data: ageUnder5
211+
data: ageUnder5,
212+
emphasize: {
213+
focus: 'series'
214+
}
179215
},
180216
{
181217
name: 'Age 5-17',
182218
type: 'bar',
183219
stack: 'Total',
184-
data: ageFive17
220+
data: ageFive17,
221+
emphasize: {
222+
focus: 'series'
223+
}
185224
},
186225
{
187226
name: 'Age 18-21',
188227
type: 'bar',
189228
stack: 'Total',
190-
data: ageEighteen21
229+
data: ageEighteen21,
230+
emphasize: {
231+
focus: 'series'
232+
}
191233
},
192234
{
193235
name: 'Age 22-29',
194236
type: 'bar',
195237
stack: 'Total',
196-
data: ageTwentyTwo29
238+
data: ageTwentyTwo29,
239+
emphasize: {
240+
focus: 'series'
241+
}
197242
},
198243
{
199244
name: 'Age 30-39',
200245
type: 'bar',
201246
stack: 'Total',
202-
data: ageThirty39
247+
data: ageThirty39,
248+
emphasize: {
249+
focus: 'series'
250+
}
203251
},
204252
{
205253
name: 'Age 40-49',
206254
type: 'bar',
207255
stack: 'Total',
208-
data: ageForty49
256+
data: ageForty49,
257+
emphasize: {
258+
focus: 'series'
259+
}
209260
},
210261
{
211262
name: 'Age 50-64',
212263
type: 'bar',
213264
stack: 'Total',
214-
data: ageFifty64
265+
data: ageFifty64,
266+
emphasize: {
267+
focus: 'series'
268+
}
215269
},
216270
{
217271
name: 'Age 65 and up',
218272
type: 'bar',
219273
stack: 'Total',
220-
data: ageSixty5up
274+
data: ageSixty5up,
275+
emphasize: {
276+
focus: 'series'
277+
}
278+
},
279+
{
280+
name: '65+',
281+
type: 'bar',
282+
stack: 'Total',
283+
data: ageSixty5up,
284+
emphasize: {
285+
focus: 'series'
286+
}
287+
},
288+
{
289+
name: 'Under 5',
290+
type: 'bar',
291+
stack: 'Total',
292+
data: ageUnder5,
293+
emphasize: {
294+
focus: 'series'
295+
}
221296
}
222297
]
223298
setCountyStateArray(countyState)
@@ -259,10 +334,15 @@ const Widget = (props: AllWidgetProps<IMConfig>) => {
259334
}
260335
}, [chart, seriesArray, countyStateArray])
261336

262-
/******************************MARK-UP********************************/
337+
/****************************MARK-UP**********************************/
263338
// If there is no data source, display a message to select a data source
264339
if (!useDataSources?.[0]) {
265-
return <div>Please select a data source</div>
340+
return (
341+
<FormattedMessage
342+
id='selectDataSource'
343+
defaultMessage={t('pleaseSelectDataSource')}
344+
/>
345+
)
266346
} else {
267347
// Return the chart and data source component
268348
return (
Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,56 @@
11
/* JIMU IMPORTS */
2-
import { React, hooks, Immutable, AllDataSourceTypes, type UseDataSource } from 'jimu-core'
3-
import { type AllWidgetSettingProps } from 'jimu-for-builder'
4-
import { SettingRow, SettingSection } from 'jimu-ui/advanced/setting-components'
5-
import { DataSourceSelector } from 'jimu-ui/advanced/data-source-selector'
6-
// TODO: https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/2
2+
import {
3+
React,
4+
hooks,
5+
Immutable,
6+
AllDataSourceTypes,
7+
type UseDataSource,
8+
} from "jimu-core";
9+
import { type AllWidgetSettingProps } from "jimu-for-builder";
10+
import {
11+
SettingRow,
12+
SettingSection,
13+
} from "jimu-ui/advanced/setting-components";
14+
import { DataSourceSelector } from "jimu-ui/advanced/data-source-selector";
715

816
/* LOCAL IMPORTS */
9-
import { type IMConfig } from '../config'
10-
import defaultI18nMessages from './translations/default'
17+
import { type IMConfig } from "../config";
18+
import defaultI18nMessages from "./translations/default";
1119

1220
/* COMPONENT */
13-
export default function Setting (props: AllWidgetSettingProps<IMConfig>) {
14-
const t = hooks.useTranslation(defaultI18nMessages)
21+
export default function Setting(props: AllWidgetSettingProps<IMConfig>) {
22+
// PROPS
23+
const { config, widgetId, useDataSources } = props;
1524

25+
// USE THE TRANSLATION HOOK
26+
const t = hooks.useTranslation(defaultI18nMessages);
27+
28+
// On data source selected, set the data source
1629
const onDataSourceSelected = (useDataSources: UseDataSource[]) => {
1730
props.onSettingChange({
18-
id: props.widgetId,
19-
useDataSources: useDataSources
20-
})
21-
}
31+
id: widgetId,
32+
useDataSources: useDataSources,
33+
});
34+
};
2235

2336
/* RENDER */
2437
return (
2538
<React.Fragment>
26-
<SettingSection title={t('dataSourceTitle')}>
27-
<SettingRow
28-
className='setting-row'
29-
label={t('dataSourcesLabel')}
30-
flow='wrap'
31-
>
32-
<DataSourceSelector
33-
types={Immutable([AllDataSourceTypes.FeatureLayer])}
34-
mustUseDataSource
35-
useDataSources={props.useDataSources}
36-
onChange={onDataSourceSelected}
37-
widgetId={props.widgetId}
38-
/>
39-
</SettingRow>
40-
</SettingSection>
39+
<SettingSection title={t("dataSourceTitle")}>
40+
<SettingRow
41+
className='setting-row'
42+
label={t("dataSourcesLabel")}
43+
flow='wrap'
44+
>
45+
<DataSourceSelector
46+
types={Immutable([AllDataSourceTypes.FeatureLayer])}
47+
mustUseDataSource
48+
useDataSources={useDataSources}
49+
onChange={onDataSourceSelected}
50+
widgetId={widgetId}
51+
/>
52+
</SettingRow>
53+
</SettingSection>
4154
</React.Fragment>
42-
)
55+
);
4356
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export default {
22
dataSourceTitle: 'Set data source',
3-
dataSourcesLabel: 'Select data source'
3+
dataSourcesLabel: 'Select data source',
4+
mapWidget: 'Map widget',
5+
dataSource: 'Data source'
46
}

0 commit comments

Comments
 (0)