Более простое построение диаграмм в React Native с помощью Apache ECharts — решение, которое вы искали

Более простое построение диаграмм в React Native с помощью Apache ECharts — решение, которое вы искали

23 марта 2023 г.
<цитата>

Мы разработали графическую библиотеку с открытым исходным кодом для приложения React Native, которое основано на Apache ECharts и использует RNSVG или RNSKia для рендеринга способом, который почти идентичен использованию в Интернете, что делает его подходящим практически для любого ситуации, требующей наглядности.

Исходный код проекта доступен по адресу https://github.com/wuba/react-native-echarts, и наш официальный сайт: https://wuba.github.io/react-native-echarts/.. р>

Введение

При рисовании диаграмм мы чаще всего используем библиотеку диаграмм ECharts. Поскольку это одна из самых зрелых библиотек диаграмм на рынке, в основном для использования в Интернете, нет лучшего способа использовать ее в React Native. Перед лицом этой ситуации наши решения:

* Вариант 1: Использовать в качестве альтернативы библиотеки диаграмм, разработанные специально для React Native, такие как react-native-charts-wrapper, Victory-Native и т. д. Стиль и взаимодействие этих библиотек диаграмм отличаются от ECahrts, а богатство графиков недостаточно. Для React Native требуется отдельный дизайн взаимодействия с пользовательским интерфейсом, особенно в случае мультиплатформенных требований. * Вариант 2: рендеринг диаграмм в react-native-webview. Это решение использует инъекции JavaScript для инициализации и postMessage для ответа на событие. Вы можете напрямую использовать библиотеки с открытым исходным кодом, такие как react-native-echarts-pro, native-echarts и т. д. Когда на странице несколько диаграмм или слишком много элементов диаграммы, она столкнется с узкими местами производительности, такими как феномен белого экрана. для диаграмм с областями большого объема данных и точечных диаграмм с одной осью на Android. Во время рендеринга будет очевидная задержка и пропадание кадров.

Поэтому мы разработали новую библиотеку диаграмм, которая может интегрировать возможности ECharts в приложения React Native для повышения удобства использования и повышения производительности. Поскольку мы не хотим писать графическую библиотеку с нуля, давайте посмотрим, какие графические библиотеки мы уже разработали для React Native:

  1. react-native-svg: обеспечивает поддержку SVG для React Native на iOS, Android, macOS, Windows и уровень совместимости для Интернета.
  2. react-native-skia: React Native Skia привносит графическую библиотеку Skia в React Native. Skia служит графическим движком для Google Chrome и Chrome OS, Android, Flutter, Mozilla Firefox и Firefox OS и многих других продуктов. Он также предоставляет компонент ImageSVG, поддерживающий визуализацию изображений в формате SVG.

Мы знаем, что ECharts поддерживает рендеринг SVG, поэтому, если мы получим данные SVG до рендеринга диаграммы и предоставим их для рендеринга в react-native-svg или react-native-skia, мы сможем достичь нашей цели.

После периода экспериментов мы разработали wrn-echart со следующими функциями:

  • 🔥 Так же, как и Apache ECharts
  • 🎨 Подробные диаграммы, охватывающие практически все сценарии использования.
  • ✨ Дополнительная библиотека рендеринга, Skia или SVG
  • 🚀 Возможность повторного использования кода в Интернете.
  • 📱 Поддержка жестов масштабирования

Как использовать

На практике общий процесс для wrn-echarts аналогичен ECharts:

  1. пряжа добавить wrn-echarts
  2. Выберите установку react-native-svg или @shopify/react-native-skia.
  3. Представьте соответствующие компоненты из wrn-echarts
  4. Замените SVGRenderer из ECharts на SVGRenderer из wrn-echarts.
  5. Запишите информацию о конфигурации параметров для диаграммы.
  6. Использовать компонент SkiaChart/SvgChart

Вот пример кода:

// import { SkiaChart, SVGRenderer } from 'wrn-echarts';
import SkiaChart, { SVGRenderer } from 'wrn-echarts/skiaChart';
import * as echarts from 'echarts/core';
import { useRef, useEffect } from 'react';
import { LineChart } from 'echarts/charts';

echarts.use([ SVGRenderer, LineChart ])

export default function App() {
  const skiaRef = useRef<any>(null);
  useEffect(() => {
    const option = {
      xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: [150, 230, 224, 218, 135, 147, 260],
          type: 'line'
        }
      ]
    }
    let chart: any;
    if (skiaRef.current) {
      chart = echarts.init(skiaRef.current, 'light', {
        renderer: 'svg',
        width: 250,
        height: 300,
      });
      chart.setOption(option);
    }
    return () => chart?.dispose();
  }, []);

  return <SkiaChart ref={skiaRef} />;
}

Вот его скриншот:

Image description

Разве это не особенно просто? Другие конфигурации диаграмм можно просмотреть на веб-сайте echarts.

Мы поддерживаем большинство диаграмм, которые в настоящее время поддерживает ECharts. Я покажу некоторые из диаграмм ниже, а другие примеры можно увидеть в проекте taro-playground.

