首页 > 解决方案 > D3JS - 在 setinterval 刷新时更改颜色(又名粗糙)

问题描述

希望有人可以在这里提供帮助。

我有几个使用 setinterval 刷新 500 毫秒的图表。刷新时,它会从 Python 脚本创建的 JSON 文件中加载数据。我希望能够根据这些值对图表中的数据进行 RAG(红色、琥珀色、绿色)。

示例:如果数字小于 10,则将其设为绿色。如果在 10 到 20 之间,则为琥珀色,如果高于 20,则为红色。

我以 Mike 的子弹图为例:https ://bl.ocks.org/mbostock/4061961

在我的 CSS 中,我添加了颜色 - s0 和 s1 出现在他的示例中:

.bullet .measure.s0 { fill: lightsteelblue; }
.bullet .measure.s1 { fill: steelblue; }
.bullet .measure.s2 { fill: rgb(242, 242, 242); }
.bullet .measure.s3 { fill: #DF4A5E; }
.bullet .measure.s4 { fill: rgb(242, 242, 242); }
.bullet .measure.s5 { fill: #FBAB4A; }
.bullet .measure.s6 { fill: rgb(242, 242, 242); }
.bullet .measure.s7 { fill: #24C678; }

在 bullet.js 中,我可以根据数据的值调用一个函数,这将选择正确的 CSS 类(此处为第 5-13 行):

            var measure = g.selectAll("rect.measure")
                .data(measurez);

            measure.enter().append("rect")
                .attr("class", function (d, i) {
                    if (d > 20) {
                        return "measure s" + (i + 2);
                    } else if (d > 10) {
                        return "measure s" + (i + 4);
                    } else {
                        return "measure s" + (i + 6);
                    }
                })
                .attr("width", w0)
                .attr("height", height / 2)
                .attr("x", reverse ? x0 : 0)
                .attr("y", height / 4)
                .transition()
                .duration(duration)
                .attr("width", w1)
                .attr("x", reverse ? x1 : 0);

            measure.transition()
                .duration(duration)
                .attr("width", w1)
                .attr("height", height / 2)
                .attr("x", reverse ? x1 : 0)
                .attr("y", height / 4);

这完美地工作,当我刷新页面时,颜色会根据 JSON 中的值正确更改,但是在我的间隔刷新时它不会更新。

我的刷新如下:

setInterval(function () {
    updateData();
}, 500);

function updateData() {
  d3.json("mailboxes.json", function (error, data) {
    d3.select("body")
      .selectAll("svg")
      .select('g')
      .data(data)
      .call(chart.duration(500));
   });
};

这会刷新数据,但显然不会重绘矩形。

我已经尝试为度量添加一个选择器,然后更改类,但这并不可悲。(我也尝试过 SelectAll("svg") 然后 select('rect.measure') 以及我能想到的任何组合。

function updateData() {
  d3.json("mailboxes.json", function (error, data) {
    d3.select("body")
      .selectAll("svg")
      .select('g')
      .data(data)
      .call(chart.duration(500));

    d3.select("body")
      .selectAll("rect.measure")
      .data(data)
      .attr("class", function (d, i) {
        if (d > 20) {
          return "measure s" + (i + 2);
        } else if (d > 10) {
          return "measure s" + (i + 4);
        } else {
          return "measure s" + (i + 6);
        }
  });
};

这是一个示例,当支持 JSON 的值低于 10 时加载页面,因此为绿色。该值已增加到 10 以上,现在应该是琥珀色。

页面刷新前的绿色项目符号

当我刷新页面时,它按预期工作

页面刷新后的琥珀色项目符号

我可能只需要像下面这样的刷新中的重绘功能,但我尝试了一些东西,但没有任何效果

redraw()

function redraw(
  measures.blah
)

标签: javascriptcssjsond3.js

解决方案


您必须更改更新课程的位置。

在 之前做transition(),否则类字符串将被插值,你会得到一个黑色rect

        measure.enter().append("rect")
            .attr("width", w0)
            .attr("height", height / 2)
            .attr("x", reverse ? x0 : 0)
            .attr("y", height / 4)
            .transition()
            .duration(duration)
            .attr("width", w1)
            .attr("x", reverse ? x1 : 0);

        measure
            .attr("class", function (d, i) {
                if (d > 20) { return "measure s" + (i + 2); }
                if (d > 10) { return "measure s" + (i + 4); }
                return "measure s" + (i + 6);
            })
            .transition()
            .duration(duration)
            .attr("width", w1)
            .attr("height", height / 2)
            .attr("x", reverse ? x1 : 0)
            .attr("y", height / 4);

推荐阅读