ART和d3条形图反应原生

时间:2017-03-29 14:30:09

标签: d3.js charts react-native

我试图制作一个反应本机条形图来可视化我的Java组件中的波形数据。

但是我不能像这个例子那样使用d3.select,因为我使用ART而不是SVG:

http://alignedleft.com/tutorials/d3/making-a-bar-chart

所以我需要为条形图创建svg路径,但是我无法使用d3.shape来实现这一点。

我尝试过使用d3.shape步骤,但是没有给出所需的结果。

知道怎么做吗?

1 个答案:

答案 0 :(得分:5)

在您的应用程序中安装以下软件包之前,请执行以下操作

  1. D3规模
  2. D3-形状
  3. D3-格式
  4. D3轴
  5. D3-路径
  6. D3
  7. 创建一个文件BarChart.js

    import React from 'react';
    import { StyleSheet, View, ART, Dimensions, TouchableWithoutFeedback } from 'react-native';
    
    const {
        Surface,
        Group,
        Rectangle,
        ClippingRectangle,
        LinearGradient,
        Shape,
        Text,
        Path,
        Transform
    } = ART;
    
    import {
        max,
        ticks
    } from 'd3-array'
    
    import * as scale from 'd3-scale';
    import * as shape from 'd3-shape';
    import * as format from 'd3-format';
    import * as axis from 'd3-axis';
    import * as path from 'd3-path';
    import Colors from '../../color.js';
    const d3 = {
        scale,
        shape,
        format,
        axis,
        path,
    };
    
    import {
        scaleLinear,
        scaleBand,
        scaleTime
    }  from 'd3-scale';
    
    const colours = {
        black: 'black',
        blue: 'steelblue',
        brown: 'brown'
    }
    
    const data = [
        {frequency: 5, letter: 'a'},
        {frequency: 6, letter: 'b'},
        {frequency: 4, letter: 'c'},
        {frequency: 1, letter: 'd'},
        {frequency: 2, letter: 'e'},
        {frequency: 3, letter: 'f'}
    ];
    
    class Bar extends React.Component {
    
        constructor(props) {
            super(props);
            this.createBarChart = this.createBarChart.bind(this);
            this.drawLine = this.drawLine.bind(this);            
            this.getRandomColor = this.getRandomColor.bind(this);
        };
    
        getRandomColor() {
            return '#' + Math.random().toString(16).substr(-6);
        }               
    
        drawLine(startPoint, endPoint) {
            var path = d3.path.path();
            path.lineTo(startPoint, endPoint);
            return path;
        }
    
        createBarChart(x, y, w, h) {
            var path = d3.path.path();
            path.rect(x, y, w, h);
            return path;
        }
    
        render() {
            const screen = Dimensions.get('window');
            const margin = {top: 50, right: 25, bottom: 200, left: 25}
            const width = screen.width - margin.left - margin.right
            const height = screen.height - margin.top - margin.bottom
    
            const x = d3.scale.scaleBand()
                .rangeRound([0, width])
                .padding(0.1)
                .domain(data.map(d => d.letter))
    
            const maxFrequency = max(data, d => d.frequency)
    
            const y = d3.scale.scaleLinear()
                .rangeRound([height, 0])
                .domain([0, maxFrequency])
    
            const firstLetterX = x(data[0].letter)
            const secondLetterX = x(data[1].letter)
            const lastLetterX = x(data[data.length - 1].letter)
            const labelDx = (secondLetterX - firstLetterX) / 2
    
            const bottomAxis = [firstLetterX - labelDx, lastLetterX + labelDx]
    
            const bottomAxisD = d3.shape.line()
                                    .x(d => d + labelDx)
                                    .y(() => 0)
                                    (bottomAxis)
    
            const leftAxis = ticks(0, maxFrequency, 5)
    
            const leftAxisD = d3.shape.line()
                                .x(() => bottomAxis[0] + labelDx)
                                .y(d => y(d) - height)
                                (leftAxis)
            const notch = 5
            const labelDistance = 9
            const emptySpace = "";
            return(
                <View>
                <Surface width={screen.width} height={screen.height}>
                    <Group x={margin.left} y={margin.top}>
                        <Group x={0} y={height}>
                            <Group key={-1}>
                                <Shape d={bottomAxisD} stroke={colours.black} key="-1"/>
                                  {
                                    data.map((d, i) =>(
                                        <Group
                                            x={x(d.letter) + labelDx}
                                            y={0}
                                            key={i + 1}
                                        >
                                            <Shape d={this.drawLine(0, notch)} y2={notch} stroke={colours.black}/>
                                            <Text
                                              y={labelDistance}
                                              fill={colours.black}
                                              font="18px helvetica"
                                            >
                                              {d.letter}
                                            </Text>
                                        </Group>
                                    ))
                                  }
                            </Group>
                            <Group key={-2} >
                                <Shape stroke={colours.black} d={leftAxisD} key="-1"/>
                                {
                                    leftAxis.map((d, i) => (
                                        <Group x={0} y={y(d)-height} key={i + 1}>
                                            <Shape d={this.drawLine(notch, 0)} stroke={colours.black}/>
                                            <Text
                                                fill={colours.black}
                                                x={-15}
                                                y={-labelDistance}
                                                font="18px helvetica"
                                            >
                                                {d + emptySpace}
                                            </Text>
                                        </Group>
                                    ))
                                }
                            </Group>
                            {
                                data.map((d, i) => (
                                    <TouchableWithoutFeedback key={i} >
                                        <Shape
                                            d={this.createBarChart(x(d.letter), y(d.frequency) - height, x.bandwidth(), height - y(d.frequency))}
                                            fill={this.getRandomColor()}
                                            >
                                        </Shape>
                                    </TouchableWithoutFeedback>
                                ))
                            }
                        </Group>
                    </Group>
                </Surface>
                </View>
            )
        }
    }
    
    const styles = {
      container: {
        margin: 20,
      },
      label: {
        fontSize: 15,
        marginTop: 5,
        fontWeight: 'normal',
      }
    };
    
    
    export default Bar;
    

    然后在App.js文件中添加以下代码:

    import React, { Component } from 'react';
    import { View } from 'react-native;
    import './App.css';
    import BarChart from './BarChart';
    
    class App extends Component {
        constructor(props) {
            super(props);       
        }
    
        render() {            
            return (
                <View>
                     <BarChart/>
                </View>
            );
        }
    }
    
    export default App;
    

    谢谢,希望这会对你有帮助。