15、热门React D3库及性能优化指南

热门React D3库及性能优化指南

在数据可视化领域,使用基于D3和React的现成库可以显著提高开发效率。本文将介绍几种流行的React D3库,包括它们的设置、实现、优缺点以及成本,并分享一些性能优化的技巧。

1. 流行的React D3库

1.1 Visx

Visx是第二受欢迎的库,Airbnb团队在这个库上投入了很多精力,它具有良好的视觉吸引力和支持。

1.1.1 设置

使用以下命令安装所需的模块:

yarn add @visx/mock-data @visx/group @visx/shape @visx/scale
1.1.2 实现

以下是一个简单的柱状图示例:

// src/component/SimpleBarGraph/SimpleBarGraph.tsx
import React from 'react'
import { letterFrequency } from '@visx/mock-data'
import { Group } from '@visx/group'
import { Bar } from '@visx/shape'
import { scaleLinear, scaleBand } from '@visx/scale'
const uuid = require('react-uuid')

const data = letterFrequency
const width = 500
const height = 500
const margin = { top: 20, bottom: 20, left: 20, right: 20 }
const xMax = width - margin.left - margin.right
const yMax = height - margin.top - margin.bottom

const x = (d: { letter: any }) => d.letter
const y = (d: { frequency: React.Key }) => +d.frequency * 100

const xScale = scaleBand({
  range: [0, xMax],
  round: true,
  domain: data.map(x),
  padding: 0.4,
})
const yScale = scaleLinear({
  range: [yMax, 0],
  round: true,
  domain: [0, Math.max(...data.map(y))],
})

const compose = (scale, accessor) => d => scale(accessor(d))
const xPoint = compose(xScale, x)
const yPoint = compose(yScale, y)

function SimpleBarGraph() {
  return (
    <svg width={width} height={height}>
      {data.map((d, i) => {
        const barHeight = yMax - yPoint(d)
        return (
          <Group key={`bar-${uuid()}`}>
            <Bar
              x={xPoint(d)}
              y={yMax - barHeight}
              height={barHeight}
              width={xScale.bandwidth()}
              fill="grey"
            />
          </Group>
        )
      })}
    </svg>
  )
}

export default SimpleBarGraph

App.tsx 中引入组件:

<SimpleBarGraph />
1.1.3 成本

解析后的大小为42KB,相对较小。

1.1.4 优缺点
  • 优点 :占用空间小,由低级组件组成,适合功能接近需求的最终产品,内置模拟数据,方便前端开发。
  • 缺点 :组件被拆分为小的低级组件,开发者需要将它们组合起来,有一定的学习曲线,对于简单图表来说可能过于复杂。

1.2 Victory

Victory是用于模块化图表和数据可视化的React.js组件。

1.2.1 设置

使用以下命令安装:

yarn add victory
1.2.2 实现

以下是一个简单的饼图示例:

// src/component/SimplePie/SimplePie.tsx
import React from 'react'
import { VictoryPie } from 'victory'

const SimplePie = () => {
  return (
    <div className="SimplePie">
      <VictoryPie
        data={[
          { x: 'Cats', y: 35 },
          { x: 'Dogs', y: 40 },
          { x: 'Birds', y: 55 }
        ]}
      />
    </div>
  )
}

export default SimplePie
1.2.3 成本

解析后的成本为164KB。

1.2.4 优缺点
  • 优点 :易于实现,示例简单,有令人印象深刻的画廊示例,拥有大量的追随者、粉丝和支持者。
  • 缺点 :图表种类不如其他一些库多,并且存在较多未解决的bug。

1.3 Nivo

Nivo提供了丰富的基于D3和Reactjs的可视化组件。

1.3.1 设置

使用以下命令安装核心库和所需模块:

yarn add @nivo/core @nivo/calendar
1.3.2 实现

以下是一个日历图表的示例:

// src/component/SimpleCalendarChart/SimpleCalendarChart.tsx
import React from 'react'
import { ResponsiveCalendar } from '@nivo/calendar'

const SimpleCalendarChart = (props: { data: { day: string; value: number }[] }) => {
  return (
    <div style={{ width: 800, height: 500 }}>
      <ResponsiveCalendar
        data={props.data}
        from="2019-01-01"
        to="2021-12-31"
        emptyColor="#eeeeee"
        colors={['#61cdbb', '#97e3d5', '#e8c1a0', '#f47560']}
        margin={{ top: 40, right: 40, bottom: 40, left: 40 }}
        yearSpacing={40}
        monthBorderColor="#ffffff"
        dayBorderWidth={2}
        dayBorderColor="#ffffff"
        legends={[
          {
            anchor: 'bottom-right',
            direction: 'row',
            translateY: 36,
            itemCount: 4,
            itemWidth: 42,
            itemHeight: 36,
            itemsSpacing: 14,
            itemDirection: 'right-to-left',
          },
        ]}
      />
    </div>
  )
}

export default SimpleCalendarChart

