如何在 D3JS 中创建更新函数

How do I create the update function in D3JS

本文关键字:创建 更新 函数 D3JS      更新时间:2023-09-26

我正在尝试构建一个条形图,我可以根据特定的时间长度在显示的数据量之间切换。到目前为止,我拥有的代码是这样的,

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

var barGraph = function(json_data, type) {
if (type === 'month')
    var barData = monthToArray(json_data);
else 
    var barData = dateToArray(json_data);

    var y = d3.scale.linear().domain([ 0, Math.round(Math.max.apply(null,
            Object.keys(barData).map(function(e) {
                return barData[e]['Count']}))/100)*100 + 100]).range(
            [ height, 0 ]);
    var x = d3.scale.ordinal().rangeRoundBands([ 0, width ], .1)
            .domain(d3.entries(barData).map(function(d) {
                return barData[d.key].Date;
            }));
    var xAxis = d3.svg.axis().scale(x).orient("bottom");
    var yAxis = d3.svg.axis().scale(y).orient("left");
    var svg = d3.select("#chart").append("svg").attr("width",
            width + margin.left + margin.right).attr("height",
            height + margin.top + margin.bottom).append("g").attr(
            "transform",
            "translate(" + margin.left + "," + margin.top + ")");
    svg.append("g").attr("class", "x axis").attr("transform",
            "translate(0," + height + ")").call(xAxis);
    svg.append("g").attr("class", "y axis").call(yAxis).append(
            "text").attr("transform", "rotate(-90)").attr("y", 6)
            .attr("dy", ".71em").style("text-anchor", "end").text(
                    "Total Hits");
    svg.selectAll(".barComplete").data(d3.entries(barData)).enter()
            .append("rect").attr("class", "barComplete").attr("x",
                    function(d) {
                        return x(barData[d.key].Date)
                    }).attr("width", x.rangeBand() / 2).attr("y",
                    function(d) {
                        return y(barData[d.key].Count);
                    }).attr("height", function(d) {
                return height - y(barData[d.key].Count);
            }).style("fill", "orange");
    var bar = svg.selectAll(".barHits").data(d3.entries(barData))
            .enter().append("rect").attr("class", "barHits").attr(
                    "x", function(d) {
                        return x(barData[d.key].Date) + x.rangeBand() / 2
                    }).attr("width", x.rangeBand() / 2).attr("y",
                    function(d) {
                        return y(barData[d.key].Count);
                    }).attr("height", function(d) {
                return height - y(barData[d.key].Count);
            }).style("fill", "red");
};

这在显示我的原始数据集方面做得很好,我设置了一个按钮,可以在页面开头绘制的所有数据集之间切换。 所有数组都存在,但无论我多么努力,我都会不断将一个新图形附加到div,因此在单击按钮后,我有两个图形, 我尝试使用 enter() exit() remove() 函数替换div 中的所有代码,但在使用这些函数时,我收到一个错误,指出没有 exit() 函数,我通过关注其他人在这里发布的帖子和另一个帖子得到了这个,但无济于事。伙计们有什么想法吗?

您最有可能做的是绘制一个新图形,可能是每次单击按钮时都会使用新div,您可以尝试做的一件事是将图表容器元素保留在某处,当单击按钮时,您只需清除它的子项并重新绘制图形。

在实践中,我几乎从不.data().enter()

// This is the syntax I prefer:
var join  = svg.selectAll('rect').data(data)
var enter = join.enter()
/* For reference: */
// Selects all rects currently on the page
// @returns: selection
svg.selectAll('rect') 
// Same as above but overwrites data of existing elements
// @returns: update selection
svg.selectAll('rect').data(data) 
// Same as above, but now you can add rectangles not on the page
// @returns: enter selection
svg.selectAll('rect').data(data).enter()

同样重要的是:

# selection.enter()

追加或插入时,输入所选内容将合并到更新所选内容中。

好的,我想通了 所以我将首先将所有注意力引导到这里 我在哪里找到了我的答案。关键在于我绘制 svg 元素的方式,而不是用新图形替换它,我只是不断地绘制一个新图形并将其附加到 #chartdiv。我找到了我引导你们的答案,并在我现有的 barGraph 函数的开头添加了这一行。

d3.select("#barChart").select("svg").remove();

它就像一个魅力,像我想象的那样来回切换图表,现在我为条形图本身增加了一些任务,我可以继续另一个项目。

谢谢大家的帮助,也许有一天我可以回报这个人情!