自适应D3甜甜圈图

时间:2018-09-18 15:29:56

标签: javascript d3.js

我正在使用甜甜圈图,以显示来自静态JSON查询的数据。我现在要使其响应。我使其他D3图具有响应性,但与此不同。

最初的想法是计算屏幕两个角之间的距离(斜边),以便重新计算形状的半径。这可能对以后有用。此计算的代码段如下所示:

console.log('width')
console.log(window.innerWidth);
console.log('height')
console.log(window.innerHeight);
console.log('final');
console.log(Math.sqrt(Math.pow(window.innerWidth,2) + Math.pow(window.innerHeight,2)));


$("#one").html(Math.sqrt(Math.pow(window.innerWidth,2) + Math.pow(window.innerHeight,2)));
<script src="https://code.jquery.com/jquery-1.9.1.js"></script>
<div id="one"></div>

 

我的主要代码段在这里,并且响应迅速,但是在甜甜圈下方显示了带有值(工具提示)的框。

var margin = {top: 20, right: 20, bottom: 50, left: 100},
    width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
    height = parseInt(d3.select("#chart").style("width")) - margin.top - margin.bottom,
    r = 180,
    inner = 180/2,
    color= d3.scale.ordinal()
    .range(["#124", "#214183", "#3061c2",  "#4876d1", "#87a5e1", "#c5d4f1"]);
    
data = [{"label":"ONE", "value":194}, 
        {"label":"TWO", "value":567}, 
        {"label":"THREE", "value":1314},
        {"label":"FOUR", "value":793},
        {"label":"FIVE", "value":1929},
        {"label":"SIX", "value":1383}];

var total = d3.sum(data, function(d) {
    return d3.sum(d3.values(d));
});

 
 var vis = d3.select('#chart').append("svg:svg").data([data])
         .attr("width", '100%')
         .attr("height", '100%')
         .attr('viewBox',(-width / 2 ) + ' ' + (-height/2) + ' '+width +' '+height)
         .attr('preserveAspectRatio','xMinYMin')


var textTop = vis.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .attr("class", "textTop")
    .text( "TOTAL" )
    .attr("y", -10),
textBottom = vis.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .attr("class", "textBottom")
    .text(total.toFixed(2) + "m")
    .attr("y", 10);

var arc = d3.svg.arc()
    .innerRadius(inner)
    .outerRadius(r);

var arcOver = d3.svg.arc()
    .innerRadius(inner + 5)
    .outerRadius(r + 5);
 
var pie = d3.layout.pie()
    .value(function(d) { return d.value; });
 
var arcs = vis.selectAll("g.slice")
    .data(pie)
    .enter()
        .append("svg:g")
            .attr("class", "slice")
            .on("mouseover", function(d) {
                d3.select(this).select("path").transition()
                    .duration(200)
                    .attr("d", arcOver)
                
                textTop.text(d3.select(this).datum().data.label)
                    .attr("y", -10);
                textBottom.text(d3.select(this).datum().data.value.toFixed(2))
                    .attr("y", 10);
            })
            .on("mouseout", function(d) {
                d3.select(this).select("path").transition()
                    .duration(100)
                    .attr("d", arc);
                
                textTop.text( "TOTAL" )
                    .attr("y", -10);
                textBottom.text(total.toFixed(2) + "m");
            });

arcs.append("svg:path")
    .attr("fill", function(d, i) { return color(i); } )
    .attr("d", arc);

var legend = d3.select("#chart").append("svg")
    .attr("class", "legend")
    .attr("width", r)
    .attr("height", r * 2)
    .selectAll("g")
    .data(data)
    .enter().append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", function(d, i) { return color(i); });

