D3JS-在setinterval刷新时更改颜色(又名ragging)

时间:2018-10-22 09:14:58

标签: javascript css json d3.js

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

我使用setinterval在500ms刷新上有几张图表。刷新时,它将从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”),然后选择('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);
        }
  });
};

这里是一个示例,其中当Support JSON的值小于10(因此为绿色)时,加载页面。此后该值增加到10以上,现在应该是琥珀色。

Green bullet before page refresh

刷新页面后,它会按预期工作

Amber bullet after page refresh

我可能只需要像下面这样的刷新中的重绘功能,但是我已经尝试了一些方法,但是没有任何作用

redraw()

function redraw(
  measures.blah
)

2 个答案:

答案 0 :(得分:0)

更改数据后,您似乎并没有绘制图表,因此整个d3更新,输入,退出模式都没有发生,您需要这样做。没错,您需要一个重绘函数,所以我建议创建一个包含主要d3代码的函数以绘制图表。首先调用它,然后在setInterval触发时调用它。可能类似于以下内容(不是有效的示例)。

<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="bullet.js"></script>
<script>

  var margin = { top: 5, right: 40, bottom: 20, left: 120 },
    width = 960 - margin.left - margin.right,
    height = 50 - margin.top - margin.bottom;

  var chart = d3.bullet()
    .width(width)
    .height(height);

//hardcoded data because of jsfiddle

var data = [{"title":"Support","subtitle":"Shared, OOH","ranges":[0],"measures":[12,15],"markers":[12,15]},{"title":"Escalations","subtitle":"Team Leaders","ranges":[0],"measures":[0,0],"markers":[0,0]}]

// load the json here
//  d3.json("mailboxes.json", function (error, data) {
//   if (error) throw error;

// Create a function to draw your chart.
function drawChart() {
    var svg = d3.select("body").selectAll("svg")
      .data(data)
      .enter().append("svg")
      .attr("class", "bullet")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
      .call(chart);

    var title = svg.append("g")
      .style("text-anchor", "end")
      .attr("transform", "translate(-6," + height / 2 + ")");

    title.append("text")
      .attr("class", "title")
      .text(function (d) { return d.title; });

    title.append("text")
      .attr("class", "subtitle")
      .attr("dy", "1em")
      .text(function (d) { return d.subtitle; });

    });
  }
  
  // Initially draw the chart.
  drawChart();

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

  function updateData() {
  // this is the refresh for the json
  // d3.json("mailboxes.json", function (error, data) {
  //    d3.select("body")
  //      .selectAll("svg")
  //      .select('g')
  //      .data(data)
  //      .call(chart.duration(500));
  
    // Get some new data and assign to your data var.

    // Draw your chart.
    drawChart();

    });

  };


</script>

答案 1 :(得分:0)

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

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);