Более простое построение диаграмм в 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:
- react-native-svg: обеспечивает поддержку SVG для React Native на iOS, Android, macOS, Windows и уровень совместимости для Интернета.
- 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:
пряжа добавить wrn-echarts
- Выберите установку react-native-svg или @shopify/react-native-skia.
- Представьте соответствующие компоненты из wrn-echarts
- Замените SVGRenderer из ECharts на SVGRenderer из wrn-echarts.
- Запишите информацию о конфигурации параметров для диаграммы.
- Использовать компонент 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} />;
}
Вот его скриншот:
Разве это не особенно просто? Другие конфигурации диаграмм можно просмотреть на веб-сайте echarts.
Мы поддерживаем большинство диаграмм, которые в настоящее время поддерживает ECharts. Я покажу некоторые из диаграмм ниже, а другие примеры можно увидеть в проекте taro-playground.
Производительность
Как упоминалось ранее, основным решением для использования ECharts в React Native является его реализация через WebView. Среди многих реализаций на основе WebView у react-native-echarts-pro больше пользователей, поэтому для сравнения мы выбрали react-native-echarts-pro.
Ниже приведены скриншоты процесса инициализации для различных реализаций:
После нескольких тестов мы обнаружили, что wrn-echarts имеет преимущества в производительности в обычных сценариях использования. Тем не менее, в сценариях с большими объемами данных будет значительная задержка из-за декларативного метода визуализации пользовательского интерфейса, который мы будем продолжать улучшать.
Детали реализации
Выше приведена блок-схема библиотеки на примере react-native-svg. Основной рабочий процесс:
- Замените SVGRenderer для ECharts и замените зарегистрированный SVGPainter на пользовательский SVGPainter.
- CustomSVGPainter наследуется от SVGPainter, перезаписывает конструктор и часть функции обновления, вызывает функцию исправления, зарегистрированную в SVGComponent, когда данные диаграммы инициализируются или обновляются, и передает ей рассчитанные новые данные SVG.
- Определите SVGComponent, который управляет текущим экземпляром диаграммы и имеет базовую функцию исправления для получения данных SVG в реальном времени, а затем вызывает функцию SVGElement.
- Функция 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.
Другой пример — масштабирование диаграммы. Мобильная сторона — это масштабирование двумя пальцами, которое преобразуется в событие колесика мыши, а соответствующее расстояние прокрутки колесика мыши рассчитывается по изменению расстояния двумя пальцами.
Вот код ключа:
- Преобразовать 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
},
})
- Применение события 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 непосредственно из магазина приложений или со страницы выпусков, чтобы испытать ее.
:::информация Также опубликовано здесь.
:::
Оригинал