App.tsx 中获取数据并传递给组件:

import React from 'react'
import './App.scss'
import { useRecoilValue } from 'recoil'
import SimpleCalendarChart from './components/SimpleCalendarChart/SimpleCalendarChart'
import { getCalendarData } from './recoil/selectors/calendarDataSelectors'

function App() {
  const data = useRecoilValue(getCalendarData) as { day: string, value: number }[]
  return (
    <div className="App">
      <header className="App-header">
        <SimpleCalendarChart data={data} />
      </header>
    </div>
  )
}

export default App
1.3.3 成本

使用一个模块需要核心库,成本为241KB,包含React-spring、D3、lodash等库。

1.3.4 优缺点
  • 优点 :提供独特的图表选择,外观美观,易于实现,具有服务器端渲染(SSR)API,适合处理大型数据集。
  • 缺点 :示例不够直观,使用文档中的示例时可能无法渲染,需要设置包装容器的宽度和高度。

1.4 React-vis

React-vis是Uber创建的可组合图表库。

1.4.1 设置

使用以下命令安装库和类型:

yarn add react-vis @types/react-vis
1.4.2 实现

以下是一个简单的折线图示例:

// src/component/SimpleReactVizChart/SimpleReactVizChart.tsx
import React from 'react'
import './BasicRadarChart.scss'
import '../../../node_modules/react-vis/dist/style.css'
import { XYPlot, LineSeries, XAxis, YAxis, HorizontalGridLines, VerticalGridLines } from 'react-vis'

const SimpleReactVizChart = () => {
  return (
    <>
      <div className="App">
        <XYPlot height={300} width={300}>
          <LineSeries
            data={[
              { x: 0, y: 8 },
              { x: 1, y: 5 },
              { x: 2, y: 4 },
              { x: 3, y: 9 },
              { x: 4, y: 1 },
              { x: 5, y: 7 },
              { x: 6, y: 6 },
              { x: 7, y: 3 },
              { x: 8, y: 2 },
              { x: 9, y: 0 },
            ]}
          />
          <VerticalGridLines />
          <HorizontalGridLines />
          <XAxis />
          <YAxis />
        </XYPlot>
      </div>
    </>
  )
}

export default SimpleReactVizChart
1.4.3 成本

未解析大小为635KB,解析后为316KB。

1.4.4 优缺点
  • 优点 :易于实现,提供大量简单和自定义的图表,自带CSS文件帮助样式组件。
  • 缺点 :库的一致性较差,体积较大,存在较多未解决的bug,需要进行架构重构。

1.5 各库对比

库名 Stars数量 贡献者数量 开源问题数量 解析后大小 优点 缺点
Visx 与Victory接近 - - 42KB 小体积,低级别组件,内置模拟数据 学习曲线,简单图表使用复杂
Victory 与Visx接近 约为Visx两倍 约为Visx两倍 164KB 易于实现,示例丰富 图表种类少,bug多
Nivo - - - 241KB 独特图表,支持SSR 示例不直观,需设置容器尺寸
React-vis - 116 277 316KB 易于实现,图表选择多,自带CSS 一致性差,体积大,bug多

2. 性能优化技巧

2.1 数据加载

优化数据传输可以显著减少图表加载时间。只传输所需的指标,避免加载整个数据集。例如,在绘制日历图表时,只使用2019 - 2021年的数据,而不是包含2018年的完整数据集。

2.2 安装模块而非全局导入

对于D3(版本4及以上)和其他许多库,可以导入特定模块而不是整个库,从而显著减少应用程序的包大小。以下是具体步骤:
1. 安装 cra-bundle-analyzer 作为开发依赖:

yarn add --dev cra-bundle-analyzer
  1. 运行分析工具:
yarn analyzer
  1. 创建一个简单的React D3代码,分别使用全局导入和模块导入D3,并比较包大小。
// 全局导入
import * as d3 from 'd3'
// 模块导入
import { select } from 'd3-selection'

2.3 其他性能优化技巧

  • 服务器端渲染(SSR) :在服务器端生成HTML,减少客户端渲染时间。
  • Tree shaking :移除未使用的代码,减小包大小。
  • 仅在需要时更新DOM :避免不必要的DOM操作,提高性能。
  • 使用CSV代替JSON :CSV文件通常比JSON文件更小,传输速度更快。
  • 优化CRA :使用预渲染、预取和预缓存等技术。
  • 使用 useCallback 记忆函数 :避免不必要的函数重新创建。

综上所述,选择合适的React D3库可以提高开发效率,但需要根据具体需求权衡其优缺点。同时,采用性能优化技巧可以显著提升应用程序的性能。

3. 性能优化操作实例

3.1 数据加载优化实例

接下来通过具体例子展示如何优化数据加载。假设我们要创建一个股票价格可视化图表,原始数据包含了多只股票多年的详细信息,但我们只需要某一只股票近一年的数据。

