@@ -9,11 +9,9 @@ import React, {
99import { Platform , useWindowDimensions , View } from 'react-native' ;
1010import { WebView } from 'react-native-webview' ;
1111
12- var isWeb = Platform . OS === 'web' ;
13-
1412import html from './uplot.html' ;
15-
1613import 'uplot/dist/uPlot.min.css' ;
14+ var isWeb = Platform . OS === 'web' ;
1715
1816var uPlot : any = null ;
1917if ( isWeb ) {
@@ -72,19 +70,52 @@ function getDimensions(
7270 return { optionsFinal, containerWidth, containerHeight } ;
7371}
7472
73+ function getCreateChartString (
74+ data : number [ ] [ ] ,
75+ options : any ,
76+ bgColor : string = 'transparent' ,
77+ injectedJavaScript : string = '' ,
78+ ) : string {
79+ return `
80+ (function() {
81+ if (window.__CHART_CREATED__) return;
82+ window.__CHART_CREATED__ = true;
83+
84+ // inject custom functions if provided
85+ ${ injectedJavaScript }
86+
87+ document.body.style.backgroundColor='${ bgColor } ';
88+
89+ // stash your data and options on window
90+ window._data = ${ JSON . stringify ( data ) } ;
91+ window._opts = parseOptions('${ stringify ( options ) } ');
92+
93+ // inject background color before chart setup if provided
94+ if ('${ bgColor } ') {
95+ document.body.style.backgroundColor='${ bgColor } ';
96+ }
97+ // now actually construct uPlot
98+ window._chart = new uPlot(window._opts, window._data, document.getElementById('chart'));
99+ })();
100+ true;
101+ ` ;
102+ }
103+
75104export interface UPlotProps {
76105 /** uPlot data array: [xValues[], series1[], series2[], ...] */
77106 data : [ number [ ] , ...number [ ] [ ] ] ;
78107 /** uPlot options object */
79108 options : any ;
80109 /** Additional style for the container */
81110 style ?: any ;
82- /** any custom functions to be injected into the webview */
83- functions ?: string [ ] ;
111+ /** any custom functions to be injected into the webview (Function or source string) */
112+ functions ?: Array < Function | string > ;
84113 /** Margin for the chart, useful for titles and legends */
85114 margin ?: { title ?: number ; legend ?: number } ;
86115 /** Callback for messages from the WebView */
87116 onMessage ?: ( event : any ) => void ;
117+ /** JavaScript to be injected into the WebView */
118+ injectedJavaScript ?: string ;
88119 /** Additional props for the WebView */
89120 webviewProps ?: any ;
90121}
@@ -98,6 +129,7 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
98129 functions,
99130 margin = { title : MARGIN_TITLE , legend : MARGIN_LEGEND } ,
100131 onMessage,
132+ injectedJavaScript = '' ,
101133 ...webviewProps
102134 } ,
103135 ref ,
@@ -116,10 +148,11 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
116148 } , [ options , style , width , height ] ) ;
117149
118150 var injectFns = useMemo ( ( ) => {
119- if ( ! functions || functions . length === 0 ) {
120- return '' ;
121- }
122- return functions . join ( '\n' ) ;
151+ if ( ! functions || functions . length === 0 ) return '' ;
152+ // convert functions to string if needed
153+ return functions
154+ . map ( ( fn ) => ( typeof fn === 'function' ? fn . toString ( ) : fn ) )
155+ . join ( '\n' ) ;
123156 } , [ functions ] ) ;
124157
125158 useEffect ( ( ) => {
@@ -144,7 +177,7 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
144177
145178 // eslint-disable-next-line @typescript-eslint/no-explicit-any
146179 const createChart = useCallback (
147- ( opts : any , data : number [ ] [ ] ) : void => {
180+ ( opts : any , data : number [ ] [ ] , bgColor ?: string ) : void => {
148181 if ( initialized . current ) {
149182 return ;
150183 }
@@ -153,25 +186,12 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
153186 uplotInstance . current = new uPlot ( opts , data , webref ) ;
154187 } else {
155188 // inject background color before chart setup if provided
156- const bgJS = bgColor
157- ? `document.body.style.backgroundColor='${ bgColor } ';`
158- : '' ;
159- webref ?. injectJavaScript (
160- `${ bgJS }
161189
162- console.debug('Creating uPlot chart...');
163-
164- window._data = ${ JSON . stringify ( data ) } ;
165- window._opts = parseOptions('${ stringify ( opts ) } ');
166-
167- window._chart = new uPlot(window._opts, window._data, document.getElementById("chart"));
168- true;
169- ` ,
170- ) ;
190+ webref ?. injectJavaScript ( getCreateChartString ( data , opts , bgColor ) ) ;
171191 }
172192 initialized . current = true ;
173193 } ,
174- [ bgColor ] ,
194+ [ ] ,
175195 ) ;
176196
177197 const setData = useCallback ( ( newData : number [ ] [ ] ) : void => {
@@ -310,26 +330,13 @@ const ChartUPlot = forwardRef<any, UPlotProps>(
310330 } }
311331 scrollEnabled = { false }
312332 onLoadEnd = { ( ) : void => {
313- // webref.injectJavaScript(guardAndCreateJS);
314- createChart ( optionsFinal , data ) ;
333+ createChart ( optionsFinal , data , bgColor ) ;
315334 } }
316335 ref = { ( r ) => {
317336 webref = r ;
318337 } }
319338 javaScriptEnabled = { true }
320- injectedJavaScript = { `
321- const consoleLog = (type, log) => window.ReactNativeWebView.postMessage(JSON.stringify({'type': 'Console', 'data': {'type': type, 'log': log}}));
322- console = {
323- log: (log) => consoleLog('log', log),
324- debug: (log) => consoleLog('debug', log),
325- info: (log) => consoleLog('info', log),
326- warn: (log) => consoleLog('warn', log),
327- error: (log) => consoleLog('error', log),
328- };
329-
330- ${ injectFns }
331- true;
332- ` }
339+ injectedJavaScript = { `${ injectedJavaScript } ; true;` }
333340 onMessage = { ( payload ) : void => {
334341 // in webviewProps, if onMessage is provided, call it with the payload
335342 if ( onMessage ) {
0 commit comments