D3.js 以圆做点绘制力图(一)

SVG是什么?

如何在SVG上绘制一个圆?

如何在SVG上绘制一条线?

力图的基本属性有哪些?

这些问题将由本文来一一解答。

在代码方面,我们沿用上文的网页框架,把body里面的js替换成现在的js即可。

SVG

SVG,可缩放的矢量图,我们以后所绘制 的数据展示图大都是在SVG这个大容器内完成的,它相当于画布。创建SVG,就是有利于导出、保存绘制好的图形。

简单的SVG标签格式 <svg width="500" height="50"></svg>,在SVG标签中可以嵌入很多可见元素,包括 rect、circle、ellipse、line、text和path。

下面,我们在body中创建一个js标签,在里面创建一个svg对象,代码如下:

<span style="font-size:14px;">var w = 500;
var h = 500;
var svg = d3.select("body")
  .append("svg")
  .attr("width", w)          //设置宽度
  .attr("height", h);        //设置高度

</span>

绘制圆

在svg内添加circle元素,先介绍下circle的基本属性:cx 圆心x坐标  cy圆心y坐标   r半径

接下来,绘制五个半径依次增大的圆,并将它们的圆心放到同一条y轴上,代码如下

<span style="font-size:14px;"> var dataset = [ 5, 10, 15, 20, 25 ];
 var circles = svg.selectAll("circle")
    .data(dataset)
    .enter()
    .append("circle");
  circles.attr("cx", function(d, i) {//圆心坐标从左向右依次递增,注意:i表示引入数据在数组的下标,如:d=5,i=0
        return (i * 50) + 25;
    })
    .attr("cy", h/2) //将圆心放到svg高度中间
    .attr("r", function(d) {//半径
        return d;
    })</span>

紧接着设置各圆的属性

<span style="font-size:14px;">    .attr("fill", "yellow")         //给各圆填充黄色
    .attr("stroke", "orange")       //给各圆边涂成橘黄
    .attr("stroke-width", function(d) { //按比例设置边的厚度
    return d/2;
});
</span>

至此,SVG上的圆就绘制完成了见下图

绘制线

在svg绘制一条线,首先要定义它的两个端点,起点和终点 (x1,y1)和(x2,y2)

线的基本属性包括:

  • x1 属性在 x 轴定义线条的开始
  • y1 属性在 y 轴定义线条的开始
  • x2 属性在 x 轴定义线条的结束
  • y2 属性在 y 轴定义线条的结束
<span style="font-size:14px;">var line = svg.append('line')
            .attr('x1',100)
            .attr('y1',100)
            .attr('x2',200)
            .attr('y2',200)
            .attr('style','stroke:rgb(99,99,99);stroke-width:2'); //描边宽度</span>

显示效果图如下:

用力图简介

有点有线,那么有关联的点用线相连,再设置下点之间的电荷排斥力,让没关联的点保持距离, 那么力图的雏形就形成了。

力学图( Force ),也有被翻译做力导向图等。这种图很有意思,先从初始数据开始,看下面代码:

{
  "nodes":[
    {"name":"Myriel","group":3,"QQ":"635511111"},
    {"name":"Napoleon","group":1,"QQ":"635511112"},
    {"name":"Mlle.Baptistine","group":1,"QQ":"635511113"},
    {"name":"Mme.Magloire","group":1,"QQ":"635511114"},
    {"name":"CountessdeLo","group":1,"QQ":"635511115"},
    {"name":"Geborand","group":1,"QQ":"635511116"},
    {"name":"Champtercier","group":1,"QQ":"635511117"},
    {"name":"Cravatte","group":1,"QQ":"635512111"},
    {"name":"Count","group":1,"QQ":"635513111"},
    {"name":"OldMan","group":1,"QQ":"635514111"},
    {"name":"Labarre","group":2,"QQ":"635515111"},
    {"name":"Valjean","group":2,"QQ":"635516111"},
    {"name":"Marguerite","group":3,"QQ":"635531111"},
    {"name":"Mme.deR","group":2,"QQ":"635511311"},
    {"name":"Isabeau","group":2,"QQ":"635511211"},
    {"name":"Gervais","group":2,"QQ":"635514111"},
    {"name":"Tholomyes","group":3,"QQ":"635571111"},
    {"name":"Listolier","group":3,"QQ":"635581111"},
    {"name":"Fameuil","group":3,"QQ":"635511011"},
    {"name":"Blacheville","group":3,"QQ":"635211111"},
    {"name":"Favourite","group":3,"QQ":"635510111"},
    {"name":"Dahlia","group":3,"QQ":"635511121"}
  ],
  "links":[
    {"source":1,"target":0,"value":1},
    {"source":2,"target":0,"value":8},
    {"source":3,"target":0,"value":10},
    {"source":3,"target":2,"value":6},
    {"source":4,"target":0,"value":1},
    {"source":5,"target":0,"value":1},
    {"source":6,"target":0,"value":1},
    {"source":7,"target":0,"value":1},
    {"source":8,"target":0,"value":2},
    {"source":9,"target":0,"value":1},
    {"source":11,"target":1,"value":1},
    {"source":11,"target":3,"value":3},
    {"source":11,"target":2,"value":3},
    {"source":11,"target":0,"value":5},
    {"source":12,"target":2,"value":1},
    {"source":13,"target":2,"value":1},
    {"source":14,"target":2,"value":1},
    {"source":15,"target":2,"value":1},
    {"source":17,"target":3,"value":4},
    {"source":18,"target":3,"value":4},
    {"source":18,"target":3,"value":4},
    {"source":19,"target":3,"value":4},
    {"source":19,"target":2,"value":4},
    {"source":19,"target":3,"value":4},
    {"source":20,"target":4,"value":3},
    {"source":20,"target":1,"value":3},
    {"source":20,"target":2,"value":3},
    {"source":20,"target":3,"value":4},
    {"source":21,"target":16,"value":3},
    {"source":21,"target":17,"value":3},
    {"source":21,"target":18,"value":3},
    {"source":21,"target":19,"value":3},
    {"source":21,"target":20,"value":5}
  ]
}

