@wavemaker/react-native-echarts 1.0.0-dev.11 → 1.0.0-dev.12

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/README.md CHANGED
@@ -182,6 +182,30 @@ Preview thumbnails for the chart examples in `assets/images/charts`. Each image
182
182
  </tbody>
183
183
  </table>
184
184
 
185
+ ### Heatmap
186
+
187
+ <table>
188
+ <tbody>
189
+ <tr>
190
+ <td align="center">
191
+ <a href="https://wavemaker.github.io/wm-react-native-echarts/?path=/story/charts-heatmap--default" target="_blank">
192
+ <img src="assets/images/charts/heatmap/default.png" width="200" height="200" alt="Heatmap default" style="object-fit: contain;" /><br /><sub>default</sub>
193
+ </a>
194
+ </td>
195
+ <td align="center">
196
+ <a href="https://wavemaker.github.io/wm-react-native-echarts/?path=/story/charts-heatmap-labels--with-cell-labels" target="_blank">
197
+ <img src="assets/images/charts/heatmap/with-cell-labels.png" width="200" height="200" alt="Heatmap with cell labels" style="object-fit: contain;" /><br /><sub>with-cell-labels</sub>
198
+ </a>
199
+ </td>
200
+ <td align="center">
201
+ <a href="https://wavemaker.github.io/wm-react-native-echarts/?path=/story/charts-heatmap-colors--custom-colors" target="_blank">
202
+ <img src="assets/images/charts/heatmap/custom-colors.png" width="200" height="200" alt="Heatmap custom colors" style="object-fit: contain;" /><br /><sub>custom-colors</sub>
203
+ </a>
204
+ </td>
205
+ </tr>
206
+ </tbody>
207
+ </table>
208
+
185
209
  ### Gauge
186
210
 
187
211
  <table>
