D3条形图未重新渲染

时间:2019-10-18 15:02:19

标签: javascript d3.js

我已经创建了一个带有工具提示的堆叠式条形图,但是当从下拉按钮中选择一个新值时,数据不会重新呈现,而是建立在相同的前一个条形图上。如何以这样的方式修改图表:当选定的图表中的新下拉值随过渡(动画)而变化时。

<!DOCTYPE html>
<meta charset="utf-8">

<head>
</head>

<body>
<select id="queryYear" data-toggle="modal" data-target="#myModal" class="btn btn-danger ">
            <option value="2019" selected="selected">2019</option>
            <option value="2018">2018</option>
            <option value="2017">2017</option>
</select>

    <div id="charts" style="margin-left:45px;margin-top:20px">
        <h3>Payee Remmittance</h3>
        <svg width="1000" height="500"></svg>
    </div>
    <script src="https://code.jquery.com/jquery-latest.min.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
        function createChartLegend(mainDiv, group) {
            var z = d3.scaleOrdinal(d3.schemeCategory10);
            var mainDivName = mainDiv.substr(1, mainDiv.length);
            $(mainDiv).before("<div id='Legend_" + mainDivName + "' class='pmd-card-body' style='margin-top:0; margin-bottom:0;'></div>");
            var keys = group;
            keys.forEach(function(d) {
                var cloloCode = z(d);
                $("#Legend_" + mainDivName).append("<span class='team-graph team1' style='display: inline-block; margin-right:10px;'>\
                    <span style='background:" + cloloCode +
                    ";width: 10px;height: 10px;display: inline-block;vertical-align: middle;'>&nbsp;</span>\
                    <span style='padding-top: 0;font-family:Source Sans Pro, sans-serif;font-size: 13px;display: inline;'>" + d +
                    " </span>\
                </span>");
            });

        }
        var group = ["Not Paid", "Paid"];
        var parseDate = d3.timeFormat("%b-%Y");
        var mainDiv = "#charts";
        var mainDivName = "charts";
        createChartLegend(mainDiv, group);
        var salesData = [{
                'agency': 'Manufacturing',
                'Paid': 35,
                'Not Paid': 10
            }, {
                'agency': 'CONSTRUCTION ',
                'Paid': 82,
                'Not Paid': 1
            },
            {
                'agency': 'INSURANCE',
                'Paid': 7,
                'Not Paid': 81
            }, {
                'agency': 'OIL & GAS',
                'Paid': 50,
                'Not Paid': 13

                            }, {
                'agency': 'TRANSPORT',
                'Paid': 19,
                'Not Paid': 28
            }, {
                'agency': 'HEALTH CARE  ',
                'Paid': 17,
                'Not Paid': 23

                            }, {
                'agency': 'LEGAL SERVICES',
                'Paid': 27,
                'Not Paid': 8

                            },
            {
                'agency': 'INFORMATION & COMMUNICATION TECH ',
                'Paid': 21,
                'Not Paid': 2
                            }, {
                'agency': 'TELECOMMUNICATION',
                'Paid': 12,
                'Not Paid': 32
                            }, {
                'agency': 'EDUCATIONAL SERVICES ',
                'Paid': 47,
                'Not Paid': 48
                            }
        ];
        var salesData1 = [{
                'agency': 'Manufacturing',
                'Paid': 125,
                'Not Paid': 200
            }, {
                'agency': 'CONSTRUCTION ',
                'Paid': 182,
                'Not Paid': 11
            },
            {
                'agency': 'INSURANCE',
                'Paid': 171,
                'Not Paid': 181
            }, {
                'agency': 'OIL & GAS',
                'Paid': 150,
                'Not Paid': 113

                            }, {
                'agency': 'TRANSPORT',
                'Paid': 119,
                'Not Paid': 128
            }, {
                'agency': 'HEALTH CARE  ',
                'Paid': 117,
                'Not Paid': 123

                            }, {
                'agency': 'LEGAL SERVICES',
                'Paid': 127,
                'Not Paid': 18

                            },
            {
                'agency': 'INFORMATION & COMMUNICATION TECH ',
                'Paid': 121,
                'Not Paid': 12
                            }, {
                'agency': 'TELECOMMUNICATION',
                'Paid': 112,
                'Not Paid': 32
                            }, {
                'agency': 'EDUCATIONAL SERVICES ',
                'Paid': 147,
                'Not Paid': 48
                            }
        ];

         d3.select("#queryYear").on("change", function(d) {
      var v = d3.select(this).property('value');
      console.log(v)
      if (v == 2018) {
          console.log(salesData1)
        update(salesData1)
      }
      if (v == 2017) {
          console.log(salesData)
        update(salesData)
      }
      if (v == 2019) {

        update(salesData)
      }

    })


    function update(mda){
    mda.forEach(function(d) {
            d = type(d);
        });
        var layers = d3.stack()
            .keys(group)
            .offset(d3.stackOffsetDiverging)
            (mda)
            ;

        var svg = d3.select("svg"),
            margin = {
                top: 20,
                right: 30,
                bottom: 60,
                left: 120
            },
            width = +svg.attr("width"),
            height = +svg.attr("height");

        var t = d3.transition()
        .duration(4000);    


        var x = d3.scaleLinear()
            .rangeRound([margin.left, width - margin.right]);

        x.domain([d3.min(layers, stackMin), d3.max(layers, stackMax)]);

        var y = d3.scaleBand()
            .rangeRound([height - margin.bottom, margin.top])
            .padding(0.1);

        y.domain(mda.map(function(d) {
            return d.agency;
        }))

        function stackMin(layers) {
            return d3.min(layers, function(d) {
                return d[0];
            });
        }

        function stackMax(layers) {
            return d3.max(layers, function(d) {
                return d[1];
            });
        }

        var z = d3.scaleOrdinal(d3.schemeCategory10);

        var maing = svg.append("g")
            .selectAll("g")
            .data(layers)
            .remove();
        var g = maing.enter()
            .append("g")
            .attr("fill", function(d) {
                return z(d.key);
            });


        var rect = g.selectAll("rect")
            .data(function(d) {
                d.forEach(function(d1) {
                    d1.key = d.key;
                    return d1;
                });
                return d;
            })
            .enter().append("rect")
            .attr("data", function(d) {
                var data = {};
                data["key"] = d.key;
                data["value"] = d.data[d.key];
                var total = 0;
                group.map(function(d1) {
                    total = total + d.data[d1]
                });
                data["total"] = total;
                return JSON.stringify(data);
            })
            .attr("width", function(d) {
                return x(d[1]) - x(d[0]);
            })
            .attr("x", function(d) {
                return x(d[0]);
            })
            .attr("y", function(d) {
                return y(d.data.agency);
            })
            .attr("height", y.bandwidth);

        rect.on("mouseover", function() {
            var currentEl = d3.select(this);
            var fadeInSpeed = 120;
            d3.select("#recttooltip_" + mainDivName)
                .transition()
                .duration(fadeInSpeed)
                .style("opacity", function() {
                    return 1;
                });
            d3.select("#recttooltip_" + mainDivName).attr("transform", function(d) {
                var mouseCoords = d3.mouse(this.parentNode);
                var xCo = 0;
                if (mouseCoords[0] + 10 >= width * 0.80) {
                    xCo = mouseCoords[0] - parseFloat(d3.selectAll("#recttooltipRect_" + mainDivName)
                        .attr("width"));
                } else {
                    xCo = mouseCoords[0] + 10;
                }
                var x = xCo;
                var yCo = 0;
                if (mouseCoords[0] + 10 >= width * 0.80) {
                    yCo = mouseCoords[1] + 10;
                } else {
                    yCo = mouseCoords[1];
                }
                var x = xCo;
                var y = yCo;
                return "translate(" + x + "," + y + ")";
            });
            //CBT:calculate tooltips text
            var tooltipData = JSON.parse(currentEl.attr("data"));
            var tooltipsText = "";
            d3.selectAll("#recttooltipText_" + mainDivName).text("");
            var yPos = 0;
            d3.selectAll("#recttooltipText_" + mainDivName).append("tspan").attr("x", 0).attr("y", yPos * 10).attr("dy", "1.9em").text(tooltipData.key + ":  " + tooltipData.value);
            yPos = yPos + 1;
            d3.selectAll("#recttooltipText_" + mainDivName).append("tspan").attr("x", 0).attr("y", yPos * 10).attr("dy", "1.9em").text("Total" + ":  " + tooltipData.total);
            //CBT:calculate width of the text based on characters
            var dims = helpers.getDimensions("recttooltipText_" + mainDivName);
            d3.selectAll("#recttooltipText_" + mainDivName + " tspan")
                .attr("x", dims.w + 4);

            d3.selectAll("#recttooltipRect_" + mainDivName)
                .attr("width", dims.w + 10)
                .attr("height", dims.h + 20);

        });

        rect.on("mousemove", function() {
            var currentEl = d3.select(this);
            currentEl.attr("r", 7);
            d3.selectAll("#recttooltip_" + mainDivName)
                .attr("transform", function(d) {
                    var mouseCoords = d3.mouse(this.parentNode);
                    var xCo = 0;
                    if (mouseCoords[0] + 10 >= width * 0.80) {
                        xCo = mouseCoords[0] - parseFloat(d3.selectAll("#recttooltipRect_" + mainDivName)
                            .attr("width"));
                    } else {
                        xCo = mouseCoords[0] + 10;
                    }
                    var x = xCo;
                    var yCo = 0;
                    if (mouseCoords[0] + 10 >= width * 0.80) {
                        yCo = mouseCoords[1] + 10;
                    } else {
                        yCo = mouseCoords[1];
                    }
                    var x = xCo;
                    var y = yCo;
                    return "translate(" + x + "," + y + ")";
                });
        });
        rect.on("mouseout", function() {
            var currentEl = d3.select(this);
            d3.select("#recttooltip_" + mainDivName)
                .style("opacity", function() {
                    return 0;
                })
                .attr("transform", function(d, i) {
                    // klutzy, but it accounts for tooltip padding which could push it onscreen
                    var x = -500;
                    var y = -500;
                    return "translate(" + x + "," + y + ")";
                });
        });

        svg.append("g")
            .attr("transform", "translate(0," + (height - margin.bottom) + ")")
            .call(d3.axisBottom(x))
            .append("text")
            .attr("x", width / 2)
            .attr("y", margin.bottom * 0.5)
            .attr("dx", "0.32em")
            .attr("fill", "#000")
            .attr("font-weight", "bold")
            .attr("text-anchor", "start")
            .text("Count")
            .remove()
            .exit();

        var ele = svg.append("g")
            .attr("transform", "translate(" + margin.left + ",0)")
            .call(d3.axisLeft(y));
        ele.selectAll("text")
            .attr("transform", "rotate(-55)")
            .attr("dx", ".5em")
            .attr("dy", "-.9em");
        ele.append("text")
            .attr("transform", "rotate(-90)")
            .attr("x", 0 - (height / 2))
            .attr("y", 15 - (margin.left))
            .attr("dy", "0.32em")
            .attr("fill", "#000")
            .attr("font-weight", "bold")
            .attr("text-anchor", "middle")
            .text("Agency Name");

        var rectTooltipg = svg.append("g")
            .attr("font-family", "sans-serif")
            .attr("font-size", 10)
            .attr("text-anchor", "end")
            .attr("id", "recttooltip_" + mainDivName)
            .attr("style", "opacity:0")
            .attr("transform", "translate(-500,-500)");

        rectTooltipg.append("rect")
            .attr("id", "recttooltipRect_" + mainDivName)
            .attr("x", 0)
            .attr("width", 120)
            .attr("height", 80)
            .attr("opacity", 0.71)
            .style("fill", "#000000");

        rectTooltipg
            .append("text")
            .attr("id", "recttooltipText_" + mainDivName)
            .attr("x", 30)
            .attr("y", 15)
            .attr("fill", function() {
                return "#fff"
            })
            .style("font-size", function(d) {
                return 10;
            })
            .style("font-family", function(d) {
                return "arial";
            })
            .text(function(d, i) {
                return "";
            });


        function type(d) {
            d.agency = d.agency;
            group.forEach(function(c) {
                d[c] = +d[c];
            });
            return d;
        }

        var helpers = {
            getDimensions: function(id) {
                var el = document.getElementById(id);
                var w = 0,
                    h = 0;
                if (el) {
                    var dimensions = el.getBBox();
                    w = dimensions.width;
                    h = dimensions.height;
                } else {
                    console.log("error: getDimensions() " + id + " not found.");
                }
                return {
                    w: w,
                    h: h
                };
            }
        };
    }

    </script>

0 个答案:

没有答案