这些数据包含两部分,点(nodes)和边(links),source 和target的数值代表nodes数组该数值下标对应的元素。

注意的一点,不管nodes元素有多少属性,source和target都暂时指向人名,如source 1 target0 表示napoleon和myriel连接

细细一看就会发现,这些点只是些人员的属性而已,光靠这些是无法知道每个点该画到哪儿。

所以就需要先了解一下D3 画力图的一些专有方法了 。下面为大家罗列一些必要的方法和解释:

为了使用方便先将上面的json数据,赋值给 dataset,放到js里

(以后这些数据都会保存在相应格式的文件中,由d3加载,加载方法在 D3总体展示篇已略有介绍)

var force = d3.layout.force()  //转换数据的方法,将点转换为坐标格式
.nodes(<span style="font-size:14px;">dataset.</span>nodes)          //传入点
.links(dataset.links)          //传入边
.size([w, h])                  //设置图形宽高
.start();                      //开始转换

以上代码是 用力图最基础的布局方法。

这些基本布局并不能满足所有数据集,我们还要在这基础上添加一些layout的自定义方法,

比如设置节点间连线的长度、节点间互斥力大小。完善之后的代码显示如下:

var force = d3.layout.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([w, h])
.linkDistance([50]) // 节点连线长度
.charge([-100]) //    排斥力
.start();

至此,力图基本初始化布局完成

接下来创建连线

var edges = svg.selectAll("line")
.data(dataset.edges)
.enter()
.append("line")
.style("stroke", "#ccc")
.style("stroke-width", 1);

这里的连线颜色和宽度都可以编写函数随意设定,例如同类人员设为同色,重要人员连线加粗等

然后为每个节点创建圆,方便浏览

var nodes = svg.selectAll("circle")
.data(dataset.nodes)
.enter()
.append("circle")
.attr("r", 10)
.style("fill", function(d, i) {
return colors(i);
})
.call(force.drag);    //增加拖动效果,拉动节点

最后,我们就要打点,将点线绘制到画布上

force.on("tick", function() {
edges.attr("x1", function(d) { return d.source.x; })
     .attr("y1", function(d) { return d.source.y; })
     .attr("x2", function(d) { return d.target.x; })
     .attr("y2", function(d) { return d.target.y; });

nodes.attr("cx", function(d) { return d.x; })
     .attr("cy", function(d) { return d.y; });
});

这样,每次打点,取得线和点的坐标,在更新到画布上。那么这些坐标哪儿来的?就是layout初始化转换传入的点线数据后,

为他们模拟一些坐标信息。你可以在浏览器控制台输入dataset查看各点线坐标信息

好了,最简单的用力图就这样完成了,后文会继续在此基础上讲解如何为个点设置图标、如何实现不同分组的群成员聚类缩放、如何显示成员信息、如何将圆替换为矩形块放置属性联系方式等,敬请期待!

				
时间: 2024-11-05 15:58:22

D3.js 以圆做点绘制力图(一)的相关文章

【玩转D3.js】--(1)绘制网格线

