最近学习了下D3.js并仿照别人的案例写了个小demo【参考文章》http://wiki.jikexueyuan.com/project/d3wiki/chart.html】,遇到了一些问题,在这里记录下:
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的效果: