Skip to content

Commit 707bd57

Browse files
committed
improve data handling for non-web when webview reinitializes, keep one canonical data source
1 parent a099328 commit 707bd57

1 file changed

Lines changed: 100 additions & 78 deletions

File tree

src/components/ChartUPlot.tsx

Lines changed: 100 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,28 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
242242
};
243243
}, []);
244244

245+
// Keep canonical copy of incoming prop `data` (convert typed arrays to plain arrays).
246+
// Also mirror to window._data for native platforms when webref is available.
247+
useEffect(() => {
248+
if (!data) return;
249+
const plain = toPlainArrays(data as any[]);
250+
dataRef.current = plain as number[][];
251+
252+
if (!isWeb && webref?.current) {
253+
// Mirror to webview window._data
254+
try {
255+
webref.current.injectJavaScript(`
256+
window._data = ${JSON.stringify(dataRef.current)};
257+
true;
258+
`);
259+
} catch (e) {
260+
console.error('Failed to inject initial data into WebView', e);
261+
}
262+
} else if (isWeb) {
263+
uplotInstance.current?.setData(dataRef.current);
264+
}
265+
}, [data]);
266+
245267
// var { optionsFinal, containerWidth, containerHeight } = useMemo(() => {
246268

247269
// const { containerWidth, containerHeight } = dimensionsRef.current.containerWidth
@@ -304,10 +326,12 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
304326
margin,
305327
);
306328

329+
const chartData = data == null ? dataRef.current : data;
330+
307331
if (isWeb) {
308332
uplotInstance.current = new uPlot(
309333
optsFinal,
310-
data == null ? dataRef.current : data,
334+
chartData,
311335
webref.current,
312336
);
313337
} else {
@@ -317,8 +341,10 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
317341
return;
318342
}
319343

