supervons / react-native-echarts-pro

A React-Native charts based on Apache ECharts, support various charts and map.
https://supervons.github.io/react-native-echarts-pro-docs/
MIT License
216 stars 33 forks source link

折线图tooltip中的formatter不生效 #50

Closed zengyuehao closed 2 years ago

zengyuehao commented 2 years ago

formatter使用function时没有作用

zengyuehao commented 2 years ago

react-native-echarts-pro【1.8.3】 react-native version【0.67.1】 react-native-webview 【11.15.0】 Platform【android】

zengyuehao commented 2 years ago

目前生效的只有字符串的形式 例如formatter: '{HH}:{mm}',

supervons commented 2 years ago

1、是否启用了 Hermes 引擎,如果是,可以查看:https://github.com/supervons/react-native-echarts-pro/issues/35

2、 可否提供一个最小可运行复现的示例代码。

zengyuehao commented 2 years ago

1、是否启用了 Hermes 引擎,如果是,可以查看:#35

2、 可否提供一个最小可运行复现的示例代码。

这是示例

` import React, {useEffect, useRef, useState} from "react"; import {StyleSheet, View, Text} from "react-native"; import * as echarts from 'echarts' import {I18n} from '../assets/js/i18n/index' import ECharts from "react-native-echarts-pro";

const TestChart = (props) => { const chartRef = useRef(null); const [option, setOption] = useState({ backgroundColor: "white", title: [], // legend: { data: [], show: true, z: 3, icon: "roundRect", bottom: 15, itemWidth: 8, itemHeight: 8, textStyle: { fontSize: 10, color: 'gray' } }, color: [ "#0ac860", "#ed3333", "#2fa4ed", "#9e5ed9", "#00b0a7", "#ed3472", "#4878f9", ], tooltip: { trigger: "axis",

        axisPointer: {
            animation: false,
        },
        formatter: function (params) {
            "show source";
            console.log('params:', params)
            let len = params.length;
            let color = "";
            let name = "";
            let value = "";
            let time = moment(params[0].value[0]).format("YYYY-MM-DD HH:mm:ss");
            let unit = "";
            let html = "";
            let frow = `<p class="tooltip_time">${time}</p>`;
            for (let i = 0; i < len; i++) {
                color = params[i].color;
                name = params[i].seriesName;
                value = params[i].value[1];

                unit = _this.getUnit(params[i].value[2]);
                html =
                    html +
                    `

                  <p class="tooltip_info">
                    <span style="display: inline-block; width: 12px; height: 12px; border-radius: 50%; background-color: ${color}"></span>
                    <span>${name}:</span>
                    <span>${value}</span>
                    <span>${unit}</span>
                  </p>
                `;
            }
            return "<div>" + frow + html + "</div>";
        }
    },
    xAxis: [{
        type: "time",
        splitLine: {
            show: true,
        },
        axisLine: {
            show: false,
        },
        axisTick: {
            show: false,
            interval: 3,
        },
        // maxInterval: 3 * 60 * 60 * 1000,
        axisLabel: {
            // 显示最大值和最小值
            showMinLabel: true,
            showMaxLabel: true,
            fontSize: 10,
            formatter: '{HH}:{mm}',
        },
    }],
    yAxis: [],
    series: [],
})

useEffect(() => {
    let data = []
    for(let i = 0; i<100; i++) {
        let timeStamp = 1650297600000 + i * 300000
        data.push([timeStamp, Math.floor((Math.random()*100)+1), 'kw'])
    }
    let defaultOption = JSON.parse(JSON.stringify(option))
    defaultOption.series.push({
        name: 'ea',
        type: "line",
        unit: 'kw',
        hoverAnimation: false,
        showSymbol: false,
        smooth: true,
        symbolSize: 4,
        data,
        areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                {
                    offset: 0,
                    color: '#1bad5810'
                },
                {
                    offset: 1,
                    color: '#1bad5870'
                }
            ]),
        },
        itemStyle: {
            borderWidth: 0,
            color: '#62ca8b',
        },
    })
    defaultOption.yAxis.push({
        name: 'kw',
        nameTextStyle: {
            color: "#1B2232",
            fontSize: 12,
        },
        max: 100,
        interval: 20,
        min: 0,
        axisLine: {
            show: false
        },
        axisTick: {
            show: false
        },
        type: "value",
        boundaryGap: [0, "100%"],
        splitLine: {
            show: true,
        },
    })

    setOption(defaultOption)
}, [])

return (
    <View style={{height: 400}}>
        <ECharts
            ref={chartRef}
            option={option}
            height={400}
        />
    </View>
);

}

const styles = StyleSheet.create({ });

export default TestChart

`

