d3.js+json-Python2014大会主题旭日图

原文地址:http://wow.techbrood.com/fiddle/2668

javascript

var margin = {
        top: 20,
        right: 0,
        bottom: 0,
        left: 0
    },
    width = 700,
    height = 600,
    radius = Math.min(width, height) / 2 - 10,
    color = d3.scale.category20c();

var getX = function(d) {
    return d.key;
};
var getY = function(d) {
    return d.values;
};

var parseDate = d3.time.format("%a, %b %d %Y").parse;

var sunburst_div = d3.select("#sunburst")

var tooltip = d3.select("#tooltip")
    .attr("class", "tooltip")
    .style("opacity", 0);

var partition = d3.layout.partition()
    .size([2 * Math.PI, radius * radius])
    .children(function(d) {
        return d.values;
    })
    .sort(function(a, b) {
        return d3.ascending(a.votes, b.votes);
    })
    .value(function(d) {
        return d.votes;
    });

var arc_start = d3.svg.arc()
    .startAngle(function(d) {
        return d.x;
    })
    .endAngle(function(d) {
        return d.x;
    })
    .innerRadius(function(d) {
        return Math.sqrt(d.y);
    })
    .outerRadius(function(d) {
        return Math.sqrt(d.y + d.dy);
    });

var arc = d3.svg.arc()
    .startAngle(function(d) {
        return d.x;
    })
    .endAngle(function(d) {
        return d.x + d.dx;
    })
    .innerRadius(function(d) {
        return Math.sqrt(d.y);
    })
    .outerRadius(function(d) {
        return Math.sqrt(d.y + d.dy);
    });

// d3js plugin for jsonp:: http://bl.ocks.org/tmcw/4494715
/*d3.jsonp = function(url, callback) {
    function rand() {
        var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
            c = '',
            i = -1;
        while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
        return c;
    }

    function create(url) {
        var e = url.match(/callback=d3.jsonp.(\w+)/),
            c = e ? e[1] : rand();
        d3.jsonp[c] = function(data) {
            callback(data);
            delete d3.jsonp[c];
            script.remove();
        };
        return 'd3.jsonp.' + c;
    }

    var cb = create(url),
        script = d3.select('head')
        .append('script')
        .attr('type', 'text/javascript')
        .attr('src', url.replace(/(\{|%7B)callback(\{|%7D)/, cb));
};
d3.jsonp('http://in.pycon.org/funnel/2014/json?callback=populate', function (d) {
    window.CP.stopExecutionOnTimeout(11);
    console.log(d);
});*/

//load from external json file
d3.json("http://wow.techbrood.com/uploads/141102/proposals.json",
    function populate(data) {
        var children = d3.nest()
            .key(function(d) {
                return d.level;
            })
            .key(function(d) {
                return d.section;
            })
            .entries(data.proposals);

        // adding a dummy root node
        var root = {
            "key": "Root",
            "values": children
        };

        draw_sunburst(sunburst_div, root, "PyConIN '14 - Proposals Sunburst Chart");
    })

/* //load from external csv
d3.csv("http://media.arundhaj.com/projects/pycon_visualization/pycon_proposals.csv", function(data) {
  data.forEach(function(d) {
    d.Vote = +d.Vote,
      d.Comments = +d.Comments,
      d.Submitted = parseDate(d.Submitted + " 2014")
  });

  // create tree hierarchy, depth 1: Level, depth 2: Section and depth 3: Topic.
  var children = d3.nest()
    .key(function(d) { return d.Level; })
    .key(function(d) { return d.Section; })
    .entries(data);

  // adding a dummy root node
  var root = {
    "key" : "Root",
    "values": children
  };

  // draw_sunburst(sunburst_div, root, "PyConIN '14 - Proposals Sunburst Chart");
});
*/

function draw_sunburst(div_element, root, heading) {
    var svg = div_element.append("svg")
        .attr("width", width)
        .attr("height", height);

    var head = svg.append("text")
        .attr("class", "head-text")
        .attr("x", (width / 2))
        .attr("y", (margin.top / 2) + 5)
        .text(heading);

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

    var path = g.datum(root).selectAll("path")
        .data(partition.nodes)
        .enter().append("path")
        .attr("display", function(d) {
            return d.depth ? null : "none";
        })
        .attr("d", arc_start)
        .style("stroke", "#fff")
        .style("fill", function(d) {
            return color((d.values ? d : d.parent).key)
        })
        .style("fill-rule", "evenodd");

    path
        .transition().duration(function(d) {
            return d.depth * 1000;
        })
        // .transition().duration(500)
        .attr("d", arc);

    path
        .on("mouseover", function(d) {
            var html = "";
            if (d.depth == 3) {
                html = "<i>Topic: </i><b>" + d.title + " </b><br />" +
                    "<i>Proposer: </i><b>" + d.proposer + " </b><br />" +
                    "<i>Section: </i><b>" + d.section + " </b><br />" +
                    "<i>Level: </i><b>" + d.level + " </b><br />" +
                    "<i>Votes: </i><b>" + d.votes + "</b>";
            } else {
                html = d.key;
            }

            tooltip.transition().duration(250)
                .style("opacity", ".9");

            tooltip.html(html)
                .style("left", (d3.event.pageX) + "px")
                .style("top", (d3.event.pageY) + "px");
        })
        .on("mouseout", function(d) {
            tooltip.transition().duration(250)
                .style("opacity", 0);
        });
}

html

<script src="/libs/d3.v3.min.js"></script>
<script src='http://d3js.org/d3.v3.min.js'></script>
<div id="sunburst"></div>
<div id="tooltip"></div>

css

svg {
    display: block;
    margin: auto;
    border: 1px solid lightgrey;
}
div.tooltip {
    position: absolute;
    text-align: center;
    padding: 7px;
    font: 12px sans-serif;
    background: lightsteelblue;
    border-radius: 4px;
    pointer-events: none;
}
.head-text {
    text-anchor: middle;
    font: 14px sans-serif;
    font-weight: bold;
}
text {
    font: 12px sans-serif;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值