本示例是基于Typescript 和 D3 五版本绘制树状图。
网上绝大多数都是D3 3版本,四版本也有一些示例,比较少,5版本几乎没有。这里是结合TS 和 D3 5版本的一个示例:
直接上代码:
/**
* create by yanle
* create time 2018-10-30 15:21
*/
import {hierarchy, tree} from "d3-hierarchy";
import {DefaultLinkObject, line, Link, linkHorizontal, linkVertical} from "d3-shape";
import {select, selectAll} from "d3-selection";
class Demo8 {
private treeData: any = {
"name": "中国",
"children":
[
{
"name": "浙江",
"children":
[
{"name": "杭州"},
{"name": "宁波"},
{"name": "温州"},
{"name": "绍兴"}
]
},
{
"name": "广西",
"children":
[
{
"name": "桂林",
"children":
[
{"name": "秀峰区"},
{"name": "叠彩区"},
{"name": "象山区"},
{
"name": "七星区",
"children":
[
{"name": "哈尔滨"},
{"name": "齐齐哈尔"},
{"name": "牡丹江"},
{"name": "大庆"}
]
}
]
},
{"name": "南宁"},
{"name": "柳州"},
{"name": "防城港"}
]
},
{
"name": "黑龙江",
"children":
[
{"name": "哈尔滨"},
{"name": "齐齐哈尔"},
{"name": "牡丹江"},
{"name": "大庆"}
]
},
{
"name": "新疆",
"children":
[
{"name": "乌鲁木齐"},
{"name": "克拉玛依"},
{"name": "吐鲁番"},
{"name": "哈密"}
]
}
]
};
main() {
let width: number = 900;
let height: number = 1400;
let treeWidth: number = width - 50;
let treeHeight: number = height - 50;
let treeMain = tree()
.size([width, treeWidth - 300])
.separation(function (a, b) {
return (a.parent === b.parent) ? 1 : 2
});
const hierarchyData = hierarchy(this.treeData).sum(function (d) {
return d.value
});
// 这样写是为了 让数据横向显示 x, y 互换
const renderLink: Link<any, DefaultLinkObject, [number, number]> = linkHorizontal().x(function (d: any) {
return d.y
}).y(function (d: any) {
return d.x
});
const lineMain = line();
// 创建svg
let svg = select('body')
.append('svg')
.attr('width', treeWidth)
.attr('height', treeHeight)
.append('g')
.attr('transform', 'translate(40, 0)');
let g = svg.append('g').attr('transform', 'translate(40, 40)');
treeMain(hierarchyData);
const nodes = hierarchyData.descendants();
const links = hierarchyData.links();
// 绘制线
g.selectAll('.link')
.data(links)
.enter()
.append('path')
.attr('class', 'link')
.attr("fill", "none") // 这个是取消默认填充色
.attr("stroke", "#000") // 给与一个自己的 外框填充色
.attr('d', function (d: any) {
return renderLink(d)
});
// 绘制节点
g.selectAll('.node')
.data(nodes)
.enter()
.append('g')
.attr('class', 'node')
.attr('transform', function (d: any) { // 这样写是为了 让数据横向显示
return `translate(${d.y}, ${d.x})`
});
g.selectAll('.node')
.append('circle')
.attr('r', 5)
.attr('fill', 'green');
// 绘制文字
g.selectAll('.node')
.append('text')
.attr('dy', 3)
.attr('x', function (d: any) {
return d.children ? -8 : 8;
})
.attr('text-anchor', function (d: any) {
return d.children ? 'end' : 'start'
})
.text(function (d: any) {
return d.data.name
})
.style('font-size', '18px')
}
}
export default Demo8;
相关api介绍:
api | 说明
:- | :-
**d3.hierarchy** | **从给定的层次结构数据构造一个根节点并为各个节点指定深度等属性.**
node.ancestors | 从当前节点开始返回其祖先节点数组.
node.descendants | 从当前节点开始返回其后代节点数组.
node.leaves | 返回当前节点为根节点的子树的叶节点.
node.path | 返回从当前节点到指定目标节点的最短路径.
node.links | 返回当前节点所在子树的所有边.
node.sum | 评估和汇总定量值.
node.sort | 排序所有的后代兄弟节点.
node.count | 统计叶节点的个数.
node.each | 广度优先遍历当前子树.
node.eachAfter | 后续遍历当前子树.
node.eachBefore | 前序遍历当前子树.
node.copy | 拷贝一个当前节点为根节点的子树的副本.
**d3.stratify** | **创建一个新的分层操作.**
stratify | 根据扁平数据创建一个分层数据.
stratify.id | 设置节点 id 访问器.
stratify.parentId | 设置父节点 id 访问器.
**d3.cluster** | **创建一个新的集群(系统树图)布局.**
cluster | 将指定的数据布局为系统树图.
cluster.size | 设置布局尺寸.
cluster.nodeSize | 设计节点尺寸.
cluster.separation | 设置两个叶节点之间的间距.
**d3.tree** | **创建一个新的整齐(同深度节点对齐)的树布局.**
tree | 将指定的层次数据布局为整齐的树布局.
tree.size | 设置布局尺寸.
tree.nodeSize | 设置节点尺寸.
tree.separation | 设置两个相邻的节点之间的间距.
具体项目请见github: https://github.com/yanlele/D3.js-learning
|
请发表评论