zengyuehao commented 2 years ago

在这个示例中setNewOption不知道为什么没有生效

supervons commented 2 years ago

我运行了你的示例代码,排查到的原因是:

你在 useEffect 中使用

let defaultOption = JSON.parse(JSON.stringify(option))

对原有 opion 进行 JSON.stringify 后,会对 function 模式的 formatter造成影响。

所以,你可以把 formatter 赋值放到useEffect中:

下面是我移除了一些不能运行的依赖后的示例,可直接运行:

import React, { useEffect, useRef, useState } from "react";
import { StyleSheet, View, Text } from "react-native";
import ECharts from "react-native-echarts-pro";

const TestChart = props => {
  const chartRef = useRef(null);
  const [option, setOption] = useState({
    backgroundColor: "white",
    title: [], //
    legend: {
      data: [],
      show: true,
      z: 3,
      icon: "roundRect",
      bottom: 15,
      itemWidth: 8,
      itemHeight: 8,
      textStyle: {
        fontSize: 10,
        color: "gray",
      },
    },
    color: [
      "#0ac860",
      "#ed3333",
      "#2fa4ed",
      "#9e5ed9",
      "#00b0a7",
      "#ed3472",
      "#4878f9",
    ],
    tooltip: {
      trigger: "axis",

      axisPointer: {
        animation: false,
      },
    },
    xAxis: [
      {
        type: "time",
        splitLine: {
          show: true,
        },
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
          interval: 3,
        },
        // maxInterval: 3 * 60 * 60 * 1000,
        axisLabel: {
          // 显示最大值和最小值
          showMinLabel: true,
          showMaxLabel: true,
          fontSize: 10,
          formatter: "{HH}:{mm}",
        },
      },
    ],
    yAxis: [],
    series: [],
  });

  useEffect(() => {
    let data = [];
    for (let i = 0; i < 100; i++) {
      let timeStamp = 1650297600000 + i * 300000;
      data.push([timeStamp, Math.floor(Math.random() * 100 + 1), "kw"]);
    }
    let defaultOption = JSON.parse(JSON.stringify(option));
    defaultOption.tooltip.formatter = function (params) {
      "show source";
      console.log("params:", params);
      let len = params.length;
      let color = "";
      let name = "";
      let value = "";
      let time = "123444";
      let unit = "";
      let html = "";
      let frow = `<p class="tooltip_time">${time}</p>`;
      for (let i = 0; i < len; i++) {
        color = params[i].color;
        name = params[i].seriesName;
        value = params[i].value[1];

        unit = "777";
        html =
          html +
          `

                  <p class="tooltip_info">
                    <span style="display: inline-block; width: 12px; height: 12px; border-radius: 50%; background-color: ${color}"></span>
                    <span>${name}:</span>
                    <span>${value}</span>
                    <span>${unit}</span>
                  </p>
                `;
      }
      return "<div>" + frow + html + "</div>";
    };
    defaultOption.series.push({
      name: "ea",
      type: "line",
      unit: "kw",
      hoverAnimation: false,
      showSymbol: false,
      smooth: true,
      symbolSize: 4,
      data,
      itemStyle: {
        borderWidth: 0,
        color: "#62ca8b",
      },
    });
    defaultOption.yAxis.push({
      name: "kw",
      nameTextStyle: {
        color: "#1B2232",
        fontSize: 12,
      },
      max: 100,
      interval: 20,
      min: 0,
      axisLine: {
        show: false,
      },
      axisTick: {
        show: false,
      },
      type: "value",
      boundaryGap: [0, "100%"],
      splitLine: {
        show: true,
      },
    });

    setOption(defaultOption);
  }, []);

  return (
    <View style={{ height: 400 }}>
      <ECharts ref={chartRef} option={option} height={400} />
    </View>
  );
};

const styles = StyleSheet.create({});

export default TestChart;