D3.js(v3)+react 制作 一个带坐标与比例尺的散点图 (V3版本) - 溢杨年华 - 博客园

上一章做了柱形图,https://www.cnblogs.com/littleSpill/p/10835041.html   这一章做散点图。

散点图(Scatter Chart),通常是一横一竖两个坐标轴,数据是一组二维坐标,分别对应两个坐标轴,与坐标轴对应的地方打上点。由此可以猜到,需要的元素包括circle(圆)axis(坐标轴)。需要进行可视化的数据有:

复制代码; "复制代码")

1   //圆心数据
2 var center = [ 3 [0.5,0.5],[0.7,0.8],[0.4,0.9], 4 [0.11,0.32],[0.88,0.25],[0.75,0.12], 5 [0.5,0.1],[0.2,0.3],[0.4,0.1],[0.6,0.7] 6 ]

复制代码; "复制代码")

然后定义一个SVG的绘制区域:

复制代码; "复制代码")

1   //定义一个svg的绘制区域。
2 var width = 600; //svg绘制区域的宽度
3 var height = 500; //svg绘制区域的高度
4
5 var svg = d3.select("#body") //选择id为body的div
6 .append("svg") //在<body>中添加<avg>
7 .attr("width",width) //设定<svg>的宽度属性
8 .attr("height",height) //设定<svg>的高度属性

复制代码; "复制代码")

数组中的每一项都是一个数组,子数组的第一项表示x值,第二项表示y值。实际应用中x轴和y轴可能对应着不同的意义,单位也可能不同。比如人口-GDP、烟龄-肺癌率等。这些数据都不可能直接用像素作单位来绘制,因为类似(0.5,0.5)、(0.7,0.8)这样的位置,即便绘制了也会看到圆都挤到一块,分不清彼此。因此要先使用比例尺将它们放大。

复制代码; "复制代码")

1   //定义比例尺
2 //x轴宽度
3 var xAxisWidth = 300;
4 //y轴宽度
5 var yAxisWidth = 300;
6 //x轴比例尺
7 var xScale = d3.scale.linear() //创建一个线性比例尺
8 .domain([0,1.2*d3.max(center,function(d){ //设定定义域
9 return d[0] 10 })]) 11 .range([0,xAxisWidth]) //设定值域
12 //y轴比例尺
13 var yScale = d3.scale.linear() //创建一个线性比例尺
14 .domain([0,1.2*d3.max(center,function(d){ //设定定义域
15 return d[1] 16 })]) 17 .range([0,yAxisWidth]) //设定值域

复制代码; "复制代码")

xAxisWidth和yAxisWidth可以根据需求设定。要注意,两个比例尺都是线性比例尺,在设定定义域domain时,使用了d3.max(),这是一个求数组最大值的函数。详情见https://www.cnblogs.com/littleSpill/p/10793275.html对于x轴的比例尺来说,这里的意思是,相对于center数组的每一项,返回其子数组的第一项(d[0])组成一个新的数组,然后再求最大值。最大值前面乘了一个1.2,这是为了使得散点图不会有某一点存在于坐标轴的边缘上。

下面在SVG中绘制图形,先绘制圆:

复制代码; "复制代码")

1   //在svg中绘制图形,先绘制圆
2 //外边框
3 var padding = {top:30,right:30,bottom:100,left:100};
4 //绘制圆
5 var circle = svg.selectAll("circle")
6 .data(center) //绑定数据
7 .enter() //获取enter部分
8 .append("circle") //
9
10 .attr("fill","goldEnrod") //设置颜色
11 .attr("cx",function(d){ //设置圆心的x坐标
12 return padding.left + xScale(d[0]) 13 }) 14 .attr("cy",function(d){ //设置圆心的y坐标
15 return height-padding.bottom-yScale(d[1]) 16 }) 17 .attr("r",5) //设置圆的半径

复制代码; "复制代码")

注意上面代码的粗体字部分,分别使用x轴和y轴的比例尺放大数据。

最后定义坐标轴:

复制代码; "复制代码")

1   //定义坐标轴
2 //x轴
3 var xAxis = d3.svg.axis() //创建一个默认的新坐标轴
4 .scale(xScale) //设定坐标轴的比例尺
5 .orient("bottom") //设定坐标轴的方向
6
7
8 yScale.range([yAxisWidth,0]) //重新设置y轴比例尺的值域,与原来的相反
9
10 //y轴
11 var yAxis = d3.svg.axis() //创建一个默认的新坐标轴
12 .scale(yScale) //设定坐标轴的比例尺
13 .orient("left") //设定坐标轴的方向
14
15 //添加x轴和平移
16 svg.append("g") //在svg中添加一个包含坐标轴各元素的g元素
17 .attr("class","axis") //定义class名
18 .attr("transform","translate("+padding.left+","+(height-padding.bottom)+")") //将x轴进行平移
19 .call(xAxis) //将自身作为参数传递给xAxis函数
20
21 //设置y轴和平移
22 svg.append("g") //在svg中添加一个包含坐标轴各元素的g元素
23 .attr("class","axis") //定义class名
24 .attr("transform","translate("+padding.left+","+(height-padding.bottom-yAxisWidth+")")) //将y轴进行平移
25 .call(yAxis)

