代码之家  ›  专栏  ›  技术社区  ›  Datacrawler

响应D3甜甜圈图表屏幕调整大小

  •  1
  • Datacrawler  · 技术社区  · 6 年前

    是否可以快速使用调整大小功能来更改图例的半径、字体大小和矩形大小?如果它是一个条形图,调整大小的功能将非常简单。在这种情况下,我想知道是否值得在每个D3图表中创建一个基础。如果我用这个底座: http://jsfiddle.net/radomer/zc8akt40/ 我能改变代码使我的图形响应吗?我猜,如果是的话,我将不得不改变基本代码,因为我失去了悬停图的动画。

    //Calculate the diagonal of the parent sreen div
    
    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)));
    
    var diagonal = Math.sqrt(Math.pow(window.innerWidth,2) + Math.pow(window.innerHeight,2))/5;
    
    //Create the D3 chart
    
    var margin = {top: 20, right: 20, bottom: 50, left: 20},
        width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
        height = parseInt(d3.select("#chart").style("width")) - margin.top - margin.bottom,
        r = diagonal,
        inner = diagonal/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");
     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://code.jquery.com/jquery-1.9.1.js"></script>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    
    <div id="chart"></div>
    1 回复  |  直到 6 年前
        1
  •  2
  •   Sebastian Rothbucher    6 年前

    你可以用这个 viewBox 中的属性 svg 标记以创建独立于实际屏幕大小的坐标系,然后使用 style="width: x%; " img

    下面是它的样子:

    <svg id="scalesvg" viewBox="0 0 100 100">
    

    #scalesvg { width: 20%; }
    

    我现在有一个100x100的坐标系,我可以用0到100的绝对坐标来画图。浏览器仍将调整大小。

    不过,它也会调整字体大小,因此您可能会提出更改字体大小的媒体查询,并可能将文本向上/向下翻译几个像素,以真正创建一个良好的体验。

    http://www.sarasoueidan.com/blog/svg-coordinate-systems/

    https://codepen.io/sebredhh/pen/jvJGry