D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
shimizu
Full window
Github gist
邦画興行収入ツリーマップ
2007年〜2016年までの邦画興行収入ツリーマップ。
データ元
過去興行収入上位作品 一般社団法人日本映画製作者連盟
Built with
blockbuilder.org
<!DOCTYPE html> <meta charset="utf-8"> <title>映画興行収入ツリーマップ</title> <style> html, body { margin:0px; padding:0px; } form { margin-left:4px; } text { font: 10px sans-serif; } tspan:last-child { font-size: 9px; fill-opacity: 0.8; } .node rect { shape-rendering: crispEdges; } .node--hover rect { stroke: #000; } .tooltip { position: absolute; min-width: 150px; z-index: 10; padding: 0; background-color: #ffffff; color: #222222; font-size: 16px; border: 0; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; -webkit-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; -moz-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; -ms-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; opacity: 1; box-sizing: border-box; pointer-events: none; transform: translate(26px, -5px); } .tooltip { h4 { font-size: 16px; font-weight: bold; margin: 4px 0 12px 0; padding: 0 0 12px 0; border-bottom: 1px solid #e8e8e8; } h5 { font-size: 16px; margin: 0 0 3px 0; padding: 0 0 0 0; } } .tooltip .tooltip_container { padding: 10px; background-color: #ffffff; text-align: center; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; &:after { content: ""; position: absolute; bottom: -5px; height: 10px; left: 50%; margin-left: -5px; width: 10px; z-index: -1; right: auto; top: auto; margin-top: auto; background-color: rgb(255, 255, 255); -webkit-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; -moz-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; -ms-box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; box-shadow: rgba(0, 0, 0, 0.247059) 0px 1px 3px; -webkit-transform: rotate(45deg) scale(1); -moz-transform: rotate(45deg) scale(1); -ms-transform: rotate(45deg) scale(1); transform: rotate(45deg) scale(1); } } #contenner { width: 960px; } #info { width: 200px; margin: 10px auto; } .total { font-size: 0.8em; opacity: 0.7; } .unit { font-size: 0.8em; } .count, .persent { font-weight: bold; margin-right: 2px; } </style> <div id="contenner"> <form id="form" name="form" action=""> <input id="Checkbox1" type="checkbox" value="実写化" data-color="#ffcccc" checked="checked"/><label for="Checkbox1">実写化</label> <input id="Checkbox2" type="checkbox" value="アニメ" data-color="#ccffff" /><label for="Checkbox2">アニメ</label> <input id="Checkbox3" type="checkbox" value="特撮" data-color="#ccffcc" /><label for="Checkbox3">特撮</label> <input id="Checkbox4" type="checkbox" value="ドラマ" data-color="#ffccff" /><label for="Checkbox4">TVドラマ</label> <input id="Checkbox5" type="checkbox" value="小説" data-color="#ccccff" /><label for="Checkbox5">小説原作</label> <input id="Checkbox6" type="checkbox" value="その他" data-color="#ffffaf" /><label for="Checkbox6">その他</label> <div id="info"></div> </form> <svg width="960" height="1060"></svg> </div> <script src="//d3js.org/d3.v4.0.0-alpha.35.min.js"></script> <script> var total = 0; var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"); var format = d3.format(".1f"); var color = ["#333", "#ccc", "#fff"]; var stratify = d3.stratify() .parentId(function(d) { return d.id.substring(0, d.id.lastIndexOf(".")); }); var treemap = d3.treemap() .size([width, height]) .paddingOuter(3) .paddingTop(19) .paddingInner(1) .round(true); var cast = function(d){ Object.keys(d).forEach(function(key){ d[key] = d[key].trim(); if (d[key] && !isNaN(+d[key])) d[key] = +d[key]; }); return d; }; d3.tsv("movie.tsv", cast, function(error, data) { if (error) throw error; var nested = d3.nest() .rollup(function(d){ return d[0]; }) .key(function(d){ return d.uid ;}) .map(data); var root = stratify(data) .sum(function(d) { return d["興収(単位:億円)"] ; }) .sort(function(a, b) { return b["興収(単位:億円)"] - a["興収(単位:億円)"]; }); treemap(root); var cell = svg .selectAll(".node") .data(root.descendants()) .enter().append("g") .attr("transform", function(d) { return "translate(" + d.x0 + "," + d.y0 + ")"; }) .attr("class", "node") .each(function(d) { d.node = this; }) .on("mouseover", hovered(true)) .on("mouseout", hovered(false)); cell.append("rect") .attr("id", function(d) { return "rect-" + d.id; }) .attr("width", function(d) { return d.x1 - d.x0; }) .attr("height", function(d) { return d.y1 - d.y0; }) .attr("fill", function(d) { return color[d.depth]; }) .attr("class",function(d){ if (d.depth < 2) return ; return "cell " + d.data["タイプ"] }) .call(bindTooltip) ; total = d3.selectAll(".cell").nodes().length; var count = fillCeckedCell(); output(count, total); cell.append("clipPath") .attr("id", function(d) { return "clip-" + d.id; }) .append("use") .attr("xlink:href", function(d) { return "#rect-" + d.id + ""; }); var label = cell.append("text") .attr("clip-path", function(d) { return "url(#clip-" + d.id + ")"; }); label .filter(function(d) { return d.children; }) .selectAll("tspan") .data(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); }) .enter().append("tspan") .attr("x", function(d, i) { return i ? null : 4; }) .attr("y", 13) .attr("fill", function(d){ return (d !="root") ? "black" : "white"; }) .text(function(d) { return (d !="root") ? d : "邦画10億円以上作品 2007-2016" ; }); label .filter(function(d) { return !d.children; }) .selectAll("tspan") .data(function(d) { return d.id.substring(d.id.lastIndexOf(".") + 1).split(/(?=[A-Z][^A-Z])/g); }) .enter().append("tspan") .attr("x", 4) .attr("y", function(d, i) { return 13 + i * 10; }) .text(function(id) {var data = nested.get(id); return data["タイトル"]; }); }); function hovered(hover) { return function(d) { d3.selectAll(d.ancestors().map(function(d) { return d.node; })) .classed("node--hover", hover) .select("rect") .attr("width", function(d) { return d.x1 - d.x0 - hover; }) .attr("height", function(d) { return d.y1 - d.y0 - hover; }); }; } var tooltip = d3.select("body") .append("div") .attr("class", "tooltip") .style("visibility", "hidden"); function bindTooltip(selector) { selector.on("mouseover", function(d) { if (!d.data["タイトル"]) return ; d3.select(this).classed("selected", true); tooltip.style("visibility", "visible"); }) .on("mouseout", function(d) { selector.classed("selected", false); tooltip.style("visibility", "hidden"); }) .on("mousemove", function(d){ var data = d.data; var content = [ '<div class="tooltip_container">', '<h4>', data['タイトル'], '</h4>', '<h5>興収:', data['興収(単位:億円)'], '億円</h5>', "</div>"].join(""); tooltip .style("top", (d3.event.pageY-100)+"px") .style("left",(d3.event.pageX-100)+"px") .html(content); }); } d3.select("#form").on("change", function(){ d3.selectAll(".cell").attr("fill", "#fff"); var count = fillCeckedCell(); output(count, total); }); function output(count, total) { d3.select("#info").html('<span class="count">'+count + '</span><span class="unit">作品</span>/<span class="total">' + total + '</span> <span class="persent">' +format((count/total)*100)+'</span><span class="unit">%</span>') } function fillCeckedCell() { var checked = d3.select("#form").selectAll("input:checked"); var count = 0; checked.each(function(){ var selector = d3.selectAll("."+this.value).attr("fill", this.dataset.color); count += selector.nodes().length; }); return count; } </script>
https://d3js.org/d3.v4.0.0-alpha.35.min.js