344+
// Ensure dataRef is the source of truth for the created chart in the WebView
345+
dataRef.current = toPlainArrays(chartData || []) as number[][];
320346
webref.current.injectJavaScript(
321-
getCreateChartString(data, optsFinal, bgColor),
347+
getCreateChartString(dataRef.current, optsFinal, bgColor),
322348
);
323349
}
324350
initialized.current = true;
@@ -346,78 +372,71 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
346372
* @param {number[][]} newData - The new data to set for the chart.
347373
*/
348374
const setData = useCallback((newData: number[][]): void => {
375+
// Keep canonical copy (plain arrays)
376+
const plain = toPlainArrays(newData as any[]);
377+
dataRef.current = plain as number[][];
378+
349379
if (isWeb) {
350-
dataRef.current = newData;
351380
uplotInstance.current?.setData(dataRef.current);
352-
} else {
353-
if (!webref?.current) {
354-
console.error('WebView reference is not set');
355-
return;
356-
}
357-
358-
webref.current.injectJavaScript(`
359-
var item = ${JSON.stringify(toPlainArrays(newData))};
381+
return;
382+
}
360383

361-
if (window._chart) {
362-
window._data = item;
363-
var size = [
364-
item.length,
365-
item[0].length,
366-
item[1].length,
367-
]
368-
window._chart.setData(window._data);
369-
} else {
370-
console.error('Chart not initialized');
371-
}
372-
true;
373-
`);
384+
if (!webref?.current) {
385+
console.error('WebView reference is not set');
386+
return;
374387
}
388+
389+
// Mirror full data into window._data and set chart
390+
webref.current.injectJavaScript(`
391+
window._data = ${JSON.stringify(dataRef.current)};
392+
if (window._chart) {
393+
window._chart.setData(window._data);
394+
} else {
395+
console.error('Chart not initialized');
396+
}
397+
true;
398+
`);
375399
}, []);
376400

377401
/**
378402
* Append a new data point across all series: [x, y1, y2, ...]
379403
*/
380404
const pushData = useCallback((item: number[]): void => {
381-
if (isWeb) {
382-
if (!dataRef.current || dataRef.current.length !== item.length) {
383-
dataRef.current = [];
384-
for (let i = 0; i < item.length; i++) {
385-
dataRef.current.push([]);
386-
}
387-
}
388-
389-
for (let i = 0; i < item.length; i++) {
390-
dataRef.current[i].push(item[i]);
391-
}
405+
// Update canonical copy locally first
406+
if (!dataRef.current || dataRef.current.length !== item.length) {
407+
dataRef.current = [];
408+
for (let i = 0; i < item.length; i++) dataRef.current.push([]);
409+
}
410+
for (let i = 0; i < item.length; i++) dataRef.current[i].push(item[i]);
392411

412+
if (isWeb) {
393413
uplotInstance.current?.setData(dataRef.current);
394-
} else {
395-
if (!webref?.current) {
396-
console.error('WebView reference is not set');
397-
return;
398-
}
414+
return;
415+
}
399416

400-
webref.current.injectJavaScript(`
401-
var item = ${JSON.stringify(item)};
417+
if (!webref?.current) {
418+
console.error('WebView reference is not set');
419+
return;
420+
}
402421

403-
if (window._data === undefined || window._data == null || window._data.length !== item.length) {
422+
// For native: inject only the new item and append to window._data in the WebView,
423+
// then call setData there. Avoid sending the entire dataRef.
424+
webref.current.injectJavaScript(`
425+
(function() {
426+
var item = ${JSON.stringify(item)};
427+
if (!window._data || window._data.length !== item.length) {
404428
window._data = [];
405-
for (let i = 0; i < item.length; i++) {
406-
window._data.push([]);
407-
}
408-
}
409-
410-
for (let i = 0; i < item.length; i++) {
411-
window._data[i].push(item[i]);
429+
for (var i = 0; i < item.length; i++) window._data.push([]);
412430
}
431+
for (var j = 0; j < item.length; j++) window._data[j].push(item[j]);
413432
if (window._chart) {
414433
window._chart.setData(window._data);
415434
} else {
416435
console.error('Chart not initialized');
417436
}
418-
true;
419-
`);
420-
}
437+
})();
438+
true;
439+
`);
421440
}, []);
422441

423442
/**
@@ -432,37 +451,34 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
432451
*/
433452
const sliceSeries = useCallback(
434453
(axis: number, min: number, max: number): void => {
435-
if (isWeb) {
436-
// Slice the data arrays
437-
dataRef.current = _sliceSeries(dataRef.current, axis, min, max);
454+
// Update canonical dataRef by slicing locally
455+
dataRef.current = _sliceSeries(dataRef.current, axis, min, max);
438456

457+
if (isWeb) {
439458
if (!uplotInstance.current) {
440459
console.error('uPlot instance is not initialized');
441460
return;
442461
}
443-
// Update the uPlot instance with the new data
444462
uplotInstance.current.setData(dataRef.current);
445-
} else {
446-
if (!webref?.current) {
447-
console.error('WebView reference is not set');
448-
return;
449-
}
450-
webref.current.injectJavaScript(`
451-
var axis = ${JSON.stringify(axis)};
452-
var min = ${JSON.stringify(min)};
453-
var max = ${JSON.stringify(max)};
454-
455-
if (window._chart && window._data && window._data[axis]) {
456-
// call sliceSeries function, which we assume is already defined in the webview
457-
window._data = sliceSeries(window._data, axis, min, max);
458-
window._chart.setData(window._data);
459-
} else {
460-
console.error('Chart not initialized or data not available');
461-
}
463+
return;
464+
}
462465

463-
true;
464-
`);
466+
if (!webref?.current) {
467+
console.error('WebView reference is not set');
468+
return;
465469
}
470+
471+
// Mirror sliced data into window._data and update the chart in the WebView
472+
webref.current.injectJavaScript(`
473+
window._data = ${JSON.stringify(dataRef.current)};
474+
if (window._chart) {
475+
window._chart.setData(window._data);
476+
} else {
477+
console.error('Chart not initialized or data not available');
478+
}
479+
true;
480+
`);
481+
return;
466482
},
467483
[],
468484
);
@@ -615,7 +631,9 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
615631
}}
616632
scrollEnabled={false}
617633
onLoadEnd={(): void => {
618-
createChart(options, data, bgColor);
634+
// Use canonical dataRef when creating the native WebView chart
635+
dataRef.current = toPlainArrays(data as any[]) as number[][];
636+
createChart(options, dataRef.current, bgColor);
619637

620638
if (onLoad) {
621639
onLoad();
@@ -630,6 +648,9 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
630648
destroy(true);
631649
}
632650

651+
console.log('shouldReinit', shouldReinit);
652+
console.log('data', data);
653+
633654
containerRef.current = r;
634655
webref.current = r;
635656

@@ -646,7 +667,8 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
646667
true;
647668
`);
648669

649-
createChart(options, data, bgColor);
670+
// reinit using the canonical dataRef rather than the original prop
671+
createChart(options, dataRef.current, bgColor);
650672
}
651673
}
652674
}}

0 commit comments

Comments
 (0)