转自:http://www.ourd3js.com/wordpress/?p=660

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

发表于2014/12/08

在 SVG 绘制区域中作图,在绘制直线和曲线时,常需要在某处添加箭头。本文介绍如何在 D3 中给直线和曲线添加箭头。

到目前为止,我们绘制 D3 的图表都是在 SVG 绘制区域内,虽然 D3 也可用 Canvas 或 WebGL 等作图,但 SVG 是最常用的。那么,用 D3 来绘制箭头,先要明白在 SVG 中是怎么绘制的。

1. 在 SVG 中定义箭头的标识

定义箭头的标识如下,先写一对 <defs> ,里面再写一对 <marker>,其中 marker 的属性的意义为:

viewBox 坐标系的区域
refX, refY 在 viewBox 内的基准点,绘制时此点在直线端点上(要注意大小写)
markerUnits 标识大小的基准,有两个值:strokeWidth(线的宽度)和userSpaceOnUse(图形最前端的大小)
markerWidth, markerHeight 标识的大小
orient 绘制方向,可设定为:auto(自动确认方向)和 角度值
id 标识的id号

然后在 marker 里绘制图形即可,下面的代码中用 path 绘制了一个箭头的图形。

<defs>
<marker id="arrow"
markerUnits="strokeWidth"
markerWidth="12"
markerHeight="12"
viewBox="0 0 12 12"
refX="6"
refY="6"
orient="auto">
<path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: #000000;" />
</marker>
</defs>
1
2
3
4
5
6
7
8
9
10
11
12
<defs>
<marker id="arrow"
markerUnits="strokeWidth"
markerWidth="12"
markerHeight="12"
viewBox="0 0 12 12"
refX="6"
refY="6"
orient="auto">
        <path d="M2,2 L10,6 L2,10 L6,6 L2,2" style="fill: #000000;" />
</marker>
</defs>

2. 在 SVG 中绘制箭头

有了上面的标识,就可以绘制箭头了。下面绘制一条线段,在线段末尾添加箭头:

<line x1="0" y1="0" x2="200" y2="50" stroke="red" stroke-width="2" marker-end="url(#arrow)"/>
1
<line x1="0" y1="0" x2="200" y2="50"  stroke="red" stroke-width="2" marker-end="url(#arrow)"/>

也可以用 path 来绘制:

<path d="M20,70 T80,100 T160,80 T200,90" fill="white" stroke="red" stroke-width="2" marker-start="url(#arrow)" marker-mid="url(#arrow)" marker-end="url(#arrow)"/>
1
<path d="M20,70 T80,100 T160,80 T200,90" fill="white" stroke="red" stroke-width="2" marker-start="url(#arrow)" marker-mid="url(#arrow)" marker-end="url(#arrow)"/>

在不同的位置绘制的属性如下:

  • marker-start :路径起点处
  • marker-mid:路径中间端点处(必须是 path 中间出现的点)
  • marker-end :路径终点处

3. 使用 D3 绘制箭头

有了上面的内容,在 D3 中如何绘制呢?

先定义箭头的标识:

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);

var defs = svg.append("defs");

var arrowMarker = defs.append("marker")
.attr("id","arrow")
.attr("markerUnits","strokeWidth")
.attr("markerWidth","12")
.attr("markerHeight","12")
.attr("viewBox","0 0 12 12")
.attr("refX","6")
.attr("refY","6")
.attr("orient","auto");

var arrow_path = "M2,2 L10,6 L2,10 L6,6 L2,2";

arrowMarker.append("path")
.attr("d",arrow_path)
.attr("fill","#000");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
 
var defs = svg.append("defs");
 
var arrowMarker = defs.append("marker")
.attr("id","arrow")
.attr("markerUnits","strokeWidth")
    .attr("markerWidth","12")
                        .attr("markerHeight","12")
                        .attr("viewBox","0 0 12 12")
                        .attr("refX","6")
                        .attr("refY","6")
                        .attr("orient","auto");
 
var arrow_path = "M2,2 L10,6 L2,10 L6,6 L2,2";
 
arrowMarker.append("path")
.attr("d",arrow_path)
.attr("fill","#000");

使用上述 marker 绘制箭头的代码为:

//绘制直线
var line = svg.append("line")
.attr("x1",0)
.attr("y1",0)
.attr("x2",200)
.attr("y2",50)
.attr("stroke","red")
.attr("stroke-width",2)
.attr("marker-end","url(#arrow)");

//绘制曲线
var curve_path = "M20,70 T80,100 T160,80 T200,90";

var curve = svg.append("path")
.attr("d",curve_path)
.attr("fill","white")
.attr("stroke","red")
.attr("stroke-width",2)
.attr("marker-start","url(#arrow)")
.attr("marker-mid","url(#arrow)")
.attr("marker-end","url(#arrow)");

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//绘制直线
var line = svg.append("line")
.attr("x1",0)
.attr("y1",0)
.attr("x2",200)
.attr("y2",50)
.attr("stroke","red")
.attr("stroke-width",2)
.attr("marker-end","url(#arrow)");
 
//绘制曲线
var curve_path = "M20,70 T80,100 T160,80 T200,90";
 
var curve = svg.append("path")
.attr("d",curve_path)
.attr("fill","white")
.attr("stroke","red")
.attr("stroke-width",2)
.attr("marker-start","url(#arrow)")
.attr("marker-mid","url(#arrow)")
.attr("marker-end","url(#arrow)");

结果图为本文开始的图片所示,完整代码为:

