diff --git a/apps/demos/Demos/FloatingActionButton/Overview/React/App.tsx b/apps/demos/Demos/FloatingActionButton/Overview/React/App.tsx index d17f9189ee5c..e45f36ea21fc 100644 --- a/apps/demos/Demos/FloatingActionButton/Overview/React/App.tsx +++ b/apps/demos/Demos/FloatingActionButton/Overview/React/App.tsx @@ -2,46 +2,47 @@ import React, { useCallback, useRef, useState } from 'react'; import config from 'devextreme/core/config'; import repaintFloatingActionButton from 'devextreme/ui/speed_dial_action/repaint_floating_action_button'; import DataGrid, { - Column, Editing, Lookup, Texts, Selection, type DataGridTypes, + Column, Editing, Lookup, Texts, Selection, } from 'devextreme-react/data-grid'; import { SpeedDialAction } from 'devextreme-react/speed-dial-action'; -import { SelectBox, type SelectBoxTypes } from 'devextreme-react/select-box'; +import { SelectBox } from 'devextreme-react/select-box'; +import type { SelectBoxTypes } from 'devextreme-react/select-box'; +import type { DataGridTypes, DataGridRef } from 'devextreme-react/data-grid'; import { - employees, states, directions, directionLabel, + employees, states, directions, optionDirections, directionLabel, } from './data.ts'; - -const optionDirections = ['auto', 'up', 'down']; +import type { DirectionKey } from './data.ts'; const App = () => { const [selectedRowIndex, setSelectedRowIndex] = useState(-1); - const gridRef = useRef(null); + const gridRef = useRef(null); const selectedChanged = useCallback((e: DataGridTypes.SelectionChangedEvent) => { setSelectedRowIndex(e.component.getRowIndexByKey(e.selectedRowKeys[0])); - }, [setSelectedRowIndex]); + }, []); const directionChanged = useCallback((e: SelectBoxTypes.SelectionChangedEvent) => { config({ - floatingActionButtonConfig: directions[e.selectedItem], + floatingActionButtonConfig: directions[e.selectedItem as DirectionKey], }); repaintFloatingActionButton(); }, []); const editRow = useCallback(() => { - gridRef.current.instance().editRow(selectedRowIndex); - gridRef.current.instance().deselectAll(); - }, [gridRef, selectedRowIndex]); + gridRef.current?.instance()?.editRow(selectedRowIndex); + gridRef.current?.instance()?.deselectAll(); + }, [selectedRowIndex]); const deleteRow = useCallback(() => { - gridRef.current.instance().deleteRow(selectedRowIndex); - gridRef.current.instance().deselectAll(); - }, [gridRef, selectedRowIndex]); + gridRef.current?.instance()?.deleteRow(selectedRowIndex); + gridRef.current?.instance()?.deselectAll(); + }, [selectedRowIndex]); const addRow = useCallback(() => { - gridRef.current.instance().addRow(); - gridRef.current.instance().deselectAll(); - }, [gridRef]); + gridRef.current?.instance()?.addRow(); + gridRef.current?.instance()?.deselectAll(); + }, []); return (
diff --git a/apps/demos/Demos/FloatingActionButton/Overview/React/data.ts b/apps/demos/Demos/FloatingActionButton/Overview/React/data.ts index bb415ae7953b..996f83765cd1 100644 --- a/apps/demos/Demos/FloatingActionButton/Overview/React/data.ts +++ b/apps/demos/Demos/FloatingActionButton/Overview/React/data.ts @@ -1,4 +1,22 @@ -export const directions = { +import type { FloatingActionButtonDirection, PositionAlignment } from 'devextreme-react/common'; + +type DirectionValue = { + icon: string; + shading: boolean; + direction?: FloatingActionButtonDirection; + position: { + of: string; + my: PositionAlignment; + at: PositionAlignment; + offset: string; + }; +}; + +export const optionDirections = ['auto', 'up', 'down'] as const; + +export type DirectionKey = typeof optionDirections[number]; + +export const directions: Record = { auto: { icon: 'rowfield', shading: true, diff --git a/apps/demos/Demos/FloatingActionButton/Overview/ReactJs/App.js b/apps/demos/Demos/FloatingActionButton/Overview/ReactJs/App.js index 804d66b8d647..f68c7a1518b7 100644 --- a/apps/demos/Demos/FloatingActionButton/Overview/ReactJs/App.js +++ b/apps/demos/Demos/FloatingActionButton/Overview/ReactJs/App.js @@ -7,19 +7,15 @@ import DataGrid, { import { SpeedDialAction } from 'devextreme-react/speed-dial-action'; import { SelectBox } from 'devextreme-react/select-box'; import { - employees, states, directions, directionLabel, + employees, states, directions, optionDirections, directionLabel, } from './data.js'; -const optionDirections = ['auto', 'up', 'down']; const App = () => { const [selectedRowIndex, setSelectedRowIndex] = useState(-1); const gridRef = useRef(null); - const selectedChanged = useCallback( - (e) => { - setSelectedRowIndex(e.component.getRowIndexByKey(e.selectedRowKeys[0])); - }, - [setSelectedRowIndex], - ); + const selectedChanged = useCallback((e) => { + setSelectedRowIndex(e.component.getRowIndexByKey(e.selectedRowKeys[0])); + }, []); const directionChanged = useCallback((e) => { config({ floatingActionButtonConfig: directions[e.selectedItem], @@ -27,17 +23,17 @@ const App = () => { repaintFloatingActionButton(); }, []); const editRow = useCallback(() => { - gridRef.current.instance().editRow(selectedRowIndex); - gridRef.current.instance().deselectAll(); - }, [gridRef, selectedRowIndex]); + gridRef.current?.instance()?.editRow(selectedRowIndex); + gridRef.current?.instance()?.deselectAll(); + }, [selectedRowIndex]); const deleteRow = useCallback(() => { - gridRef.current.instance().deleteRow(selectedRowIndex); - gridRef.current.instance().deselectAll(); - }, [gridRef, selectedRowIndex]); + gridRef.current?.instance()?.deleteRow(selectedRowIndex); + gridRef.current?.instance()?.deselectAll(); + }, [selectedRowIndex]); const addRow = useCallback(() => { - gridRef.current.instance().addRow(); - gridRef.current.instance().deselectAll(); - }, [gridRef]); + gridRef.current?.instance()?.addRow(); + gridRef.current?.instance()?.deselectAll(); + }, []); return (
{ if (arg.layer.type === 'marker') { return { text: arg.attribute('tooltip') }; } - return null; + return {}; }; -const customizeText = (arg: { index: string | number; }) => ['< 8000K', '8000K to 10000K', '> 10000K'][arg.index]; +const customizeText: ILegendProps['customizeText'] = (arg) => ['< 8000K', '8000K to 10000K', '> 10000K'][arg.index]; -const customizeItems = (items: any[]) => items.reverse(); +const customizeItems = (items: VectorMapTypes.LegendItem[]) => items.reverse(); export default function App() { return ( diff --git a/apps/demos/Demos/VectorMap/BubbleMarkers/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/BubbleMarkers/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/BubbleMarkers/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/BubbleMarkers/ReactJs/App.js b/apps/demos/Demos/VectorMap/BubbleMarkers/ReactJs/App.js index 4eef4c4ec8a5..eb8d2d43b11d 100644 --- a/apps/demos/Demos/VectorMap/BubbleMarkers/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/BubbleMarkers/ReactJs/App.js @@ -11,7 +11,7 @@ const customizeTooltip = (arg) => { if (arg.layer.type === 'marker') { return { text: arg.attribute('tooltip') }; } - return null; + return {}; }; const customizeText = (arg) => ['< 8000K', '8000K to 10000K', '> 10000K'][arg.index]; const customizeItems = (items) => items.reverse(); diff --git a/apps/demos/Demos/VectorMap/ColorsCustomization/React/App.tsx b/apps/demos/Demos/VectorMap/ColorsCustomization/React/App.tsx index ef1154c0d5bd..173c98be4261 100644 --- a/apps/demos/Demos/VectorMap/ColorsCustomization/React/App.tsx +++ b/apps/demos/Demos/VectorMap/ColorsCustomization/React/App.tsx @@ -6,16 +6,19 @@ import VectorMap, { Border, Font, } from 'devextreme-react/vector-map'; -import type { ILayerProps, ITooltipProps } from 'devextreme-react/vector-map'; +import type { ILayerProps, ITooltipProps, VectorMapTypes } from 'devextreme-react/vector-map'; import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import { countries } from './data.ts'; +type CountriesKey = keyof typeof countries; + const bounds = [-180, 85, 180, -60]; const customizeLayer: ILayerProps['customize'] = (elements) => { elements.forEach((element) => { - const country = countries[element.attribute('name')]; + const name = element.attribute('name') as CountriesKey; + const country = countries[name]; if (country) { element.applySettings({ color: country.color, @@ -26,14 +29,15 @@ const customizeLayer: ILayerProps['customize'] = (elements) => { }); }; -const clickHandler = ({ target }) => { - if (target && countries[target.attribute('name')]) { +const clickHandler = ({ target }: VectorMapTypes.ClickEvent) => { + const name = target?.attribute('name') as CountriesKey; + if (target && countries[name]) { target.selected(!target.selected()); } }; const customizeTooltip: ITooltipProps['customizeTooltip'] = ({ attribute }) => { - const name = attribute('name'); + const name = attribute('name') as CountriesKey; const country = countries[name]; if (country) { return { @@ -41,7 +45,7 @@ const customizeTooltip: ITooltipProps['customizeTooltip'] = ({ attribute }) => { color: country.color, }; } - return null; + return {}; }; export default function App() { diff --git a/apps/demos/Demos/VectorMap/ColorsCustomization/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/ColorsCustomization/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/ColorsCustomization/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/ColorsCustomization/ReactJs/App.js b/apps/demos/Demos/VectorMap/ColorsCustomization/ReactJs/App.js index 7672fcda6f5d..1aa4c7c541fc 100644 --- a/apps/demos/Demos/VectorMap/ColorsCustomization/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/ColorsCustomization/ReactJs/App.js @@ -8,7 +8,8 @@ import { countries } from './data.js'; const bounds = [-180, 85, 180, -60]; const customizeLayer = (elements) => { elements.forEach((element) => { - const country = countries[element.attribute('name')]; + const name = element.attribute('name'); + const country = countries[name]; if (country) { element.applySettings({ color: country.color, @@ -19,7 +20,8 @@ const customizeLayer = (elements) => { }); }; const clickHandler = ({ target }) => { - if (target && countries[target.attribute('name')]) { + const name = target?.attribute('name'); + if (target && countries[name]) { target.selected(!target.selected()); } }; @@ -32,7 +34,7 @@ const customizeTooltip = ({ attribute }) => { color: country.color, }; } - return null; + return {}; }; export default function App() { return ( diff --git a/apps/demos/Demos/VectorMap/CustomAnnotations/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/CustomAnnotations/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..e5de5ff1844d --- /dev/null +++ b/apps/demos/Demos/VectorMap/CustomAnnotations/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/usa.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const usa: FeatureCollection; + export { usa }; + export default usa; +} diff --git a/apps/demos/Demos/VectorMap/CustomMapData/React/App.tsx b/apps/demos/Demos/VectorMap/CustomMapData/React/App.tsx index ba49fed5555c..e402bc8c59ee 100644 --- a/apps/demos/Demos/VectorMap/CustomMapData/React/App.tsx +++ b/apps/demos/Demos/VectorMap/CustomMapData/React/App.tsx @@ -9,8 +9,8 @@ import type { ILayerProps } from 'devextreme-react/vector-map'; import { pangaeaBorders, pangaeaContinents } from './data.ts'; const projection = { - to: ([l, lt]) => [l / 100, lt / 100], - from: ([x, y]) => [x * 100, y * 100], + to: ([l, lt]: [number, number]) => [l / 100, lt / 100], + from: ([x, y]: [number, number]) => [x * 100, y * 100], }; const customizeLayer: ILayerProps['customize'] = (elements) => { diff --git a/apps/demos/Demos/VectorMap/CustomProjection/React/data.ts b/apps/demos/Demos/VectorMap/CustomProjection/React/data.ts index d1c11419a29d..c2c942c4c838 100644 --- a/apps/demos/Demos/VectorMap/CustomProjection/React/data.ts +++ b/apps/demos/Demos/VectorMap/CustomProjection/React/data.ts @@ -1,6 +1,13 @@ +interface LineFeature { + geometry: { + type: string; + coordinates: number[][]; + }; +} + export const coordLinesData = { type: 'FeatureCollection', - features: [], + features: [] as LineFeature[], }; // add meridians diff --git a/apps/demos/Demos/VectorMap/CustomProjection/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/CustomProjection/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/CustomProjection/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/DynamicViewport/React/App.tsx b/apps/demos/Demos/VectorMap/DynamicViewport/React/App.tsx index 87141ae7d8cf..6a28ecfa91c2 100644 --- a/apps/demos/Demos/VectorMap/DynamicViewport/React/App.tsx +++ b/apps/demos/Demos/VectorMap/DynamicViewport/React/App.tsx @@ -1,9 +1,11 @@ import React, { useCallback, useRef, useState } from 'react'; -import VectorMap, { Layer, ControlBar, type VectorMapTypes } from 'devextreme-react/vector-map'; +import VectorMap, { Layer, ControlBar } from 'devextreme-react/vector-map'; import TextBox from 'devextreme-react/text-box'; import SelectBox from 'devextreme-react/select-box'; import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import Switch from 'devextreme-react/switch'; +import type { VectorMapTypes, VectorMapRef } from 'devextreme-react/vector-map'; +import type { SelectBoxTypes } from 'devextreme-react/select-box'; import { viewportCoordinates, centerLabel, zoomLabel, continentLabel, } from './data.ts'; @@ -16,29 +18,29 @@ const App = () => { const [center, setCenter] = useState('0.000, 46.036'); const [panVisible, setPanVisible] = useState(true); const [zoomVisible, setZoomVisible] = useState(true); - const mapRef = useRef(null); + const mapRef = useRef(null); - const continentChanged = useCallback(({ value }) => { + const continentChanged = useCallback(({ value }: SelectBoxTypes.ValueChangedEvent) => { setCoordinates(value); - mapRef.current.instance().viewport(value); - }, [setCoordinates]); + mapRef.current?.instance().viewport(value); + }, []); const zoomFactorChanged = useCallback((e: VectorMapTypes.ZoomFactorChangedEvent) => { setZoomFactor(e.zoomFactor.toFixed(2)); - }, [setZoomFactor]); + }, []); const centerChanged = useCallback((e: VectorMapTypes.CenterChangedEvent) => { const value = `${e.center[0].toFixed(3)}, ${e.center[1].toFixed(3)}`; setCenter(value); - }, [setCenter]); + }, []); - const panVisibleChange = useCallback((value) => { + const panVisibleChange = useCallback((value: boolean) => { setPanVisible(value); - }, [setPanVisible]); + }, []); - const zoomVisibleChange = useCallback((value) => { + const zoomVisibleChange = useCallback((value: boolean) => { setZoomVisible(value); - }, [setZoomVisible]); + }, []); return (
diff --git a/apps/demos/Demos/VectorMap/DynamicViewport/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/DynamicViewport/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/DynamicViewport/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/DynamicViewport/ReactJs/App.js b/apps/demos/Demos/VectorMap/DynamicViewport/ReactJs/App.js index a65cae224f09..68e557102a30 100644 --- a/apps/demos/Demos/VectorMap/DynamicViewport/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/DynamicViewport/ReactJs/App.js @@ -16,38 +16,23 @@ const App = () => { const [panVisible, setPanVisible] = useState(true); const [zoomVisible, setZoomVisible] = useState(true); const mapRef = useRef(null); - const continentChanged = useCallback( - ({ value }) => { - setCoordinates(value); - mapRef.current.instance().viewport(value); - }, - [setCoordinates], - ); - const zoomFactorChanged = useCallback( - (e) => { - setZoomFactor(e.zoomFactor.toFixed(2)); - }, - [setZoomFactor], - ); - const centerChanged = useCallback( - (e) => { - const value = `${e.center[0].toFixed(3)}, ${e.center[1].toFixed(3)}`; - setCenter(value); - }, - [setCenter], - ); - const panVisibleChange = useCallback( - (value) => { - setPanVisible(value); - }, - [setPanVisible], - ); - const zoomVisibleChange = useCallback( - (value) => { - setZoomVisible(value); - }, - [setZoomVisible], - ); + const continentChanged = useCallback(({ value }) => { + setCoordinates(value); + mapRef.current?.instance().viewport(value); + }, []); + const zoomFactorChanged = useCallback((e) => { + setZoomFactor(e.zoomFactor.toFixed(2)); + }, []); + const centerChanged = useCallback((e) => { + const value = `${e.center[0].toFixed(3)}, ${e.center[1].toFixed(3)}`; + setCenter(value); + }, []); + const panVisibleChange = useCallback((value) => { + setPanVisible(value); + }, []); + const zoomVisibleChange = useCallback((value) => { + setZoomVisible(value); + }, []); return (
[l / 100, lt / 100], - from: ([x, y]) => [x * 100, y * 100], + to: ([l, lt]: [number, number]) => [l / 100, lt / 100], + from: ([x, y]: [number, number]) => [x * 100, y * 100], }; const customizeTooltip: ITooltipProps['customizeTooltip'] = (arg) => { if (arg.layer.name === 'rooms') { return { text: `Square: ${arg.attribute('square')} ft²` }; } - return null; + return {}; }; export default function App() { diff --git a/apps/demos/Demos/VectorMap/FloorPlan/ReactJs/App.js b/apps/demos/Demos/VectorMap/FloorPlan/ReactJs/App.js index 5a70077da92b..c50bb4626b34 100644 --- a/apps/demos/Demos/VectorMap/FloorPlan/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/FloorPlan/ReactJs/App.js @@ -10,7 +10,7 @@ const customizeTooltip = (arg) => { if (arg.layer.name === 'rooms') { return { text: `Square: ${arg.attribute('square')} ft²` }; } - return null; + return {}; }; export default function App() { return ( diff --git a/apps/demos/Demos/VectorMap/Legend/React/App.tsx b/apps/demos/Demos/VectorMap/Legend/React/App.tsx index 3dbf67df3945..21001ec9a60c 100644 --- a/apps/demos/Demos/VectorMap/Legend/React/App.tsx +++ b/apps/demos/Demos/VectorMap/Legend/React/App.tsx @@ -9,13 +9,14 @@ import VectorMap, { import type { ILayerProps, ILegendProps, ITooltipProps } from 'devextreme-react/vector-map'; import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import { populations, markers } from './data.ts'; +import type { PopulationKey } from './data.ts'; const colorGroups = [0, 0.5, 0.8, 1, 2, 3, 100]; const sizeGroups = [0, 8000, 10000, 50000]; const bounds = [-180, 85, 180, -75]; -const customizeText = (arg: { index: number; start: any; end: any; }) => { +const customizeText: ILegendProps['customizeText'] = (arg) => { if (arg.index === 0) { return '< 0.5%'; } if (arg.index === 5) { @@ -34,7 +35,7 @@ const customizeItems: ILegendProps['customizeItems'] = (items) => items.reverse( const customizeLayer: ILayerProps['customize'] = (elements) => { elements.forEach((element) => { - const name = element.attribute('name'); + const name = element.attribute('name') as PopulationKey; const population = populations[name]; if (population) { element.attribute('population', population); diff --git a/apps/demos/Demos/VectorMap/Legend/React/data.ts b/apps/demos/Demos/VectorMap/Legend/React/data.ts index 261b08e55d55..5d02b26493f5 100644 --- a/apps/demos/Demos/VectorMap/Legend/React/data.ts +++ b/apps/demos/Demos/VectorMap/Legend/React/data.ts @@ -38,6 +38,8 @@ export const populations = { Uzbekistan: 0.43, }; +export type PopulationKey = keyof typeof populations; + export const markers = { type: 'FeatureCollection', features: [ diff --git a/apps/demos/Demos/VectorMap/Legend/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/Legend/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/Legend/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/Overview/React/App.tsx b/apps/demos/Demos/VectorMap/Overview/React/App.tsx index 2a9587e8a014..142f1d142d0d 100644 --- a/apps/demos/Demos/VectorMap/Overview/React/App.tsx +++ b/apps/demos/Demos/VectorMap/Overview/React/App.tsx @@ -14,13 +14,15 @@ import type { ILegendProps, ILayerProps } from 'devextreme-react/vector-map'; import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import { countriesGDP } from './data.ts'; import TooltipTemplate from './TooltipTemplate.tsx'; +import type { CountriesGDPKey } from './data.ts'; const colorGroups = [0, 10000, 50000, 100000, 500000, 1000000, 10000000, 50000000]; const mapBounds = [-180, 85, 180, -60]; const customizeLayer: ILayerProps['customize'] = (elements) => { elements.forEach((element) => { - const countryGDPData = countriesGDP[element.attribute('name')]; + const name = element.attribute('name') as CountriesGDPKey; + const countryGDPData = countriesGDP[name]; element.attribute('total', (countryGDPData?.total) || 0); }); }; diff --git a/apps/demos/Demos/VectorMap/Overview/React/PieChartComponent.tsx b/apps/demos/Demos/VectorMap/Overview/React/PieChartComponent.tsx index 1cd37c6bba95..ab3d3d4d705c 100644 --- a/apps/demos/Demos/VectorMap/Overview/React/PieChartComponent.tsx +++ b/apps/demos/Demos/VectorMap/Overview/React/PieChartComponent.tsx @@ -9,7 +9,7 @@ import type { ILabelProps } from 'devextreme-react/pie-chart'; const customizeText: ILabelProps['customizeText'] = (pointInfo) => `${pointInfo.argument[0].toUpperCase()}${pointInfo.argument.slice(1)}: $${pointInfo.value}M`; -function PieChartComponent(props) { +function PieChartComponent(props: { data: { name: string; value: number }[] }) { return ( string; +}) { const name = info.attribute('name'); const countryGDPData = countriesGDP[name]; const total = countryGDPData?.total; diff --git a/apps/demos/Demos/VectorMap/Overview/React/data.ts b/apps/demos/Demos/VectorMap/Overview/React/data.ts index 41e0f1a3c3cd..6f87d206e060 100644 --- a/apps/demos/Demos/VectorMap/Overview/React/data.ts +++ b/apps/demos/Demos/VectorMap/Overview/React/data.ts @@ -1,4 +1,11 @@ -export const countriesGDP = { +export type CountryGDP = { + agriculture?: number; + industry?: number; + services?: number; + total?: number; +}; + +export const countriesGDP: Record = { Afghanistan: { agriculture: 34.9, industry: 25, services: 40, total: 20312, }, @@ -663,3 +670,5 @@ export const countriesGDP = { agriculture: 20.4, industry: 24.6, services: 54.9, total: 13672, }, }; + +export type CountriesGDPKey = keyof typeof countriesGDP; diff --git a/apps/demos/Demos/VectorMap/Overview/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/Overview/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..c50aa3059f60 --- /dev/null +++ b/apps/demos/Demos/VectorMap/Overview/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,28 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/Overview/ReactJs/App.js b/apps/demos/Demos/VectorMap/Overview/ReactJs/App.js index 3553e3f44afb..8ad1791ad1a5 100644 --- a/apps/demos/Demos/VectorMap/Overview/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/Overview/ReactJs/App.js @@ -18,7 +18,8 @@ const colorGroups = [0, 10000, 50000, 100000, 500000, 1000000, 10000000, 5000000 const mapBounds = [-180, 85, 180, -60]; const customizeLayer = (elements) => { elements.forEach((element) => { - const countryGDPData = countriesGDP[element.attribute('name')]; + const name = element.attribute('name'); + const countryGDPData = countriesGDP[name]; element.attribute('total', countryGDPData?.total || 0); }); }; diff --git a/apps/demos/Demos/VectorMap/Overview/ReactJs/TooltipTemplate.js b/apps/demos/Demos/VectorMap/Overview/ReactJs/TooltipTemplate.js index 86369a91748b..25495f950c04 100644 --- a/apps/demos/Demos/VectorMap/Overview/ReactJs/TooltipTemplate.js +++ b/apps/demos/Demos/VectorMap/Overview/ReactJs/TooltipTemplate.js @@ -6,11 +6,12 @@ const { format } = new Intl.NumberFormat('en-US', { minimumFractionDigits: 0, }); function getPieData(name) { - return countriesGDP[name] + const data = countriesGDP[name]; + return data ? [ - { name: 'industry', value: countriesGDP[name].industry }, - { name: 'services', value: countriesGDP[name].services }, - { name: 'agriculture', value: countriesGDP[name].agriculture }, + { name: 'industry', value: data.industry ?? 0 }, + { name: 'services', value: data.services ?? 0 }, + { name: 'agriculture', value: data.agriculture ?? 0 }, ] : null; } diff --git a/apps/demos/Demos/VectorMap/Palette/React/App.tsx b/apps/demos/Demos/VectorMap/Palette/React/App.tsx index 5d503699ba75..8866c65858da 100644 --- a/apps/demos/Demos/VectorMap/Palette/React/App.tsx +++ b/apps/demos/Demos/VectorMap/Palette/React/App.tsx @@ -10,6 +10,7 @@ import type { ILayerProps, ILegendProps, ITooltipProps } from 'devextreme-react/ import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import { populations } from './data.ts'; +import type { PopulationsKey } from './data.ts'; const colorGroups = [0, 0.5, 0.8, 1, 2, 3, 100]; @@ -17,7 +18,8 @@ const bounds = [-180, 85, 180, -60]; const customizeLayer: ILayerProps['customize'] = (elements) => { elements.forEach((element) => { - element.attribute('population', populations[element.attribute('name')]); + const name = element.attribute('name') as PopulationsKey; + element.attribute('population', populations[name]); }); }; @@ -37,7 +39,7 @@ const customizeTooltip: ITooltipProps['customizeTooltip'] = (arg) => { if (arg.attribute('population')) { return { text: `${arg.attribute('name')}: ${arg.attribute('population')}% of world population` }; } - return null; + return {}; }; export default function App() { diff --git a/apps/demos/Demos/VectorMap/Palette/React/data.ts b/apps/demos/Demos/VectorMap/Palette/React/data.ts index 905a0b6d729d..4b9c42f54c80 100644 --- a/apps/demos/Demos/VectorMap/Palette/React/data.ts +++ b/apps/demos/Demos/VectorMap/Palette/React/data.ts @@ -40,3 +40,5 @@ export const populations = { Morocco: 0.46, Uzbekistan: 0.43, }; + +export type PopulationsKey = keyof typeof populations; diff --git a/apps/demos/Demos/VectorMap/Palette/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/Palette/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/Palette/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/Palette/ReactJs/App.js b/apps/demos/Demos/VectorMap/Palette/ReactJs/App.js index 5bdfdc964b87..619b9c094315 100644 --- a/apps/demos/Demos/VectorMap/Palette/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/Palette/ReactJs/App.js @@ -9,7 +9,8 @@ const colorGroups = [0, 0.5, 0.8, 1, 2, 3, 100]; const bounds = [-180, 85, 180, -60]; const customizeLayer = (elements) => { elements.forEach((element) => { - element.attribute('population', populations[element.attribute('name')]); + const name = element.attribute('name'); + element.attribute('population', populations[name]); }); }; const customizeText = (arg) => { @@ -29,7 +30,7 @@ const customizeTooltip = (arg) => { text: `${arg.attribute('name')}: ${arg.attribute('population')}% of world population`, }; } - return null; + return {}; }; export default function App() { return ( diff --git a/apps/demos/Demos/VectorMap/PieMarkers/React/App.tsx b/apps/demos/Demos/VectorMap/PieMarkers/React/App.tsx index 6708af986782..3cc132a89873 100644 --- a/apps/demos/Demos/VectorMap/PieMarkers/React/App.tsx +++ b/apps/demos/Demos/VectorMap/PieMarkers/React/App.tsx @@ -17,7 +17,7 @@ const customizeTooltip: ITooltipProps['customizeTooltip'] = (arg) => { text: arg.attribute('tooltip'), }; } - return null; + return {}; }; const customizeText: ILegendProps['customizeText'] = (arg) => names[arg.index]; diff --git a/apps/demos/Demos/VectorMap/PieMarkers/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/PieMarkers/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/PieMarkers/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/PieMarkers/ReactJs/App.js b/apps/demos/Demos/VectorMap/PieMarkers/ReactJs/App.js index f2c2c4e89d32..d43bfaf031ab 100644 --- a/apps/demos/Demos/VectorMap/PieMarkers/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/PieMarkers/ReactJs/App.js @@ -12,7 +12,7 @@ const customizeTooltip = (arg) => { text: arg.attribute('tooltip'), }; } - return null; + return {}; }; const customizeText = (arg) => names[arg.index]; export default function App() { diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/App.tsx b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/App.tsx index 36b5006af478..7ac6b1a86cd3 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/App.tsx +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/App.tsx @@ -16,6 +16,7 @@ import type { ILayerProps, ILegendProps } from 'devextreme-react/vector-map'; import * as mapsData from 'devextreme-dist/js/vectormap-data/world.js'; import { countriesGDP } from './data.ts'; import TooltipTemplate from './TooltipTemplate.tsx'; +import type { CountriesGDPKey } from './data.ts'; const colorGroups = [0, 10000, 50000, 100000, 500000, 1000000, 10000000, 50000000]; const mapBounds = [-180, 85, 180, -60]; @@ -26,7 +27,8 @@ const { format } = new Intl.NumberFormat('en-US', { const customizeLayer: ILayerProps['customize'] = (elements) => { elements.forEach((element) => { - const countryGDPData = countriesGDP[element.attribute('name')]; + const name = element.attribute('name') as CountriesGDPKey; + const countryGDPData = countriesGDP[name]; element.attribute('total', (countryGDPData?.total) || 0); }); }; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/PieChartComponent.tsx b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/PieChartComponent.tsx index 36d35644e815..8db7f96a6c1d 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/PieChartComponent.tsx +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/PieChartComponent.tsx @@ -6,7 +6,18 @@ import PieChart, { Connector, } from 'devextreme-react/pie-chart'; -function PieChartComponent(props) { +import type { ILabelProps } from 'devextreme-react/pie-chart'; + +interface PieChartDataItem { + name: string; + value: number; +} + +interface PieChartComponentProps { + data: PieChartDataItem[]; +} + +function PieChartComponent(props: PieChartComponentProps) { return ( `${pointInfo.argument[0].toUpperCase()}${ + pointInfo.argument.slice(1) +}: $${pointInfo.value}M`; export default PieChartComponent; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/TooltipTemplate.tsx b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/TooltipTemplate.tsx index 965051cccd1b..8bee897cc9b2 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/TooltipTemplate.tsx +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/TooltipTemplate.tsx @@ -7,15 +7,16 @@ const { format } = new Intl.NumberFormat('en-US', { minimumFractionDigits: 0, }); -function getPieData(name: string | number) { - return countriesGDP[name] ? [ - { name: 'industry', value: countriesGDP[name].industry }, - { name: 'services', value: countriesGDP[name].services }, - { name: 'agriculture', value: countriesGDP[name].agriculture }, +function getPieData(name: string) { + const data = countriesGDP[name]; + return data ? [ + { name: 'industry', value: data.industry ?? 0 }, + { name: 'services', value: data.services ?? 0 }, + { name: 'agriculture', value: data.agriculture ?? 0 }, ] : null; } -export default function TooltipTemplate(info) { +export default function TooltipTemplate(info: { attribute: (name: string) => string; }) { const name = info.attribute('name'); const countryGDPData = countriesGDP[name]; const total = countryGDPData?.total; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/data.ts b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/data.ts index 41e0f1a3c3cd..6f87d206e060 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/data.ts +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/data.ts @@ -1,4 +1,11 @@ -export const countriesGDP = { +export type CountryGDP = { + agriculture?: number; + industry?: number; + services?: number; + total?: number; +}; + +export const countriesGDP: Record = { Afghanistan: { agriculture: 34.9, industry: 25, services: 40, total: 20312, }, @@ -663,3 +670,5 @@ export const countriesGDP = { agriculture: 20.4, industry: 24.6, services: 54.9, total: 13672, }, }; + +export type CountriesGDPKey = keyof typeof countriesGDP; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/App.js b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/App.js index 439f6de3f066..82cf573edf2b 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/App.js @@ -21,7 +21,8 @@ const { format } = new Intl.NumberFormat('en-US', { }); const customizeLayer = (elements) => { elements.forEach((element) => { - const countryGDPData = countriesGDP[element.attribute('name')]; + const name = element.attribute('name'); + const countryGDPData = countriesGDP[name]; element.attribute('total', countryGDPData?.total || 0); }); }; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/PieChartComponent.js b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/PieChartComponent.js index b9323e6dc088..180bb0ccd78b 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/PieChartComponent.js +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/PieChartComponent.js @@ -28,9 +28,6 @@ function PieChartComponent(props) { ); } -function customizeText(pointInfo) { - return `${pointInfo.argument[0].toUpperCase()}${pointInfo.argument.slice(1)}: $${ - pointInfo.value - }M`; -} +const customizeText = (pointInfo) => + `${pointInfo.argument[0].toUpperCase()}${pointInfo.argument.slice(1)}: $${pointInfo.value}M`; export default PieChartComponent; diff --git a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/TooltipTemplate.js b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/TooltipTemplate.js index 86369a91748b..25495f950c04 100644 --- a/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/TooltipTemplate.js +++ b/apps/demos/Demos/VectorMap/TooltipsCustomization/ReactJs/TooltipTemplate.js @@ -6,11 +6,12 @@ const { format } = new Intl.NumberFormat('en-US', { minimumFractionDigits: 0, }); function getPieData(name) { - return countriesGDP[name] + const data = countriesGDP[name]; + return data ? [ - { name: 'industry', value: countriesGDP[name].industry }, - { name: 'services', value: countriesGDP[name].services }, - { name: 'agriculture', value: countriesGDP[name].agriculture }, + { name: 'industry', value: data.industry ?? 0 }, + { name: 'services', value: data.services ?? 0 }, + { name: 'agriculture', value: data.agriculture ?? 0 }, ] : null; } diff --git a/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/App.tsx b/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/App.tsx index d88795df2b22..0b13fc651d7f 100644 --- a/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/App.tsx +++ b/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/App.tsx @@ -3,7 +3,7 @@ import VectorMap, { Layer, Tooltip, } from 'devextreme-react/vector-map'; -import type { VectorMapTypes, ITooltipProps } from 'devextreme-react/vector-map'; +import type { VectorMapTypes, ITooltipProps, VectorMapRef } from 'devextreme-react/vector-map'; import Button from 'devextreme-react/button'; @@ -16,7 +16,7 @@ const customizeTooltip: ITooltipProps['customizeTooltip'] = (arg) => { if (arg.layer.type === 'marker') { return { text: arg.attribute('name') }; } - return null; + return {}; }; const markerClick = (e: VectorMapTypes.ClickEvent) => { @@ -27,12 +27,12 @@ const markerClick = (e: VectorMapTypes.ClickEvent) => { }; const App = () => { - const vectorMapRef = useRef(null); + const vectorMapRef = useRef(null); const reset = useCallback(() => { - vectorMapRef.current.instance().center(null); - vectorMapRef.current.instance().zoomFactor(null); - }, [vectorMapRef]); + vectorMapRef.current?.instance().center([0, 0]); + vectorMapRef.current?.instance().zoomFactor(1); + }, []); return ( <> diff --git a/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/devextreme-vectormap-data.d.ts b/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/devextreme-vectormap-data.d.ts new file mode 100644 index 000000000000..370ec277e5ea --- /dev/null +++ b/apps/demos/Demos/VectorMap/ZoomingAndCentering/React/devextreme-vectormap-data.d.ts @@ -0,0 +1,27 @@ +declare module 'devextreme-dist/js/vectormap-data/world.js' { + type Position = number[]; + type Geometry = + | { type: 'Point'; coordinates: Position } + | { type: 'MultiPoint'; coordinates: Position[] } + | { type: 'LineString'; coordinates: Position[] } + | { type: 'MultiLineString'; coordinates: Position[][] } + | { type: 'Polygon'; coordinates: Position[][] } + | { type: 'MultiPolygon'; coordinates: Position[][][] }; + + interface Feature { + type: 'Feature'; + geometry: Geometry; + properties: Record; + } + + interface FeatureCollection { + type: 'FeatureCollection'; + features: Feature[]; + // eslint-disable-next-line spellcheck/spell-checker + bbox?: number[]; + } + + const world: FeatureCollection; + export { world }; + export default world; +} diff --git a/apps/demos/Demos/VectorMap/ZoomingAndCentering/ReactJs/App.js b/apps/demos/Demos/VectorMap/ZoomingAndCentering/ReactJs/App.js index b876c84f5f29..ef26685b939e 100644 --- a/apps/demos/Demos/VectorMap/ZoomingAndCentering/ReactJs/App.js +++ b/apps/demos/Demos/VectorMap/ZoomingAndCentering/ReactJs/App.js @@ -9,7 +9,7 @@ const customizeTooltip = (arg) => { if (arg.layer.type === 'marker') { return { text: arg.attribute('name') }; } - return null; + return {}; }; const markerClick = (e) => { if (e.target?.layer.type === 'marker') { @@ -20,9 +20,9 @@ const markerClick = (e) => { const App = () => { const vectorMapRef = useRef(null); const reset = useCallback(() => { - vectorMapRef.current.instance().center(null); - vectorMapRef.current.instance().zoomFactor(null); - }, [vectorMapRef]); + vectorMapRef.current?.instance().center([0, 0]); + vectorMapRef.current?.instance().zoomFactor(1); + }, []); return ( <>