react结合d3.js和svg绘制条形统计图

6 篇文章 0 订阅

最近学习了下D3和仿照别人的案例写了个小demo,遇到了一些问题,在这里记录下:
1.遇到的一些坑:
(1.)D3.js中V3和V4的版本差别很大,所以一定要注意版本;
(2.)引用D3.js的js库文件的时候,应该通过npm安装库依赖,虽然D3.js不咋出名,但是npm还是可以安装它,安装命令是:
npm安装:npm install d3
前端导入:import * as d3 from 'd3';

(3.)react中css的解析和导入:
一:如果是通过create-react-app创建的项目,可以直接通过命令:

import './styles.css';

导入,可以参考蚂蚁金服的样式导入和操作;
二:非create-react-app项目,可以参考文章:
http://echizen.github.io/tech/2017/03-09-css-in-react
2.demo的源码:
animSVG.js


import React, { Component } from 'react';
import * as SimulationData from './svgData';
import * as d3 from 'd3';
import './styles.css';
//需要注意的问题:v3和v4版本差别很大,需要高度注意;
class AnimSVG extends React.Component {

    render() {
        {/* 定义柱状图的颜色数组; */ }
        const colors = ["#39D1DE", "#1CDB62", "#1FE015", "#A7E51F", "#E3E312", "#EA6A1F", "#29A0E3"];
        {/* 画布大小 */ }
        var width = 400;
        var height = 400;

        {/* 在 body 里添加一个 SVG 画布 */ }
        var svg = d3.select("body")
            .append("svg")
            .attr("width", width)
            .attr("height", height);

        {/* 画布周边的空白 */ }
        var padding = { left: 30, right: 30, top: 20, bottom: 20 };

        {/* 定义一个数组 */ }
        var dataset = [10, 20, 30, 40, 33, 24, 12, 5];

        {/* x轴的比例尺 */ }
        var xScale = d3.scale.ordinal()
            .domain(d3.range(dataset.length))
            .rangeRoundBands([0, width - padding.left - padding.right]);

        {/* y轴的比例尺 */ }
        var yScale = d3.scale.linear()
            .domain([0, d3.max(dataset)])
            .range([height - padding.top - padding.bottom, 0]);

        {/* 定义x轴 */ }
        var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient("bottom");

        {/* 定义y轴 */ }
        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left");

        {/* 矩形之间的空白间距的宽度; */ }
        var rectPadding = 4;

        //添加矩形元素
        var rects = svg.selectAll(".MyRect")
            .data(dataset)
            .enter()
            .append("rect")
            .attr("class", "MyRect")
            .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .attr("x", function (d, i) {
                return xScale(i) + rectPadding / 2;
            })
            .attr("width", xScale.rangeBand() - rectPadding)
            .attr("y", function (d) {
                var min = yScale.domain()[0];
                return yScale(min);
            })
            .attr("height", function (d) {
                return 0;
            })
            .transition()
            .delay(function (d, i) {
                return i * 200;
            })
            .duration(2000)
            .ease("bounce")
            .style("fill", function (uselsssVO, index) {
                var currentColorIndex = index % (colors.length);
                return colors[currentColorIndex];
            })
            .attr("y", function (d) {
                return yScale(d);
            })
            .attr("height", function (d) {
                return height - padding.top - padding.bottom - yScale(d);
            });

        {/* 添加文字元素 */ }
        var texts = svg.selectAll(".MyText")
            .data(dataset)
            .enter()
            .append("text")
            .attr("class", "MyText")
            .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .attr("x", function (d, i) {
                return xScale(i) + rectPadding / 2;
            })
            .attr("dx", function () {
                return (xScale.rangeBand() - rectPadding) / 2;
            })
            .attr("dy", function (d) {
                return 20;
            })
            .text(function (d) {
                return d;
            })
            .attr("y", function (d) {
                var min = yScale.domain()[0];
                return yScale(min);
            })
            .transition()
            .delay(function (d, i) {
                return i * 200;
            })
            .duration(2000)
            .ease("bounce")
            .attr("y", function (d) {
                return yScale(d);
            });

        {/* 添加x轴 */ }
        svg.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
            .call(xAxis); 

        {/* 添加y轴 */ }
        svg.append("g")
            .attr("class", "axis")
            .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
            .call(yAxis);

        return (
            <svg xmlns="http://www.w3.org/2000/svg"></svg>
        );
    }
}

export default AnimSVG;

styles.css

.axis path,
.axis line {
    fill: none;
    stroke: black;
    shape-rendering: crispEdges;
}

.axis text {
    font-family: sans-serif;
    font-size: 11px;
}

.MyRect {
    fill: steelblue;
}

.MyText {
    fill: white;
    text-anchor: middle;
}

3.demo的效果:
这里写图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值