d3v4-堆叠的条形图转换和动画修复

时间:2020-05-31 10:41:56

标签: javascript d3.js

enter image description here

我有这些带有堆叠条形图的旧代码示例。最好清理代码并将其从d3版本3升级到4。我认为可以改善图表本身的动画效果-也许是数据结构,如果这是将其引入图表的最佳方法。我认为当条形图向上运动时,文本标签会向下运动-有点奇怪吗?

  var initialHeight = 0;

  var barholder = d3.select(selector + " .barholder");

  //_morph stacks  
  var stacks = barholder.selectAll(".stack")
    .data(data);

  // Enter
  stacks.enter()
    .append("g")
    .attr("class", "stack")
    .attr("x", function(d) {
      return methods.x(d.Label);
    })
    .attr("transform", function(d) {
      return "translate(" + methods.x(d.Label) + ",0)";
    });

  // Update
  stacks
    .attr("x", function(d) {
      return methods.x(d.Label);
    })
    .transition()
    .duration(500)
    .attr("x", function(d) {
      return methods.x(d.Label);
    })
    .attr("transform", function(d) {
      return "translate(" + methods.x(d.Label) + ",0)";
    });

  // Exit
  stacks.exit()
    .transition()
    .duration(250)
    .attr("x", function(d) {
      return methods.x(d.Label);
    })
    .remove();
  //_morph stacks  


  //_morph bars       


  var bar = stacks.selectAll("rect")
    .data(function(d) {
      return d.blocks;
    });

  // Enter
  bar.enter()
    .append("rect")
    .attr("class", "bar")
    .attr("y", function(d) {
      return methods.y(d.y1);
    })
    .attr("width", methods.x.rangeBand())
    .style("fill", function(d) {
      return methods.color(d.name);
    });

  // Update
  bar
    .attr("y", methods.height)
    .attr("height", initialHeight)
    .attr("width", methods.x.rangeBand())
    .transition()
    .duration(500)
    .attr("x", function(d) {
      return methods.x(d.Label);
    })
    .attr("width", methods.x.rangeBand())
    .attr("y", function(d) {
      return methods.y(d.y1);
    })
    .attr("height", function(d) {
      return methods.y(d.y0) - methods.y(d.y1);
    })

  // Exit
  bar.exit()
    .transition()
    .duration(250)
    .attr("y", function(d) {
      return methods.y(d.y1);
    })
    .attr("height", function(d) {
      methods.y(d.y0) - methods.y(d.y1);
    })
    .remove();


  //__morph bars

//堆积图1版本3 https://jsfiddle.net/4x6thm08/1/

//堆积图2版本3 https://jsfiddle.net/msh14f5d/2/

所以我试图清理代码库

//堆叠图表-版本4-正在进行中 我从这个jsfiddle开始清理基本结构 https://jsfiddle.net/vdwhkLs8/1/

我正在得到范围限制而不是函数错误。


完整的代码