操作步骤
  1. 数据筛选 :在后端对数据进行筛选,只返回所需的股票近一年的数据。以下是一个简单的Node.js示例:
const express = require('express');
const app = express();
const allStockData = require('./allStockData.json');

app.get('/stockData', (req, res) => {
    const targetStock = 'ABC';
    const oneYearAgo = new Date();
    oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);

    const filteredData = allStockData.filter(item => {
        return item.stockName === targetStock && new Date(item.date) >= oneYearAgo;
    });

    res.json(filteredData);
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server running on port ${port}`);
});
  1. 前端获取数据 :在前端使用 fetch 请求筛选后的数据:
async function getStockData() {
    try {
        const response = await fetch('/stockData');
        const data = await response.json();
        // 使用数据绘制图表
        drawChart(data);
    } catch (error) {
        console.error('Error fetching data:', error);
    }
}

function drawChart(data) {
    // 绘制图表的代码
}

getStockData();

3.2 安装模块而非全局导入实例

继续以之前创建的 Rectangle 组件为例,展示如何通过导入特定模块来减小包大小。

操作步骤
  1. 创建组件 :使用 npx generate-react-cli 创建 Rectangle 组件:
npx generate-react-cli component Rectangle --type=d3
  1. 安装依赖 :安装全局D3库和 d3-selection 模块:
yarn add d3-selection @types/d3-selection
yarn add d3 @types/d3
  1. 全局导入示例
// src/component/Rectangle/Rectangle.tsx
import React, { useEffect, RefObject } from 'react';
import * as d3 from 'd3';

const Rectangle = () => {
    const ref: RefObject<HTMLDivElement> = React.createRef();
    useEffect(() => {
        draw();
    });
    const draw = () => {
        d3.select(ref.current).append('p').text('Hello World');
        d3.select('svg')
          .append('g')
          .attr('transform', 'translate(250, 0)')
          .append('rect').attr('width', 500)
          .attr('height', 500)
          .attr('fill', 'tomato');
    };
    return (
        <div className="Rectangle" ref={ref}>
            <svg width="500" height="500">
                <g transform="translate(0, 0)">
                    <rect width="500" height="500" fill="green" />
                </g>
            </svg>
        </div>
    );
};

export default Rectangle;
  1. 模块导入示例
// src/component/Rectangle/Rectangle.tsx
import React, { useEffect, RefObject } from 'react';
import { select } from 'd3-selection';

const Rectangle = () => {
    const ref: RefObject<HTMLDivElement> = React.createRef();
    useEffect(() => {
        draw();
    });
    const draw = () => {
        select(ref.current).append('p').text('Hello World');
        select('svg')
          .append('g')
          .attr('transform', 'translate(250, 0)')
          .append('rect').attr('width', 500)
          .attr('height', 500)
          .attr('fill', 'tomato');
    };
    return (
        <div className="Rectangle" ref={ref}>
            <svg width="500" height="500">
                <g transform="translate(0, 0)">
                    <rect width="500" height="500" fill="green" />
                </g>
            </svg>
        </div>
    );
};

export default Rectangle;
  1. 比较包大小 :使用 cra-bundle-analyzer 分析包大小:
yarn add --dev cra-bundle-analyzer
yarn analyzer

通过对比可以发现,使用模块导入时D3的解析大小显著减小。

2.3 性能优化技巧总结

优化技巧 说明 操作步骤
数据加载优化 只传输所需的指标,避免加载整个数据集 后端筛选数据,前端请求筛选后的数据
安装模块而非全局导入 导入特定模块而非整个库,减小包大小 安装分析工具,对比全局导入和模块导入的包大小
服务器端渲染(SSR) 在服务器端生成HTML,减少客户端渲染时间 使用支持SSR的框架,如Next.js
Tree shaking 移除未使用的代码,减小包大小 使用支持Tree shaking的打包工具,如Webpack
仅在需要时更新DOM 避免不必要的DOM操作,提高性能 使用React的 shouldComponentUpdate React.memo
使用CSV代替JSON CSV文件通常比JSON文件更小,传输速度更快 使用CSV解析库,如 csv-parser
优化CRA 使用预渲染、预取和预缓存等技术 使用 react-scripts 的相关配置
使用 useCallback 记忆函数 避免不必要的函数重新创建 在函数定义时使用 useCallback

4. 性能优化流程

graph LR
    A[开始] --> B[数据加载优化]
    B --> C[安装模块而非全局导入]
    C --> D[服务器端渲染]
    D --> E[Tree shaking]
    E --> F[仅在需要时更新DOM]
    F --> G[使用CSV代替JSON]
    G --> H[优化CRA]
    H --> I[使用useCallback记忆函数]
    I --> J[结束]

通过以上的性能优化技巧和操作实例,我们可以在使用React D3库进行数据可视化开发时,提高应用程序的性能和用户体验。在选择库时,根据具体需求权衡各库的优缺点,同时结合性能优化技巧,打造高效、稳定的数据可视化应用。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值