legend.append("text")
    .attr("x", 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .text(function(d) { return d.label; }); 
*{
  font-family: 'Roboto', sans-serif;
  text-transform:capitalize;
  margin: 0 auto;
  text-align:left;
}

body {
        font-family: "Roboto"!important;
        width: 100%;
        height: 400px;
        position: relative;
    }

 

.slice path {
    stroke: #fff;
    stroke-width: 1px;
}

.textTop {
    font-size: 12pt;
    fill: #bbb;
}

.textBottom {
    fill: #444;
    font-weight: bold;
    font-size: 18pt;
}

.top {
    border: 1px solid #bbb;
    color: #777;
    padding: 5px;
    text-decoration: none;
}

.top:hover {
    border: 1px solid #555;
    color: #333;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="chart"></div>

<svg id="chart2"></svg>

如何在甜甜圈的右侧添加工具提示(传说-不确定确切的术语)?

1 个答案:

答案 0 :(得分:1)

您可以通过以下方式将图例直接包含在主svg中:

var svg = d3.select('#chart').append("svg:svg");
var vis = svg.data([data])
(...)

而不是:

var vis = d3.select('#chart').append("svg:svg").data([data])
(...)

然后,您可以将图例添加到该svg中,替换为:

var legend = d3.select("#chart").append("svg")

使用:

var legend = svg.append("svg")

最后,您必须处理图例位置。这是一个有效的JSFiddle:https://jsfiddle.net/anh9Lr1e/4/和一个摘要,以防jsfiddle URL过期:

var margin = {top: 20, right: 20, bottom: 50, left: 100},
    width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
    height = parseInt(d3.select("#chart").style("width")) - margin.top - margin.bottom,
    r = 180,
    inner = 180/2,
    color= d3.scale.ordinal()
    .range(["#124", "#214183", "#3061c2",  "#4876d1", "#87a5e1", "#c5d4f1"]);
    
data = [{"label":"ONE", "value":194}, 
        {"label":"TWO", "value":567}, 
        {"label":"THREE", "value":1314},
        {"label":"FOUR", "value":793},
        {"label":"FIVE", "value":1929},
        {"label":"SIX", "value":1383}];

var total = d3.sum(data, function(d) {
    return d3.sum(d3.values(d));
});

 
 var svg = d3.select('#chart').append("svg:svg")
 			.attr("width", '100%')
        .attr("height", '100%')
        .attr('preserveAspectRatio','xMinYMin');
 var vis = svg.data([data])
         .attr("width", '100%')
         .attr("height", '100%')
         .attr('viewBox',(-width / 2 ) + ' ' + (-height/2) + ' '+width +' '+height)
         .attr('preserveAspectRatio','xMinYMin')


var textTop = vis.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .attr("class", "textTop")
    .text( "TOTAL" )
    .attr("y", -10),
textBottom = vis.append("text")
    .attr("dy", ".35em")
    .style("text-anchor", "middle")
    .attr("class", "textBottom")
    .text(total.toFixed(2) + "m")
    .attr("y", 10);

var arc = d3.svg.arc()
    .innerRadius(inner)
    .outerRadius(r);

var arcOver = d3.svg.arc()
    .innerRadius(inner + 5)
    .outerRadius(r + 5);
 
var pie = d3.layout.pie()
    .value(function(d) { return d.value; });
 
var arcs = vis.selectAll("g.slice")
    .data(pie)
    .enter()
        .append("svg:g")
            .attr("class", "slice")
            .on("mouseover", function(d) {
                d3.select(this).select("path").transition()
                    .duration(200)
                    .attr("d", arcOver)
                
                textTop.text(d3.select(this).datum().data.label)
                    .attr("y", -10);
                textBottom.text(d3.select(this).datum().data.value.toFixed(2))
                    .attr("y", 10);
            })
            .on("mouseout", function(d) {
                d3.select(this).select("path").transition()
                    .duration(100)
                    .attr("d", arc);
                
                textTop.text( "TOTAL" )
                    .attr("y", -10);
                textBottom.text(total.toFixed(2) + "m");
            });

arcs.append("svg:path")
    .attr("fill", function(d, i) { return color(i); } )
    .attr("d", arc);

var legend = svg.append("svg")
    .attr("class", "legend")
    //.attr("width", r)
    //.attr("height", r * 2)
    .selectAll("g")
    .data(data)
    .enter().append("g")
    .attr("transform", function(d, i) { return "translate(" + (r + 20) + "," + i * 20 + ")"; });

legend.append("rect")
    .attr("width", 18)
    .attr("height", 18)
    .style("fill", function(d, i) { return color(i); });

legend.append("text")
    .attr("x", 24)
    .attr("y", 9)
    .attr("dy", ".35em")
    .text(function(d) { return d.label; }); 
*{
  font-family: 'Roboto', sans-serif;
  text-transform:capitalize;
  margin: 0 auto;
  text-align:left;
}

body {
        font-family: "Roboto"!important;
        width: 100%;
        height: 400px;
        position: relative;
    }

 

.slice path {
    stroke: #fff;
    stroke-width: 1px;
}

.textTop {
    font-size: 12pt;
    fill: #bbb;
}

.textBottom {
    fill: #444;
    font-weight: bold;
    font-size: 18pt;
}

.top {
    border: 1px solid #bbb;
    color: #777;
    padding: 5px;
    text-decoration: none;
}

.top:hover {
    border: 1px solid #555;
    color: #333;
}
 
<script src="https://d3js.org/d3.v3.min.js"></script>
<div id="chart"></div>