<!DOCTYPE html>
<html>
    <head>
        <title>StackedChart I</title>

        <!--libs-->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="https://d3js.org/d3.v4.min.js"></script>

        <!--js-->
        <script>

            $(document).ready(function() {


                var $this = $('.stackedchart');

                var data = [{
                    "Pizza": 3,
                    "Pancakes": 0.001,
                    "label": "Bombay, India"
                  },
                  {
                    "Pizza": 32,
                    "Pancakes": 20,
                    "label": "Dallas, United States"
                  },
                  {
                    "Pizza": 33,
                    "Pancakes": 330,
                    "label": "Detroit, United States"
                  }
                ];

                var width = $this.data('width'),
                    height = $this.data('height');

                var color = d3.scaleOrdinal()
                    .range(["#eb6383", "#fa9191", "#ffe9c5", "#b4f2e1"]);

                data.forEach(function(d) {
                    d.total = +d.value;
                });

                var margin = {top: 20, right: 5, bottom: 30, left: 20},
                    width = width - margin.left - margin.right,
                    height = height - margin.top - margin.bottom;

                var x = d3.scaleBand()
                          .range([0, width])
                          .padding(0.1);
                var y = d3.scaleLinear()
                          .range([height, 0]);

                x.domain(data.map(function(d) { return d.label; }));
                y.domain([0, d3.max(data, function(d) { return d.total; })]);





                var svg = d3.select($this[0])
                    .append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr('class', 'stackedchart')
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

                var stacked = svg.append('g').attr('class', 'stacked');

                /*
                bars.selectAll(".bar")
                    .data(data)
                    .enter().append("rect")
                    .attr("class", "bar")
                    .attr('fill', function(d, i) {
                        return color(i);
                    })
                    .attr("x", function(d) { return x(d.label); })
                    .attr("width", x.bandwidth())
                    .attr("y", function(d) { return y(d.value); })
                    .attr("height", function(d) { return height - y(d.total); });

                bars.append("g")
                    .attr("transform", "translate(0," + height + ")")
                    .call(d3.axisBottom(x));

                bars.append("g")
                    .call(d3.axisLeft(y));*/


                //var data = data.slice(0);

                color.domain(d3.keys(data[0]).filter(function(key) { return key !== "label"; }));

                data.forEach(function(d) {

                    var y0 = 0;

                    d.blocks = color.domain().map(function(name) {
                        var val = d[name];

                        if(isNaN(val)){
                            val = 0;
                        }

                        return {name: name, values: val, y0: y0, y1: y0 += +val};
                    });

                    d.total = d.blocks[d.blocks.length - 1].y1;
                });







                //_morph stacks  
                var stacks = stacked.selectAll(".stack")
                  .data(data);

                    // Enter
                    stacks.enter()
                        .append("g")
                        .attr("class", "stack")
                        .attr("x", function(d) { return x(d.label);})
                        .attr("transform", function(d) { 
                            return "translate(" + x(d.label) + ",0)";
                        });

                    // Update
                    stacks
                        .attr("x", function(d) { return x(d.label);})
                        .transition()
                        .duration(500)
                        .attr("x", function(d) { return x(d.label); })
                        .attr("transform", function(d) { 
                                return "translate(" + x(d.label) + ",0)";
                        });

                    // Exit
                    stacks.exit()
                        .transition()
                        .duration(250)
                        .attr("x", function(d) { return x(d.label);})
                        .remove();
                //_morph stacks  




                    var blockData = data.map(d => d.blocks);
                    console.log("blockData", blockData)

                var initialHeight = 0;
$.each(blockData, function( index, value ) {

                var bar = stacked.selectAll(".bar")
                    .data(value);


                    // array1.map(x => x * 2)

                // Enter
                bar.enter()
                    .append("rect")
                    .attr("class", "bar")
                    .attr("y", function(d) { 
                        console.log("y(d['y1'])", y(d['y1']))

                        return 23//y(d['y1']); 
                    })
                    .attr("width", x.bandwidth())
                    .style("fill", function(d) { 
                        console.log("d", d)

                        return "blue";

                        //return color(d.name); 
                    });



                bar
                    .attr("y", height)
                    .attr("height", 40)//.attr("height", initialHeight)
                    .attr("width", x.bandwidth())
                    .transition()
                    .duration(500)
                    .attr("x", function(d) { return x(d.label); })
                    .attr("width", x.bandwidth())
                    .attr("y", function(d) { 

                        return 60;
                        //return y(d['y1']); 
                    })
                    //.attr("height", function(d) { return y(d.y0) - y(d.y1); })


/*
                // Exit
                bar.exit()
                    .transition()
                    .duration(250)
                    .attr("y", function(d) { return methods.y(d.y1); })
                    //.attr("height", function(d) { methods.y(d.y0) - methods.y(d.y1); })
                    .remove();

*/



});





/*              
                // Update
                bar
                    .attr("y", height)
                    .attr("height", initialHeight)
                    .attr("width", x.bandwidth())
                    .transition()
                    .duration(500)
                    .attr("x", function(d) { return x(d.label); })
                    .attr("width", x.bandwidth())
                    .attr("y", function(d) { return y(d.y1); })
                    .attr("height", function(d) { return y(d.y0) - y(d.y1); })

                // Exit
                bar.exit()
                    .transition()
                    .duration(250)
                    .attr("y", function(d) { return y(d.y1); })
                    .attr("height", function(d) { y(d.y0) - y(d.y1); })
                    .remove();

*/



            });

        </script>
        <!--js-->

        <!--css-->
        <style>
            body {
                background: #ffd;
            }
        </style>
        <!--css-->
    </head>
    <body>

        <h1>StackedChart I</h1>
        <!--html-->
        <div
            class="stackedchart"
            data-width="300"
            data-height="300"
        />
        <!--html-->

    </body>