复制代码; "复制代码")

看一下效果图:

完整代码:

复制代码; "复制代码")

1 import React, { Component } from 'react';
2 import * as d3 from 'd3'
3 class ScatterChart extends Component {
4 constructor(props) {
5 super(props);
6 this.state = {} 7 }
8
9 componentDidMount(){
10 this.oneMethod()
11 }
12
13 oneMethod(){
14
15 //圆心数据
16 var center = [ 17 [0.5,0.5],[0.7,0.8],[0.4,0.9],
18 [0.11,0.32],[0.88,0.25],[0.75,0.12],
19 [0.5,0.1],[0.2,0.3],[0.4,0.1],[0.6,0.7]
20 ]
21
22 //定义一个svg的绘制区域。
23 var width = 600; //svg绘制区域的宽度
24 var height = 500; //svg绘制区域的高度
25
26 var svg = d3.select("#body") //选择id为body的div
27 .append("svg") //在<body>中添加<avg>
28 .attr("width",width) //设定<svg>的宽度属性
29 .attr("height",height) //设定<svg>的高度属性
30
31 //定义比例尺
32 //x轴宽度
33 var xAxisWidth = 300;
34 //y轴宽度
35 var yAxisWidth = 300;
36 //x轴比例尺
37 var xScale = d3.scale.linear() //创建一个线性比例尺
38 .domain([0,1.2*d3.max(center,function(d){ //设定定义域
39 return d[0]
40 })])
41 .range([0,xAxisWidth]) //设定值域
42 //y轴比例尺
43 var yScale = d3.scale.linear() //创建一个线性比例尺
44 .domain([0,1.2*d3.max(center,function(d){ //设定定义域
45 return d[1]
46 })])
47 .range([0,yAxisWidth]) //设定值域
48
49 //在svg中绘制图形,先绘制圆
50 //外边框
51 var padding = {top:30,right:30,bottom:100,left:100};
52 //绘制圆
53 var circle = svg.selectAll("circle")
54 .data(center) //绑定数据
55 .enter() //获取enter部分
56 .append("circle") //
57
58 .attr("fill","goldEnrod") //设置颜色
59 .attr("cx",function(d){ //设置圆心的x坐标
60 return padding.left + xScale(d[0])
61 })
62 .attr("cy",function(d){ //设置圆心的y坐标
63 return height-padding.bottom-yScale(d[1])
64 })
65 .attr("r",5) //设置圆的半径
66
67 //定义坐标轴
68 //x轴
69 var xAxis = d3.svg.axis() //创建一个默认的新坐标轴
70 .scale(xScale) //设定坐标轴的比例尺
71 .orient("bottom") //设定坐标轴的方向
72
73
74 yScale.range([yAxisWidth,0]) //重新设置y轴比例尺的值域,与原来的相反
75
76 //y轴
77 var yAxis = d3.svg.axis() //创建一个默认的新坐标轴
78 .scale(yScale) //设定坐标轴的比例尺
79 .orient("left") //设定坐标轴的方向
80
81 //添加x轴和平移
82 svg.append("g") //在svg中添加一个包含坐标轴各元素的g元素
83 .attr("class","axis") //定义class名
84 .attr("transform","translate("+padding.left+","+(height-padding.bottom)+")") //将x轴进行平移
85 .call(xAxis) //将自身作为参数传递给xAxis函数
86
87 //设置y轴和平移
88 svg.append("g") //在svg中添加一个包含坐标轴各元素的g元素
89 .attr("class","axis") //定义class名
90 .attr("transform","translate("+padding.left+","+(height-padding.bottom-yAxisWidth+")")) //将y轴进行平移
91 .call(yAxis) //将自身作为参数传递给yAxis函数
92
93 }
94
95 render() {
96 return ( 97 <div id="body" >
98
99 </div>
100 ); 101 } 102 } 103
104 export default ScatterChart;

复制代码; "复制代码")

散点图就做完了。 接下来会给大家介绍绘制颜色和一些生成器。


原网址: 访问
创建于: 2023-01-15 23:16:06
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论