D3学习之弦布局

几天的稍稍有点难度,估计还得反复多敲几遍才能有更深刻的领悟

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>弦图制作入门</title>
        <style type="text/css">
        .chord path {
            fill-opacity:0.67;
            stroke:#000;
            stroke-width:0.5px;
        }
        </style>
        <script type="text/javascript" src="../d3/d3.min.js"></script>
    </head>
    <body>
        <script type="text/javascript">
        //原数据
        var city_name = ["北京", "上海", "深圳", "广州", "香港"];
        //population矩阵
        //eg:第一行第一列表示北京本地人1000
        //第一行第二列表示北京有3045人来自上海
        //以此类推
        var population = [
           [1000, 3045, 4567, 1289, 3987],
           [1892, 3754, 3729, 1093, 3749],
           [3743, 3829, 7484, 3847, 2384],
           [1838, 3748, 4844, 4099, 1022],
           [2874, 2943, 1923, 2843, 3821]
        ];

        //转换数据格式
        //为画弦图所需要的数据
        var chord_layout = d3.layout.chord()
                             .padding(0.03)
                             .sortSubgroups(d3.descending)
                             .matrix(population);
        //padding:节点之间的间隔
        //sortSubgroups:排序,
        //每个城市的人口来源按照降序排序
        //体现在图形中就是顺时针子集数量减少
        //引入需要的矩阵population

        var groups = chord_layout.groups();
        var chords = chord_layout.chords();

        //groups:布局之后产生的节点
        //chords:布局之后产生的连线

        console.log(groups);
        console.log(chords);

        //截至到这儿,控制台输出的数据不太对
        //节点没有name元素
        //没有就对了
        //还没有添加节点的name

        var width = 600,
            height = 600;
        var innerRadius = width / 2 * 0.7;
        var 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) + ")");//?这个g
        //这里面的g是将整个svg看成是一个分组
        //将整个svg的坐标原点平移到了svg的中心
        var outer_arc = d3.svg.arc()
                          .innerRadius(innerRadius)
                          .outerRadius(outerRadius);
        //弧生成器
        var g_outer = svg.append("g");
        //g:指定外层圆环整个为一个组
        //每一个path和text都采用相同的计算

        g_outer.selectAll("path")
               .data(groups)
               .enter()
               .append("path")
               .style("fill", function (d) {return color(d.index);})
               .style("stroke", function (d) {return color(d.index);})
               .attr("d", outer_arc);
        //这里的path为将要生成的每一段弧
        //所以这儿的data采用的是布局之后产生的节点数据:groups

        g_outer.selectAll("text")
               .data(groups)
               .enter()
               .append("text")
               .each(function (d, i) {
                d.angle = (d.startAngle + d.endAngle) / 2;
                d.name = city_name[i];
               })
               .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)" : "");
               })
               .text(function (d) {return d.name;});
        //.35em:相对于当前对象内文本的字体尺寸
        //先rotate再translate
        //((d.angle > Math.PI * 3 / 4 && d.angle < Math.PI * 5 / 4) ? "rotate(180)" : "")
        //上一句为了让字全都是依着弧的方向正着的
        //此处才添加了城市名称:d.name
        var inner_chord = d3.svg.chord()
                            .radius(innerRadius);

        svg.append("g")
           .attr("class","chord")
           .selectAll("path")
           .data(chords)
           .enter()
           .append("path")
           .attr("d",inner_chord)
           .style("fill", function (d) {return color(d.source.index);})
           .style("opacity", 1)
           .on("mouseover", function (d, i) {
            d3.select(this)
              .style("fill", "yellow");
           })
           .on("mouseout", function (d,i) {
            d3.select(this)
              .transition()
              .duration(1000)
              .style("fill", color(d.source.index));
           })
        </script>
    </body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值