【问题标题】:How do I create the update function in D3JS如何在 D3JS 中创建更新函数
【发布时间】:2015-01-19 03:47:37
【问题描述】:

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

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() 替换 div 中的所有代码 exit( ) remove() 函数,但是在使用这些函数时,我收到一条错误消息,指出没有 exit() 函数,我是通过关注其他人发布的 here 和另一个 here 的帖子得到的,但无济于事。有什么想法吗?

【问题讨论】:

标签: javascript d3.js


【解决方案1】:

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

【讨论】:

  • 好的,所以这部分正确,现在我只需要知道如何修复它,它不是每次都重绘 div,而是每次都创建一个新的图形实例。所以我要说的是,每次单击不同的按钮时,svg 元素都会被复制而不是被替换?有什么想法吗?
  • 是的,假设您的图形位于 g 元素中,您将需要使用选择器来选择该元素,清除其中的所有内容(或至少清除图形),然后重绘该元素中的图形。
【解决方案2】:

实际上,我几乎从不链接.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()

当您追加或插入时,输入选择合并到更新选择中。

【讨论】:

  • 好的,我想我明白了,但不完全。但我也不确定我们是否在同一页上。我试图插入的数据是完全不同的数据。我正在做的是从 7 天视图切换到 30 天视图,再到三个月的月视图,以及六个月的月视图,所以我不仅要更新数据,还要重绘整个图表,我希望这有助于进一步解释这个问题,如果答案保持不变,我对 D3 的熟悉程度不如我想的那样,所以如果可能的话,请您详细说明一下?
  • 哦,这是我为之前询问的人创建的小提琴,也许它会帮助你理解我的问题,jsfiddle.net/926e7upb/8/embedded/result
【解决方案3】:

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

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

它就像一个魅力,像我想象的那样来回切换图表,现在我有更多关于条形图本身的任务,我可以继续另一个项目。

感谢大家的帮助,也许有一天我可以报答你!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 2022-08-16
    • 1970-01-01
    • 2018-10-15
    相关资源
    最近更新 更多