@@ -0,0 +1,13 @@
1
+ import type { HeatmapChartProps } from './heatmap-chart.props';
2
+ import React from 'react';
3
+ /** common -> heatmap */
4
+ export type { HeatmapChartProps, HeatmapDataPoint, HeatmapChartSelectEvent, } from './heatmap-chart.props';
5
+ export declare const HeatmapChart: ((props: HeatmapChartProps & {
6
+ theme?: Partial<import("..").ChartTheme>;
7
+ } & {
8
+ width?: number | string;
9
+ height?: number | string;
10
+ }) => React.JSX.Element) & {
11
+ displayName: string;
12
+ };
13
+ //# sourceMappingURL=heatmap-chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-chart.d.ts","sourceRoot":"","sources":["../../../../components/chart/heatmap/heatmap-chart.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAA2B,MAAM,uBAAuB,CAAC;AASxF,OAAO,KAAqC,MAAM,OAAO,CAAC;AAM1D,wBAAwB;AACxB,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAgQ/B,eAAO,MAAM,YAAY;;;;;;;CAEvB,CAAC"}
@@ -0,0 +1,232 @@
1
+ import { withResponsiveContainer } from '../chart-container';
2
+ import { useChartTheme, withChartTheme } from '../chart-theme.context';
3
+ import { SkiaChart, SkiaRenderer } from '@wuba/react-native-echarts';
4
+ import { HeatmapChart as EChartsHeatmapChart } from 'echarts/charts';
5
+ import { GridComponent, TooltipComponent, VisualMapComponent, } from 'echarts/components';
6
+ import * as echarts from 'echarts/core';
7
+ import React, { useEffect, useMemo, useRef } from 'react';
8
+ import { View } from 'react-native';
9
+ import { axisTooltipShowContentFlag } from '../cartesian/tooltip';
10
+ import { createHeatmapTooltipPreset, useHeatmapItemTooltip } from './tooltip';
11
+ echarts.use([
12
+ TooltipComponent,
13
+ GridComponent,
14
+ VisualMapComponent,
15
+ SkiaRenderer,
16
+ EChartsHeatmapChart,
17
+ ]);
18
+ const SERIES_NAME = 'Heatmap';
19
+ const ChartComponent = ({ xAxisData, yAxisData, data, width = 320, height = 300, showLabel = false, showXAxis = true, showYAxis = true, showHighlighter = true, tooltip = 'card', onSelect, renderTooltip, ...props }) => {
20
+ const { theme } = useChartTheme(props.theme, props.colors);
21
+ const chartRef = useRef(null);
22
+ const onSelectRef = useRef(onSelect);
23
+ onSelectRef.current = onSelect;
24
+ const selectContextRef = useRef({
25
+ xAxisData: [],
26
+ yAxisData: [],
27
+ data: [],
28
+ seriesName: SERIES_NAME,
29
+ });
30
+ const themeSeriesRef = useRef(theme.series);
31
+ themeSeriesRef.current = theme.series;
32
+ const tooltipOverlayActive = renderTooltip != null || tooltip !== 'none';
33
+ const renderTooltipFn = useMemo(() => {
34
+ if (renderTooltip != null)
35
+ return renderTooltip;
36
+ if (tooltip === 'none')
37
+ return () => null;
38
+ return createHeatmapTooltipPreset(tooltip);
39
+ }, [renderTooltip, tooltip]);
40
+ const { attachHeatmapItemTooltipListeners, renderHeatmapTooltipOverlay } = useHeatmapItemTooltip({
41
+ active: tooltipOverlayActive,
42
+ renderTooltip: renderTooltipFn,
43
+ contextRef: selectContextRef,
44
+ themeSeriesRef,
45
+ width,
46
+ height,
47
+ });
48
+ const normalizedData = useMemo(() => {
49
+ if (!Array.isArray(data))
50
+ return [];
51
+ return data.filter((row) => Array.isArray(row) &&
52
+ row.length >= 3 &&
53
+ Number.isFinite(Number(row[0])) &&
54
+ Number.isFinite(Number(row[1])) &&
55
+ Number.isFinite(Number(row[2])));
56
+ }, [data]);
57
+ selectContextRef.current = {
58
+ xAxisData: xAxisData ?? [],
59
+ yAxisData: yAxisData ?? [],
60
+ data: normalizedData,
61
+ seriesName: SERIES_NAME,
62
+ };
63
+ const valueRange = useMemo(() => {
64
+ if (normalizedData.length === 0)
65
+ return { min: 0, max: 10 };
66
+ const values = normalizedData.map((d) => Number(d[2]));
67
+ const min = Math.min(...values);
68
+ const max = Math.max(...values);
69
+ return { min: min === max ? min - 1 : min, max: min === max ? max + 1 : max };
70
+ }, [normalizedData]);
71
+ const option = useMemo(() => {
72
+ const seriesColor = theme.series[0]?.color ?? '#3b82f6';
73
+ const tooltipConfig = tooltipOverlayActive
74
+ ? {
75
+ trigger: 'item',
76
+ ...axisTooltipShowContentFlag(true),
77
+ }
78
+ : { show: false };
79
+ const xAxisConfig = {
80
+ type: 'category',
81
+ data: xAxisData,
82
+ splitArea: { show: true },
83
+ axisLabel: {
84
+ show: showXAxis,
85
+ color: theme.axis.x.tickLabelColor,
86
+ },
87
+ axisLine: showXAxis
88
+ ? {
89
+ show: true,
90
+ lineStyle: {
91
+ color: theme.axis.x.lineColor,
92
+ width: theme.axis.x.lineWidth,
93
+ },
94
+ }
95
+ : { show: false },
96
+ axisTick: { show: showXAxis },
97
+ splitLine: { show: false },
98
+ };
99
+ const yAxisConfig = {
100
+ type: 'category',
101
+ data: yAxisData,
102
+ splitArea: { show: true },
103
+ axisLabel: {
104
+ show: showYAxis,
105
+ color: theme.axis.y.tickLabelColor,
106
+ },
107
+ axisLine: showYAxis
108
+ ? {
109
+ show: true,
110
+ lineStyle: {
111
+ color: theme.axis.y.lineColor,
112
+ width: theme.axis.y.lineWidth,
113
+ },
114
+ }
115
+ : { show: false },
116
+ axisTick: { show: showYAxis },
117
+ splitLine: { show: false },
118
+ };
119
+ const grid = {
120
+ top: '8%',
121
+ left: '12%',
122
+ right: '4%',
123
+ bottom: '8%',
124
+ containLabel: true,
125
+ };
126
+ const seriesConfig = {
127
+ name: SERIES_NAME,
128
+ type: 'heatmap',
129
+ data: normalizedData,
130
+ label: {
131
+ show: showLabel,
132
+ color: theme.legend.textColor,
133
+ },
134
+ emphasis: showHighlighter
135
+ ? {
136
+ itemStyle: {
137
+ shadowBlur: 10,
138
+ shadowColor: 'rgba(0, 0, 0, 0.35)',
139
+ },
140
+ }
141
+ : { disabled: true },
142
+ };
143
+ const config = {
144
+ tooltip: tooltipConfig,
145
+ grid,
146
+ xAxis: xAxisConfig,
147
+ yAxis: yAxisConfig,
148
+ series: [seriesConfig],
149
+ };
150
+ config.visualMap = {
151
+ type: 'continuous',
152
+ min: valueRange.min,
153
+ max: valueRange.max,
154
+ show: false,
155
+ inRange: {
156
+ color: [theme.series[1]?.color ?? '#93c5fd', seriesColor],
157
+ },
158
+ };
159
+ return config;
160
+ }, [
161
+ xAxisData,
162
+ yAxisData,
163
+ normalizedData,
164
+ theme,
165
+ showLabel,
166
+ showXAxis,
167
+ showYAxis,
168
+ showHighlighter,
169
+ tooltipOverlayActive,
170
+ valueRange,
171
+ ]);
172
+ useEffect(() => {
173
+ let chart;
174
+ let detachHeatmapTooltip = () => { };
175
+ if (chartRef.current) {
176
+ try {
177
+ chart = echarts.init(chartRef.current, 'light', { width, height });
178
+ chart.setOption(option);
179
+ detachHeatmapTooltip = attachHeatmapItemTooltipListeners(chart);
180
+ const handleHeatmapClick = (params) => {
181
+ const cb = onSelectRef.current;
182
+ if (typeof cb !== 'function')
183
+ return;
184
+ if (params.componentType !== 'series')
185
+ return;
186
+ if (params.seriesType !== 'heatmap')
187
+ return;
188
+ const raw = (Array.isArray(params.data) ? params.data : params.data?.value) ??
189
+ (Array.isArray(params.value) ? params.value : undefined);
190
+ if (!raw || raw.length < 3)
191
+ return;
192
+ const xIndex = Number(raw[0]);
193
+ const yIndex = Number(raw[1]);
194
+ const value = Number(raw[2]);
195
+ if (!Number.isFinite(xIndex) || !Number.isFinite(yIndex) || !Number.isFinite(value))
196
+ return;
197
+ const event = {
198
+ xIndex,
199
+ yIndex,
200
+ xLabel: xAxisData[xIndex] ?? String(xIndex),
201
+ yLabel: yAxisData[yIndex] ?? String(yIndex),
202
+ value,
203
+ };
204
+ cb(event);
205
+ };
206
+ chart.on('click', handleHeatmapClick);
207
+ }
208
+ catch (error) {
209
+ console.warn('HeatmapChart initialization error:', error);
210
+ }
211
+ }
212
+ return () => {
213
+ detachHeatmapTooltip();
214
+ if (chart) {
215
+ try {
216
+ chart.dispose();
217
+ }
218
+ catch (error) {
219
+ console.warn('HeatmapChart disposal error:', error);
220
+ }
221
+ }
222
+ };
223
+ }, [option, width, height, attachHeatmapItemTooltipListeners, xAxisData, yAxisData]);
224
+ return (<View style={{ width, height, position: 'relative' }}>
225
+ <SkiaChart ref={chartRef} useRNGH/>
226
+ {renderHeatmapTooltipOverlay()}
227
+ </View>);
228
+ };
229
+ const HeatmapChartComponent = withResponsiveContainer(withChartTheme(ChartComponent));
230
+ export const HeatmapChart = Object.assign(HeatmapChartComponent, {
231
+ displayName: 'HeatmapChart',
232
+ });
@@ -0,0 +1,44 @@
1
+ import type { CommonChartProps } from '../props/common';
2
+ import type { ChartTooltipOption } from '../tooltip';
3
+ import type { ReactNode } from 'react';
4
+ import type { HeatmapItemTooltipParams } from './tooltip/heatmap-item-tooltip.types';
5
+ /** Single heatmap cell: `[xIndex, yIndex, value]` using indices into {@link HeatmapChartProps.xAxisData} / `yAxisData`. */
6
+ export type HeatmapDataPoint = [number, number, number];
7
+ /** Emitted when the user taps/clicks a heatmap cell. */
8
+ export interface HeatmapChartSelectEvent {
9
+ xIndex: number;
10
+ yIndex: number;
11
+ xLabel: string;
12
+ yLabel: string;
13
+ value: number;
14
+ }
15
+ /**
16
+ * Props for HeatmapChart.
17
+ * common -> heatmap (matrix chart with category axes)
18
+ */
19
+ export interface HeatmapChartProps extends CommonChartProps {
20
+ /** Category labels for the X axis (columns). */
21
+ xAxisData: string[];
22
+ /** Category labels for the Y axis (rows). */
23
+ yAxisData: string[];
24
+ /** Cell values as `[xIndex, yIndex, value]` tuples. */
25
+ data: HeatmapDataPoint[];
26
+ /** When true, shows the numeric value on each cell. @default false */
27
+ showLabel?: boolean;
28
+ /** Whether to emphasize the hovered cell. @default true */
29
+ showHighlighter?: boolean;
30
+ /** Whether to show the X-axis line and category labels. @default true */
31
+ showXAxis?: boolean;
32
+ /** Whether to show the Y-axis line and category labels. @default true */
33
+ showYAxis?: boolean;
34
+ /**
35
+ * Built-in cell tooltip preset when `renderTooltip` is omitted. Use `none` to hide the overlay.
36
+ * @default 'card'
37
+ */
38
+ tooltip?: ChartTooltipOption;
39
+ /** Overrides the default React Native item tooltip body (see {@link HeatmapItemTooltipParams}). */
40
+ renderTooltip?: (params: HeatmapItemTooltipParams) => ReactNode;
41
+ /** Called when the user selects (taps/clicks) a heatmap cell. */
42
+ onSelect?: (event: HeatmapChartSelectEvent) => void;
43
+ }
44
+ //# sourceMappingURL=heatmap-chart.props.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-chart.props.d.ts","sourceRoot":"","sources":["../../../../components/chart/heatmap/heatmap-chart.props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAErF,2HAA2H;AAC3H,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAExD,wDAAwD;AACxD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,gDAAgD;IAChD,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,uDAAuD;IACvD,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,mGAAmG;IACnG,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,SAAS,CAAC;IAChE,iEAAiE;IACjE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACrD"}
File without changes
@@ -0,0 +1,4 @@
1
+ export { HeatmapChart } from './heatmap-chart';
2
+ export type { HeatmapChartProps, HeatmapDataPoint, HeatmapChartSelectEvent, } from './heatmap-chart.props';
3
+ export * from './tooltip';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/chart/heatmap/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,GACxB,MAAM,uBAAuB,CAAC;AAC/B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { HeatmapChart } from './heatmap-chart';
2
+ export * from './tooltip';
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { ChartTooltipPreset } from '../../tooltip';
3
+ import type { HeatmapItemTooltipParams } from './heatmap-item-tooltip.types';
4
+ export declare function createHeatmapTooltipPreset(preset: ChartTooltipPreset): (params: HeatmapItemTooltipParams) => React.ReactElement;
5
+ //# sourceMappingURL=heatmap-item-tooltip-presets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-item-tooltip-presets.d.ts","sourceRoot":"","sources":["../../../../../components/chart/heatmap/tooltip/heatmap-item-tooltip-presets.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAOxD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAoD7E,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,GACzB,CAAC,MAAM,EAAE,wBAAwB,KAAK,KAAK,CAAC,YAAY,CAY1D"}
@@ -0,0 +1,41 @@
1
+ import React from 'react';
2
+ import { Text } from 'react-native';
3
+ import { TooltipPresetCard, TooltipPresetCompact, TooltipPresetKpi, TooltipPresetStriped, } from '../../tooltip/chart-tooltip-preset-shells';
4
+ function heatmapCardFromParams(p) {
5
+ const { seriesName, xLabel, yLabel, value, color } = p;
6
+ return (<TooltipPresetCard header={{ swatchColor: color, title: seriesName }}>
7
+ <Text style={{ fontSize: 12, color: '#64748b' }}>
8
+ {yLabel} · {xLabel}
9
+ </Text>
10
+ <Text style={{ fontSize: 14, fontWeight: '700', color: '#0f172a', marginTop: 4 }}>{String(value)}</Text>
11
+ </TooltipPresetCard>);
12
+ }
13
+ function heatmapCompactFromParams(p) {
14
+ const { seriesName, xLabel, yLabel, value } = p;
15
+ return (<TooltipPresetCompact emphasis={seriesName} detail={`${yLabel} · ${xLabel}: ${String(value)}`} wrap/>);
16
+ }
17
+ function heatmapKpiFromParams(p) {
18
+ const { seriesName, xLabel, yLabel, value, color } = p;
19
+ return (<TooltipPresetKpi accentColor={color ?? '#3b82f6'} minWidth={140} overline={seriesName} metric={String(value)} caption={`${yLabel} at ${xLabel}`}/>);
20
+ }
21
+ function heatmapStripedFromParams(p) {
22
+ const { seriesName, xLabel, yLabel, value, color } = p;
23
+ return (<TooltipPresetStriped headerSwatch={{ color: color ?? '#64748b', title: seriesName }} rows={[
24
+ { key: 'row', leftLabel: 'row', right: yLabel },
25
+ { key: 'col', leftLabel: 'col', right: xLabel },
26
+ { key: 'value', leftLabel: 'value', right: String(value) },
27
+ ]}/>);
28
+ }
29
+ export function createHeatmapTooltipPreset(preset) {
30
+ switch (preset) {
31
+ case 'card':
32
+ return (p) => heatmapCardFromParams(p);
33
+ case 'compact':
34
+ return (p) => heatmapCompactFromParams(p);
35
+ case 'kpi':
36
+ return (p) => heatmapKpiFromParams(p);
37
+ case 'striped':
38
+ return (p) => heatmapStripedFromParams(p);
39
+ }
40
+ throw new Error(`Unknown tooltip preset: ${String(preset)}`);
41
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Item tooltip payload for heatmap cells (ECharts `trigger: 'item'`, `seriesType: 'heatmap'`).
3
+ */
4
+ export interface HeatmapItemTooltipParams {
5
+ pointerX: number;
6
+ pointerY: number;
7
+ seriesIndex: number;
8
+ dataIndex: number;
9
+ seriesName: string;
10
+ xIndex: number;
11
+ yIndex: number;
12
+ xLabel: string;
13
+ yLabel: string;
14
+ value: number;
15
+ color?: string;
16
+ }
17
+ export interface HeatmapItemTooltipContext {
18
+ xAxisData: string[];
19
+ yAxisData: string[];
20
+ data: Array<[number, number, number]>;
21
+ seriesName?: string;
22
+ }
23
+ //# sourceMappingURL=heatmap-item-tooltip.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-item-tooltip.types.d.ts","sourceRoot":"","sources":["../../../../../components/chart/heatmap/tooltip/heatmap-item-tooltip.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,3 @@
1
+ /**
2
+ * Item tooltip payload for heatmap cells (ECharts `trigger: 'item'`, `seriesType: 'heatmap'`).
3
+ */
@@ -0,0 +1,8 @@
1
+ import type { HeatmapItemTooltipContext, HeatmapItemTooltipParams } from './heatmap-item-tooltip.types';
2
+ /**
3
+ * Build heatmap tooltip params from an ECharts `showTip` action and chart instance.
4
+ */
5
+ export declare function heatmapItemParamsFromShowTip(chart: any, evt: any, ctx: HeatmapItemTooltipContext, themeSeries: Array<{
6
+ color: string;
7
+ }>): HeatmapItemTooltipParams | null;
8
+ //# sourceMappingURL=heatmap-item-tooltip.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heatmap-item-tooltip.utils.d.ts","sourceRoot":"","sources":["../../../../../components/chart/heatmap/tooltip/heatmap-item-tooltip.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAoCxG;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,GAAG,EACV,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,yBAAyB,EAC9B,WAAW,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACpC,wBAAwB,GAAG,IAAI,CAkDjC"}
@@ -0,0 +1,87 @@
1
+ function resolveDataIndexInside(data, evt) {
2
+ if (typeof evt?.dataIndexInside === 'number' && !Number.isNaN(evt.dataIndexInside)) {
3
+ return evt.dataIndexInside;
4
+ }
5
+ if (typeof evt?.dataIndex === 'number' && !Number.isNaN(evt.dataIndex)) {
6
+ const mapped = typeof data?.indexOfRawIndex === 'function' ? data.indexOfRawIndex(evt.dataIndex) : evt.dataIndex;
7
+ if (typeof mapped === 'number' && !Number.isNaN(mapped))
8
+ return mapped;
9
+ }
10
+ return null;
11
+ }
12
+ function heatmapItemPixel(chart, seriesModel, data, diInside) {
13
+ const layout = data.getItemLayout?.(diInside);
14
+ if (layout && Number.isFinite(layout.x) && Number.isFinite(layout.y)) {
15
+ const w = typeof layout.width === 'number' ? layout.width : 0;
16
+ const h = typeof layout.height === 'number' ? layout.height : 0;
17
+ return { x: layout.x + w / 2, y: layout.y + h / 2 };
18
+ }
19
+ try {
20
+ const dims = data.dimensions ?? [];
21
+ if (dims.length >= 2 && typeof chart.convertToPixel === 'function') {
22
+ const v0 = data.get(dims[0], diInside);
23
+ const v1 = data.get(dims[1], diInside);
24
+ const pt = chart.convertToPixel({ seriesIndex: seriesModel.seriesIndex }, [v0, v1]);
25
+ if (Array.isArray(pt) && pt.length >= 2 && Number.isFinite(pt[0]) && Number.isFinite(pt[1])) {
26
+ return { x: pt[0], y: pt[1] };
27
+ }
28
+ }
29
+ }
30
+ catch {
31
+ /* ignore */
32
+ }
33
+ return null;
34
+ }
35
+ /**
36
+ * Build heatmap tooltip params from an ECharts `showTip` action and chart instance.
37
+ */
38
+ export function heatmapItemParamsFromShowTip(chart, evt, ctx, themeSeries) {
39
+ if (!chart || !evt)
40
+ return null;
41
+ if (Array.isArray(evt.dataByCoordSys) && evt.dataByCoordSys.length > 0)
42
+ return null;
43
+ const si = evt.seriesIndex;
44
+ if (typeof si !== 'number' || si < 0)
45
+ return null;
46
+ const seriesModel = chart.getModel?.().getSeriesByIndex?.(si);
47
+ const seriesKind = seriesModel?.subType ?? seriesModel?.get?.('type');
48
+ if (!seriesModel || seriesKind !== 'heatmap')
49
+ return null;
50
+ const data = seriesModel.getData?.();
51
+ if (!data)
52
+ return null;
53
+ const diInside = resolveDataIndexInside(data, evt);
54
+ if (diInside == null || diInside < 0)
55
+ return null;
56
+ const pixel = heatmapItemPixel(chart, seriesModel, data, diInside);
57
+ if (!pixel)
58
+ return null;
59
+ const row = ctx.data[diInside];
60
+ if (!row || row.length < 3)
61
+ return null;
62
+ const xIndex = Number(row[0]);
63
+ const yIndex = Number(row[1]);
64
+ const value = Number(row[2]);
65
+ if (!Number.isFinite(xIndex) || !Number.isFinite(yIndex) || !Number.isFinite(value))
66
+ return null;
67
+ const xLabel = ctx.xAxisData[xIndex] ?? String(xIndex);
68
+ const yLabel = ctx.yAxisData[yIndex] ?? String(yIndex);
69
+ const seriesName = ctx.seriesName != null && ctx.seriesName !== ''
70
+ ? String(ctx.seriesName)
71
+ : `Series ${si + 1}`;
72
+ const themeLen = Math.max(themeSeries.length, 1);
73
+ const color = themeSeries[si % themeLen]?.color;
74
+ return {
75
+ pointerX: pixel.x,
76
+ pointerY: pixel.y,
77
+ seriesIndex: si,
78
+ dataIndex: diInside,
79
+ seriesName,
80
+ xIndex,
81
+ yIndex,
82
+ xLabel,
83
+ yLabel,
84
+ value,
85
+ ...(typeof color === 'string' ? { color } : {}),
86
+ };
87
+ }
@@ -0,0 +1,4 @@
1
+ export { createHeatmapTooltipPreset } from './heatmap-item-tooltip-presets';
2
+ export { useHeatmapItemTooltip } from './use-heatmap-item-tooltip';
3
+ export type { HeatmapItemTooltipParams, HeatmapItemTooltipContext } from './heatmap-item-tooltip.types';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../components/chart/heatmap/tooltip/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,YAAY,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createHeatmapTooltipPreset } from './heatmap-item-tooltip-presets';
2
+ export { useHeatmapItemTooltip } from './use-heatmap-item-tooltip';
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { HeatmapItemTooltipContext, HeatmapItemTooltipParams } from './heatmap-item-tooltip.types';
3
+ export interface UseHeatmapItemTooltipOptions {
4
+ active: boolean;
5
+ renderTooltip: (params: HeatmapItemTooltipParams) => React.ReactNode;
6
+ contextRef: React.RefObject<HeatmapItemTooltipContext>;
7
+ themeSeriesRef: React.RefObject<Array<{
8
+ color: string;
9
+ }>>;
10
+ width: number;
11
+ height: number;
12
+ }
13
+ export interface UseHeatmapItemTooltipResult {
14
+ attachHeatmapItemTooltipListeners: (chart: {
15
+ on: (ev: string, fn: (...args: any[]) => void) => void;
16
+ off: (ev: string, fn: (...args: any[]) => void) => void;
17
+ }) => () => void;
18
+ renderHeatmapTooltipOverlay: () => React.ReactNode;
19
+ }
20
+ /** Heatmap cell tooltip as React Native UI (`trigger: 'item'`). */
21
+ export declare function useHeatmapItemTooltip(options: UseHeatmapItemTooltipOptions): UseHeatmapItemTooltipResult;
22
+ //# sourceMappingURL=use-heatmap-item-tooltip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-heatmap-item-tooltip.d.ts","sourceRoot":"","sources":["../../../../../components/chart/heatmap/tooltip/use-heatmap-item-tooltip.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AAEhE,OAAO,KAAK,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAGxG,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,KAAK,CAAC,SAAS,CAAC;IACrE,UAAU,EAAE,KAAK,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;IACvD,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,2BAA2B;IAC1C,iCAAiC,EAAE,CAAC,KAAK,EAAE;QACzC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;QACvD,GAAG,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,IAAI,CAAC;KACzD,KAAK,MAAM,IAAI,CAAC;IACjB,2BAA2B,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CACpD;AAED,mEAAmE;AACnE,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,2BAA2B,CAiDxG"}
@@ -0,0 +1,43 @@
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
+ import { ChartPointerTooltipOverlay } from '../../tooltip/chart-pointer-tooltip-overlay';
3
+ import { heatmapItemParamsFromShowTip } from './heatmap-item-tooltip.utils';
4
+ /** Heatmap cell tooltip as React Native UI (`trigger: 'item'`). */
5
+ export function useHeatmapItemTooltip(options) {
6
+ const { active, renderTooltip, contextRef, themeSeriesRef, width, height } = options;
7
+ const [params, setParams] = useState(null);
8
+ useEffect(() => {
9
+ if (!active)
10
+ setParams(null);
11
+ }, [active]);
12
+ const attachHeatmapItemTooltipListeners = useCallback((chart) => {
13
+ if (!active)
14
+ return () => { };
15
+ const onShowTip = (evt) => {
16
+ const ctx = contextRef.current;
17
+ if (!ctx?.data?.length) {
18
+ setParams(null);
19
+ return;
20
+ }
21
+ const next = heatmapItemParamsFromShowTip(chart, evt, ctx, themeSeriesRef.current ?? []);
22
+ setParams(next);
23
+ };
24
+ const onHideTip = () => setParams(null);
25
+ chart.on('showTip', onShowTip);
26
+ chart.on('hideTip', onHideTip);
27
+ return () => {
28
+ chart.off('showTip', onShowTip);
29
+ chart.off('hideTip', onHideTip);
30
+ };
31
+ }, [active, contextRef, themeSeriesRef]);
32
+ const renderHeatmapTooltipOverlay = useCallback(() => {
33
+ if (!active || params == null)
34
+ return null;
35
+ return (<ChartPointerTooltipOverlay width={width} height={height} pointerX={params.pointerX} pointerY={params.pointerY}>
36
+ {renderTooltip(params)}
37
+ </ChartPointerTooltipOverlay>);
38
+ }, [active, renderTooltip, params, width, height]);
39
+ return {
40
+ attachHeatmapItemTooltipListeners,
41
+ renderHeatmapTooltipOverlay,
42
+ };
43
+ }
package/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export * from './gauge';
13
13
  export * from './geo';
14
14
  export * from './bubble';
15
15
  export * from './candlestick';
16
+ export * from './heatmap';
16
17
  export * from './axis';
17
18
  export * from './chart-theme.context';
18
19
  export * from './chart-container';
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/chart/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACnE,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../components/chart/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AACnE,cAAc,qBAAqB,CAAC;AACpC,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
package/index.js CHANGED
@@ -12,6 +12,7 @@ export * from './gauge';
12
12
  export * from './geo';
13
13
  export * from './bubble';
14
14
  export * from './candlestick';
15
+ export * from './heatmap';
15
16
  export * from './axis';
16
17
  export * from './chart-theme.context';
17
18
  export * from './chart-container';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wavemaker/react-native-echarts",
3
- "version": "1.0.0-dev.11",
3
+ "version": "1.0.0-dev.12",
4
4
  "description": "React Native chart components built on using e-charts library.",
5
5
  "license": "MIT",
6
6
  "repository": {