</html>

我获取初始数据-并循环遍历以计算不同的块-在这里我将label属性排除为彩色条。

            data.forEach(function(d) {

                var y0 = 0;

                d.blocks = color.domain().map(function(name) {
                    var val = d[name];

                    if(isNaN(val)){
                        val = 0;
                    }

                    return {name: name, values: val, y0: y0, y1: y0 += +val};
                });

                d.total = d.blocks[d.blocks.length - 1].y1;
            });

---虽然会发生故障-在我制作了堆栈g元素并尝试将条形图嵌套在堆栈占位符之后-由于某种原因,域数据无法正常工作?像y(d.y1)变成NAN。

                //_morph stacks  
                var stacks = stacked.selectAll(".stack")
                  .data(data);

                    // Enter
                    stacks.enter()
                        .append("g")
                        .attr("class", "stack")
                        .attr("x", function(d) { return x(d.label);})
                        .attr("transform", function(d) { 
                            return "translate(" + x(d.label) + ",0)";
                        });

                    // Update
                    stacks
                        .attr("x", function(d) { return x(d.label);})
                        .transition()
                        .duration(500)
                        .attr("x", function(d) { return x(d.label); })
                        .attr("transform", function(d) { 
                                return "translate(" + x(d.label) + ",0)";
                        });

                    // Exit
                    stacks.exit()
                        .transition()
                        .duration(250)
                        .attr("x", function(d) { return x(d.label);})
                        .remove();
                //_morph stacks  




                    var blockData = data.map(d => d.blocks);
                    console.log("blockData", blockData)

                var initialHeight = 0;
$.each(blockData, function( index, value ) {

                var bar = stacked.selectAll(".bar")
                    .data(value);


                    // array1.map(x => x * 2)

                // Enter
                bar.enter()
                    .append("rect")
                    .attr("class", "bar")
                    .attr("y", function(d) { 
                        console.log("y(d['y1'])", y(d['y1']))

                        return 23//y(d['y1']); 
                    })
                    .attr("width", x.bandwidth())
                    .style("fill", function(d) { 
                        console.log("d", d)

                        return "blue";

                        //return color(d.name); 
                    });



                bar
                    .attr("y", height)
                    .attr("height", 40)//.attr("height", initialHeight)
                    .attr("width", x.bandwidth())
                    .transition()
                    .duration(500)
                    .attr("x", function(d) { return x(d.label); })
                    .attr("width", x.bandwidth())
                    .attr("y", function(d) { 

                        return 60;
                        //return y(d['y1']); 
                    })
                    //.attr("height", function(d) { return y(d.y0) - y(d.y1); })


/*
                // Exit
                bar.exit()
                    .transition()
                    .duration(250)
                    .attr("y", function(d) { return methods.y(d.y1); })
                    //.attr("height", function(d) { methods.y(d.y0) - methods.y(d.y1); })
                    .remove();

*/



});

0 个答案:

没有答案