Image description Image description Image description Image description

Производительность

Как упоминалось ранее, основным решением для использования ECharts в React Native является его реализация через WebView. Среди многих реализаций на основе WebView у react-native-echarts-pro больше пользователей, поэтому для сравнения мы выбрали react-native-echarts-pro.

Ниже приведены скриншоты процесса инициализации для различных реализаций:

Image description

После нескольких тестов мы обнаружили, что wrn-echarts имеет преимущества в производительности в обычных сценариях использования. Тем не менее, в сценариях с большими объемами данных будет значительная задержка из-за декларативного метода визуализации пользовательского интерфейса, который мы будем продолжать улучшать.

Детали реализации

Image description

Выше приведена блок-схема библиотеки на примере react-native-svg. Основной рабочий процесс:

  1. Замените SVGRenderer для ECharts и замените зарегистрированный SVGPainter на пользовательский SVGPainter.
  2. CustomSVGPainter наследуется от SVGPainter, перезаписывает конструктор и часть функции обновления, вызывает функцию исправления, зарегистрированную в SVGComponent, когда данные диаграммы инициализируются или обновляются, и передает ей рассчитанные новые данные SVG.
  3. Определите SVGComponent, который управляет текущим экземпляром диаграммы и имеет базовую функцию исправления для получения данных SVG в реальном времени, а затем вызывает функцию SVGElement.
  4. Функция SVGElement перебирает все узлы SVG и преобразует их в соответствующие элементы SVG, предоставленные react-native-svg, для окончательного действия по рендерингу.

При использовании react-native-skia есть некоторые отличия. Существует базовый метод patchString для определенного компонента SkiaComponent. patchString получает измененные данные SVG, преобразует их в строку SVG и передает компоненту ImageSVG react-native-skia для рендеринга.

Обработка события TouchEvent

События ECharts — это события мыши, такие как щелчок, двойной щелчок, нажатие кнопки мыши, перемещение мыши и т. д. События мыши используются для запуска отображения или анимации элементов диаграммы.

Мы используем PanResponder React Native для захвата событий. Затем мы имитируем мобильное событие TouchEvent как событие мыши и отправляем его экземпляру диаграммы, сгенерированному методом инициализации ECharts.

Например, действие следования за мышью для отображения легенды на диаграмме — это TouchStart + TouchMove на мобильной стороне, что преобразуется в событие мыши mousedown + mousemove.

Другой пример — масштабирование диаграммы. Мобильная сторона — это масштабирование двумя пальцами, которое преобразуется в событие колесика мыши, а соответствующее расстояние прокрутки колесика мыши рассчитывается по изменению расстояния двумя пальцами.

Вот код ключа:

  1. Преобразовать TouchEvent в MouseEvent
PanResponder.create({
  onPanResponderGrant: ({ nativeEvent }) => {
    // Action start, translated into mouse down and move events
    dispatchEvent(
      zrenderId,
      ['mousedown', 'mousemove'],
      nativeEvent,
      'start'
    );
  },
  onPanResponderMove: ({ nativeEvent }) => {
    // Handling finger movement operations
    const length = nativeEvent.touches.length;
    if (length === 1) {
      // single finger
    } else if (length === 2) {
      // Handling two-finger movement operations here
      if (!zooming) {
        // ...
      } else {
        // Here the event is converted to a scroll wheel
        const { initialX, initialY, prevDistance } = pan.current;
        const delta = distance - prevDistance;
        pan.current.prevDistance = distance;
        dispatchEvent(zrenderId, ['mousewheel'], nativeEvent, undefined, {
          zrX: initialX,
          zrY: initialY,
          zrDelta: delta / 120,
        });
      }
    }
  },
  onPanResponderRelease: ({ nativeEvent }) => {
    // The action is over, where it is transformed into a mouse click release operation
  },
})

  1. Применение события MouseEvent к экземпляру диаграммы ECharts
function dispatchEvent(
  zrenderId: number,
  types: HandlerName[],
  nativeEvent: NativeTouchEvent,
  stage: 'start' | 'end' | 'change' | undefined,
  props: any = {
    zrX: nativeEvent.locationX,
    zrY: nativeEvent.locationY,
  }
) {
  if (zrenderId) {
    var handler = getInstance(zrenderId).handler;
    types.forEach(function (type) {
      handler.dispatch(type, {
        preventDefault: noop,
        stopImmediatePropagation: noop,
        stopPropagation: noop,
        ...props,
      });
      stage && handler.processGesture(wrapTouch(nativeEvent), stage);
    });
  }
}

Для получения дополнительной информации

Перейдите на страницу https://github.com/wuba/react-native-echarts, чтобы просмотреть исходный код. код, и дайте нам звезду, если вам это нравится. Если у вас возникнут какие-либо проблемы, вы можете отправить сообщение о проблеме.

Пример кода в этом посте относится к проекту https://github.com/wuba/taro-playground, который также с открытым исходным кодом. Заинтересованные стороны также могут установить новую версию приложения Taro Playground непосредственно из магазина приложений или со страницы выпусков, чтобы испытать ее.

:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE