d3.js主要布局种类总结

 (本文章代码来自网络与《D3API详解》这本书,收集做学习交流之用)

1、捆绑布局

1.1、简介:

捆绑布局根据结点数据输入确定结点的父子关系,再根据边数据输入确定结点之间的边怎么画,当从一个结点映射出去的连接比较多时看上去像是形成一捆绳,所以叫捆图。适合展示如demo所示各大城市之间高铁连接关系这样的情况。

1.2、demo:

多个城市之间的高铁连接情况:

1.3、代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>捆图</title>
    <style>
        body{
            background-color: #000000;
        }

        .node circle {
            stroke: black;
            stroke-width: 2px;
        }

        .node text{
            font-size: 12px;
            font-family: simsun;
        }

        .link {
            fill: none;
            stroke: white;
            stroke-opacity: .5;
            stroke-width: 8px;
        }

    </style>

</head>
<body>
<script src="../../d3.js"></script>
<script>

    var width  = 1370;	//SVG绘制区域的宽度
    var height = 670;	//SVG绘制区域的高度

    var svg = d3.select("body")			//选择<body>
            .append("svg")			//在<body>中添加<svg>
            .attr("width", width)	//设定<svg>的宽度属性
            .attr("height", height);//设定<svg>的高度属性


    //1. 确定初始数据
    var vertex = {
        name: "",
        children:[
            {name: "北京"},{name: "上海"},{name: "杭州"},
            {name: "广州"},{name: "桂林"},{name: "昆明"},
            {name: "成都"},{name: "西安"},{name: "太原"}
        ]
    };

    var edges = [
        {source: "北京", target: "上海"},
        {source: "北京", target: "广州"},
        {source: "北京", target: "杭州"},
        {source: "北京", target: "西安"},
        {source: "北京", target: "成都"},
        {source: "北京", target: "太原"},
        {source: "北京", target: "桂林"},
        {source: "北京", target: "昆明"},
        {source: "北京", target: "成都"},
        {source: "上海", target: "杭州"},
        {source: "昆明", target: "成都"},
        {source: "西安", target: "太原"}
    ];

    var Zoom_data = 400;//这个值可以调节图的大小
    //2. 转换数据
    var cluster = d3.layout.cluster()
            .size([360, width/2 - Zoom_data])
            .separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });

    var bundle = d3.layout.bundle();

    //数据接口
    var nodes = cluster.nodes(vertex);
    var oLinks = map(nodes, edges);

    var links = bundle(oLinks);

    //将links中的source和target由名称替换成节点
    function map( nodes, links ){
        var hash = [];
        for(var i = 0; i < nodes.length; i++){
            hash[nodes[i].name] = nodes[i];
        }
        var resultLinks = [];
        for(var j = 0; j < links.length; j++){
            resultLinks.push({  source: hash[ links[j].source ],
                target: hash[ links[j].target ]
            });
        }
        return resultLinks;
    }

    //3. 绘图
    var line = d3.svg.line.radial()
            .interpolate("bundle")
            .tension(.85)
            .radius(function(d) { return d.y; })
            .angle(function(d) { return d.x / 180 * Math.PI; });

    gBundle = svg.append("g")
            .attr("transform", "translate(" + (width/2) + "," + (height/2) + ")");

    var color = d3.scale.category20c();

    var link = gBundle.selectAll(".link")
            .data(links)
            .enter()
            .append("path")
            .attr("class", "link")
            .attr("d", line);	//使用线段生成器


    var node = gBundle.selectAll(".node")
            .data( nodes.filter(function(d) { return !d.children; }) )
            .enter()
            .append("g")
            .attr("class", "node")
            .attr("transform", function(d) {
                return "rotate(" + (d.x- 90) + ")translate(" + d.y + ")" + "rotate("+ (90 - d.x) +")";
            });

    node.append("circle")
            .attr("r", 20)
            .style("fill",function(d,i){ return color(i); });

    node.append("text")
            .attr("dy",".2em")
            .style("text-anchor", "middle")
            .text(function(d) { return d.name; });

</script>

</body>
</html>

2、弦布局

2.1、简介:

弦图用来展示一组实体之间的关系,通过在不同的弧线之间画出二次贝塞尔曲线,将实体之间的关系表示在一张弦图中。下面展示了一个弦图,表示五个城市人口互相之间的来源关系,比如北京有2015人来自上海,上海有2060人来自广州。

2.2、demo:

2.3、代码:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>弦图</title>
    <style>
        body{
            background-color: #000000;
        }
    </style>
</head>

<body>
<script src="../../d3.js"></script>
<script>
    var city_name = ["北京","上海","广州","深圳","香港"];
    var population = [
        [1000,3015,4567,1234,3714],
        [3214,2000,2060,124,3234],
        [8761,6545,3000,8045,647],
        [3211,1067,3214,4000,1006],
        [2146,1034,6745,4764,5000]
    ];

    var chord_layout = d3.layout.chord()
            .padding (0.03)//取得或设置弦片段间的角填充,也就是每一个弦片段的间距啦
            .sortSubgroups(d3.descending)
            .matrix(population); // 取得或设置布局需要的关联矩阵数据

    var width = 800,
            height = 670;
    var innerRadius = width/2*0.7,
            outerRadius = innerRadius*1.1;
    var color = d3.scale.category20();

    var svg = d3.select("body").append("svg")
            .attr("width",width)
            .attr("height",height)
            .append("g")
            .attr("transform","translate("+width/2+","+height/2+")");

    var outer_arc = d3.svg.arc()
            .innerRadius(innerRadius)
            .outerRadius(outerRadius);

    var g_outer = svg.append("g");
    g_outer.selectAll("path")
            .data(chord_layout.groups) //返回index(行索引)、subindex(列索引)、startAngle、endAngle、value
            .enter()
            .append("path")
            .style("fill", function (d) {
                return color(d.index)
            }
    )
            .style("stroke", function (d) {
                return color(d.index)
            })
            .attr("d",outer_arc);

    g_outer.selectAll("text")
            .data(chord_layout.groups)
            .enter()
            .append("text")
            .each(function(d,i){
                d.angle = (d.startAngle+ d.endAngle)/2;
                d.name = city_name[i];
            }) //表示对于任何一个绑定的元素,都执行后面的无名函数 function 的代码,这里的代码为: 计算一个角度,赋值给 d.angle ;获取城市的名称。
            .attr("dy",".35em")
            .attr("transform",function(d){
                return "rotate("+(d.angle*180/Math.PI)+")"+"translate(0,"+-1.0*(outerRadius+10)+")"+((d.angle>Math.PI*3/4 && d.angle<Math.PI*5/4)?"rotate(180)":"");
            })//在用 transform 进行位移时,要注意转换的顺序: rotate -> translate,最后一行转换代码表示:当角度在135°到225°之间时,旋转180°。否则下方的文字是倒的,不利于观看。
            .text(function(d){return d.name;})
            .style("stroke","white");

    var inner_chord =
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jspyth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值