SVG版:http://www.ourd3js.com/demo/J-4.0/arrow.svg

D3版:http://www.ourd3js.com/demo/J-4.0/arrow.html

【 D3.js 进阶系列 — 4.0 】 绘制箭头的更多相关文章

  1. 【 D3.js 进阶系列 — 5.0 】 直方图

    直方图用于描写叙述概率分布,D3 提供了直方图的布局 Histogram 用于转换数据. 假设有数组 a = [10, 11, 11.5, 12.5, 13, 15, 19, 20 ],如今把10~2 ...

  2. 【 D3.js 进阶系列 — 1.0 】 CSV 表格文件的读取

    在入门系列的教程中.我们经常使用 d3.json() 函数来读取 json 格式的文件.json 格式非常强大.但对于普通用户可能不太适合,普通用户更喜欢的是用 Microsoft Excel 或 O ...

  3. 【 D3.js 进阶系列 】 进阶总结

    进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...

  4. 【 D3.js 进阶系列 — 1.1 】 其它表格文件的读取

    CSV 表格文件是以逗号作为单元分隔符的,其他还有以制表符 Tab 作为单元分隔符的 TSV 文件,还有人为定义的其他分隔符的表格文件.本文将说明在 D3 中怎样读取它们. 1. TSV 表格文件是什 ...

  5. 【 D3.js 进阶系列 — 1.2 】 读取 CSV 文件时乱码的解决方法

    在 D3 中使用 d3.csv 读取 CSV 文件时,有时会出现乱码问题. 怎么解决呢? 1. 乱码问题 使用 d3.csv 读取 xxx.csv 文件时.假设 xxx.csv 文件使用的是 UTF- ...

  6. 【 D3.js 高级系列 — 8.0 】 标线

    有时候,需要在地图上绘制连线,表示"从某处到某处"的意思,这种时候在地图上绘制的连线,称为"标线". 1. 标线是什么 标线,是指地图上需要两个坐标以上才能表示 ...

  7. 【 D3.js 高级系列 — 4.0 】 矩阵树图

    矩阵树图(Treemap),也是层级布局的扩展,根据数据将区域划分为矩形的集合.矩形的大小和颜色,都是数据的反映.许多门户网站都能见到类似图1,将照片以不同大小的矩形排列的情形,这正是矩阵树图的应用. ...

  8. 【 D3.js 高级系列 — 8.0 】 打标

    有时,需要在地图上画线.代表"从地方到什么地方"的含义,因此,在连接的映象绘制时.称为"打标". 1. 标线是什么 标线.是指地图上须要两个坐标以上才干表示的元 ...

  9. 【 D3.js 进阶系列 — 6.1 】 缩放的应用(Zoom)

    缩放(Zoom)是另一种重要的可视化操作,主要是使用鼠标的滚轮进行. 1. zoom 的定义 缩放是由 d3.behavior.zoom() 定义的. var zoom = d3.behavior.z ...

随机推荐

  1. php集成开发环境xampp的搭建

    一:运维闲谈 作为一名linux运维工程师,在确保能够有熟练的服务器的搭建和维护优化技能的前提,还需对自身解决问题方法上做出一番功夫. 如何为自己的运维工作添砖加瓦,自动化运维便变得非常重要,一方面, ...

  2. scrapy--selenium(二)

    今天学习了很多,还是想给大家讲一讲正题:scrapy的动态加载AJax的网页爬取:selenium.让我们开始 三: 针对大型电商网站:京东网,因为比较有代表性,爬出来有点小成就.先给大家看下效果图. ...

  3. python__系统 : 进程

    在类unix操作系统下,可以用 os.fork() 创建一个新的进程,windows系统不可以: import os ret = os.fork() print('ret=%d' % ret) : p ...

  4. JZOJ 5913. 林下风气

    Description 里口福因有林下风气,带领全国各地高校掀起了一股AK风,大家都十分痴迷于AK.里口福为了打击大家的自信心,出了一道自以为十分困难的题目.里口福有一棵树,第i个节点上有点权ai,他 ...

  5. 2-安装linux7

    1.操作系统简介 操作系统: 桌面操作系统 redhat fedora slackware ubuntu debian suse linux centos 服务器操作系统 linux redhat s ...

  6. Qsys配置生成nios系统模块

    1. 本次使用的是别人写好的例程,主要研究学习,使用quartus 11打开工程 2. bdf文件是块编辑器的,相当于原理图,以前只在用NIOS的时候会用到这种方式.接下来新建一个工程,添加原理图元件 ...

  7. R语言中的机器学习包

    R语言中的机器学习包   Machine Learning & Statistical Learning (机器学习 & 统计学习)  网址:http://cran.r-project ...

  8. erlang连接mysql [转]

    转自: http://blog.csdn.net/flyinmind/article/details/7740540 项目中用到erlang,同时也用到mysql.惯例,google. 但是,按照网上 ...

  9. 初学JS——利用JS制作的别踩白块儿(街机模式) 小游戏

    这个是上个星期5写的了,当时是突然想写个游戏,就想到了别踩白块儿,当时的想法是 可能普通模式的别踩白块儿因为他的“块儿”是滚动的向上这种,以我目前会的技术想不出怎么写, 但是如果是街机模式,通过你每按 ...

  10. PJMEDIA之录音器的使用(capture sound to avi file)

    为了熟悉pjmedia的相关函数以及使用方法,这里练习了官网上的一个录音器的例子. 核心函数: pj_status_t pjmedia_wav_writer_port_create ( pj_pool ...