apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.3k stars 19.61k forks source link

[Bug] Can't get ECharts Object in my reate-native app #20117

Open CannoChen opened 3 months ago

CannoChen commented 3 months ago

Version

5.5.0

Link to Minimal Reproduction

None

Steps to Reproduce

I implemented a Component in my reat-native app. The code is given below:

(1) Component

const CellsDataPlotComponent = () => {
    const svgRef = useRef(null);
    const dispatch = useDispatch();
    const {data, cur} = useSelector(dataAndCurSelector);

    useEffect(() => {
        let chart: any;
        if (svgRef.current) {
            chart = echarts.init(svgRef.current, 'light', {
                renderer: 'svg',
                width: E_WIDTH,
                height: E_HEIGHT,
            });
            chart.setOption(option);
        }

        return () => {
            chart?.dispose();
        };
    }, []);

    useEffect(() => {
        console.log(`CellsDataPlotComponent::data: ${data.length}`);
        if (!svgRef.current) {
            console.log("if (!svgRef.current)");
            return;
        }
        const chart = echarts.getInstanceByDom(svgRef.current);
        if (chart === null || chart === undefined) {
            console.log(chart);
            return;
        }
        // if (data.length === 0) return;

        const categoriesCur = data.map(item => item.timeStamp).slice(cur, data.length < (cur + 10) ? data.length : (cur + 10));
        const valHighCur = data.map(item => item.valHigh).slice(cur, data.length < (cur + 10) ? data.length : (cur + 10));
        const valLowCur = data.map(item => item.valLow).slice(cur, data.length < (cur + 10) ? data.length : (cur + 10));
        dispatch(addCur());

        console.log(`CellsDataPlotComponent::valHighCur: ${valHighCur}`);

        chart.setOption({
            xAxis: [
                { data: categoriesCur },
                { data: categoriesCur },
            ],
            series: [
                { data: valHighCur },
                { data: valLowCur },
            ],
        });
        return () => {
            chart?.dispose();
        };
    }, [data]);

    return (
        <View style={styles.container}>
            <SvgChart ref={svgRef} />
        </View>
    );
}

(2) option

const option = {
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'cross',
            label: {
                backgroundColor: '#283b56',
            },
        },
    },
    legend: {},
    toolbox: {
        show: true,
        feature: {
            dataView: { show: false, readOnly: false },
            restore: {},
        },
    },
    dataZoom: {
        show: false,
        start: 0,
        end: 100,
    },
    xAxis: [
        {
            type: 'category',
            boundaryGap: true,
            data: [],
        },
        {
            type: 'category',
            boundaryGap: true,
            data: [],
        },
    ],
    yAxis: [
        {
            type: 'value',
            name: 'Price',
        },
        {
            type: 'value',
            // scale: true,
            name: 'Order',
            max: 200,
            min: -200,
        },
    ],
    series: [
        {
            name: 'valHigh',
            type: 'line',
            data: []
        },
        {
            name: 'valLow',
            type: 'line',
            data: [],
        },
    ],
};  // option

(3) I also use Redux to manage state. It helps me to cache data received from bluetooth. The Slice is shown below:

const BluetoothSlice = createSlice({
    name: 'bluetooth',
    initialState: {
        data: [],           
        cur: 0,             
        isOpen: false,      
        isConnected: false, 
    },
    reducers: {
        on: (state) => {
            state.isOpen = true;
        },
        off: (state) => {
            state.isOpen = false;
        },
        connect: (state) => {
            state.isConnected = true;
        },
        disconnect: (state) => {
            state.isConnected = false;
        },
        addCur: (state) => {
            state.cur = state.cur + 1;
            console.log(`bluetoothSlice::addCur`);
        },
        pushData: (state, action) => {
            state.data.push(action.payload);
            console.log(`bluetoothSlice::pushData`);
        }
    },
    extraReducers: builder => {
        builder
            .addCase(sendDataToServer.pending, () => {})
            .addCase(sendDataToServer.fulfilled, (state) => {
                state.data = [];  
                state.cur = 0;    
            })
            .addCase(sendDataToServer.rejected, () => {})
    }
});

const dataSelector = state => state.bluetooth.data;
const curSelector = state => state.bluetooth.cur;
const dataAndCurSelector = createSelector(
    [dataSelector, curSelector],
    (data, cur) => { return {data, cur} }
);

const sendDataToServer = createAsyncThunk(
    "bluetooth/sendData",
    async (state) => {
        // connect to server

        return true;
    }
);

export default BluetoothSlice.reducer;
export const {
    on,
    off,
    connect,
    disconnect,
    addCur,
    pushData } = BluetoothSlice.actions;
export {dataAndCurSelector};

Current Behavior

In , I can't get ECharts Object. When i call const chart = echarts.getInstanceByDom(svgRef.current);, it always return undefined to me. So, I can't display data received by Bluetooth to my app.

Expected Behavior

I need to get the ECharts Object. then I will be able to display the data received by Bluetooth to the screen.

Environment

- OS:Android
- Browser: -
- Framework: react-native@0.74.2

Any additional comments?

No response

CannoChen commented 3 months ago

Does anyone know how this problem should be solved?

CannoChen commented 3 months ago

简而言之,这个问题就是:const chart = echarts.getInstanceByDom(svgRef.current) 这条语句一直返回的是undefined。

In short, the problem is that the statement const chart = echarts.getInstanceByDom(svgRef.current) keeps returning undefined.