我们常常使用常规图表(直方图,折线图等)来表现数据.为了清楚的表示数据在数轴上的哪个数值区间,会直接在矩形和点上标注数值. 除了这个办法外,还可以使用色调偏淡的网格作为背景参照. 本文介绍了如何使用D3绘制网格线的小技巧: 绘制效果: 思路很简单: 1 绘制SVG容器. 2 给SVG分组,并设置分组的样式类. 3 为分组分别添加横线和竖线. 关键技术介绍 (1) 生成一个10元素的数组: (2) 定义x和y比例尺 x = d3.scale.linear().domain([0,1]).range

d3.js——箭头的绘制

首先我们要明白如何在svg中进行箭头的绘制: 先写一对<defs>,里面再写一对<marker>,其中marker的属性意义为: viewBox 坐标系的区域 refX, refY 在 viewBox 内的基准点,绘制时此点在直线端点上(要注意大小写) markerUnits 标识大小的基准,有两个值:strokeWidth(线的宽度)和userSpaceOnUse(图形最前端的大小) markerWidth, markerHeight 标识的大小 orient 绘制方向,可设定为

d3.js:数据可视化利器之快速入门

hello,data! 在进入d3.js之前,我们先用一个小例子回顾一下将数据可视化的基本流程. 任务 用横向柱状图来直观显示以下数据: var data = [10,15,23,78,57,29,34,71]; 简单地思考一下,要完成这个任务有两个问题需要解决: 用什么可视元素来表现横向柱? 数据对应到可视元素的什么属性? 这个不算困难,我们使用HTML的DIV元素来实现,代码参见http://www.hubwiz.com/course/54fd40cfe564e50d50dcf284/:快速

【D3.js数据可视化实战】--(3)桑基图(sankey)的绘制

什么是桑基图 用D3绘制简单的Sankey图 添加文字 圆形节点 添加交互效果 注:本文未经作者允许严禁转载和演绎 1 什么是桑基图? 桑基图是流图 (flow diagram )的一种,用来描述能量,人口,经济等的流动情况.最早由爱尔兰人Matthew Henry Phineas Riall Sankey 提出.Sankey是一名船长也是工程师,1898年Sankey在土木工程师学会会报纪要的一篇关于蒸汽机能源效率的文章中首次推出了第一个能量流动图,后来被命名为Sankey图,中文音译为桑基图

[3] 用D3.js做一个简单的图表吧!

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 前面说了几节,都是对文字进行处理,这一节中将用 D3.js 做一个简单的柱形图. 做柱形图有很多种方法,比如用 HTML 的 div 标签,或用 svg . 推荐用 SVG 来做各种图形.SVG 意为可缩放矢量图形(Scalable Vector Graphics),SVG 使用 XML 格式定义图像,不清楚什么是SVG的朋友请先在 w3cschools 学习下

【 D3.js 入门系列 --- 10 】 地图的绘制

本人的个人博客为:www.ourd3js.com csdn博客为:blog.csdn.net/lzhlzz 转载请注明出处,谢谢. 地图的制作在 D3 中可以说是最重要的一环.因为在进行数据可视化时,很多情况都会和地图联系在一起,如中国各省的人口多少,GDP多少等,都可以和地图联系在一起. D3 中制作地图所需要的文件问 JSON 文件.JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.关于 JSON 的语法格式,可以在: http://www.w3s

【 D3.js 进阶系列 — 4.0 】 绘制箭头

在 SVG 绘制区域中作图,在绘制直线和曲线时,常需要在某处添加箭头.本文介绍如何在 D3 中给直线和曲线添加箭头. 到目前为止,我们绘制 D3 的图表都是在 SVG 绘制区域内,虽然 D3 也可用 Canvas 或 WebGL 等作图,但 SVG 是最常用的.那么,用 D3 来绘制箭头,先要明白在 SVG 中是怎么绘制的. 1. 在 SVG 中定义箭头的标识 定义箭头的标识如下,先写一对 <defs> ,里面再写一对 <marker>,其中 marker 的属性的意义为: vie

利用d3.js绘制中国地图

d3.js是一个比较强的数据可视化js工具.利用它画了一幅中国地图,如下图所示: 源码如下: <!DOCTYPE html> <html> <head> <script type="text/javascript" src="d3.js"></script> <script type="text/javascript" src="d3.csv.js">&l

利用d3.js绘制雷达图

利用d3,js将数据可视化,可以做到数据与代码的分离,方便以后修改数据. 这次利用d3.js绘制了一个五维的雷达图,即将多个对象的五种属性在一张图上对比. 数据写入data.csv.数据类型写入type.csv文件. 效果如下图所示 源码连接:http://download.csdn.net/detail/svap1/7358123 使用是只需调用 radar()函数即可,如下是测试页面代码. <!DOCTYPE html> <html> <head> <meta