前面已经说过D3的功能十分强大,但是往往实际使用时只需要用到一部分内容,在这里,就只用到了 比例尺 布局 两部分,外加 核心 的请求部分(请求数据),分别用来绘制Graph的显示坐标轴和图的顶点及边;

此处为博客中出现的关于Spark、Hadoop、Java、IDEA、Js及html相关内容的图片

绘制坐标轴

传统坐标轴

这里指的是 第一象限 的坐标轴,即两轴的坐标均为正数,坐标原点为(0,0)

具体可以看 这里,说的比较详细。

十字坐标轴

这里指的是 全象限 坐标轴,即两轴的坐标均从-∞开始,坐标原点为(0,0)

本质上,仍然是一般坐标轴的变形,主要原理有两点:

  • 一是利用 比例尺 对源数据做符合中心坐标轴的变换;
  • 二是创建坐标轴时利用attr("transform","translate(0,"+0.5*svgHight+")")来对坐标轴进行平移,从而达到原点在画布中心的十字坐标轴的效果。
创建比例尺
1
2
3
4
5
6
// 创建比例尺
var xScale = d3.scale.linear()
.domain([-50,50]).range([0,1000]);
//意思为生成数据是[-50,50],现在要映射到[0,1000]
var yScale = d3.scale.linear()
.domain([-50,50]).range([1000,0]);
添加坐标轴
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var formatPrecision = d3.format('');
// 定义X轴
var xAxis = d3.svg.axis()
.scale(xScale)
.ticks(11) // 粗略的设置刻度线的数量,包括原点
.orient('bottom')
.tickFormat(formatPrecision); // 设置刻度格式
// 定义Y轴
var yAxis = d3.svg.axis()
.scale(yScale)
.orient('left')
.ticks(11)
.tickFormat(formatPrecision);
// 创建X轴, svg中: g元素是一个分组元素
svg.append('g')
.attr('class', 'axis')
.attr("transform","translate(0,"+0.5*svgHight+")") // 平移到水平中间
.call(xAxis);
// 创建Y轴
svg.append('g')
.attr('class', 'axis')
.attr("transform","translate("+0.5*svgWidth+",0)") // 平移到竖直中间
.call(yAxis);

绘制图(circle+line)

关于图的绘制,本质上就是圆点和线的绘制,所以这也解释了为什么输入文件中的边数据也需要包含坐标的原因,因为在d3中绘制顶点和绘制边是互不相关的。

另外需要注意的是,这里不要直接返回源数据坐标,要带入到上述定义的 比例尺 中。

话不多说直接上代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 创建SVG
var svg = d3.select('#div'+index)
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHight);
// 设置标题
svg.append('text')
.attr('x', svgWidth / 2 - 120)
.attr('y', 30)
.attr('class', 'title')
.text('这是一个用d3画的简略坐标轴');
// 画点,即绘制图的顶点
svg.selectAll('circle')
.data(data.nodes) // json对象
.enter()
.append('circle')
.attr('cx', function(d) {
return xScale(d.cx); // 使用比例尺返回合适的变换
})
.attr('cy', function(d) {
return yScale(d.cy); // 同上
})
.attr("fill","#6495ed") // 填充颜色
.attr("origin", function(d) {
return d.cx+","+d.cy;
})
.attr('r', function(d) { // 圆点直径(大小)
if(d.value === 0||d.value/2===0)return 2;
else return d.value/2;
});
// 画线,即绘制图的边
svg.selectAll('line')
.data(data.links) // json对象
.enter()
.append('line')
.attr('x1',function(d){
return xScale(d.x1);
})
.attr('y1',function(d){
return yScale(d.y1);
})
.attr('x2',function(d){
return xScale(d.x2);
})
.attr('y2',function(d){
return yScale(d.y2);
})
.attr("stroke","gray") // 边的颜色
.attr('stroke-width', function() {
return 0.2; // 边的宽度(粗细)
});

数据读入

在数据读取方面,d3.js本身提供了一套请求操作,属于 核心 部分。具体的操作如下:

此处为博客中出现的关于Spark、Hadoop、Java、IDEA、Js及html相关内容的图片

可以直接使用上述的API进行文件读取,非常方便

1
2
3
4
d3.csv("data.csv",function(error,data){
if(error){...}
esle{...}
});

当然可以完美的结合JQuery进行数据操作:

1
2
3
$.getJSON("data.json, "", function(data) {
// 前面各部分内容,对data进行解析即可
}

最终效果

数据格式,见文章 D3+Node快速实现图数据的可视化

此处为博客中出现的关于Spark、Hadoop、Java、IDEA、Js及html相关内容的图片