javascript - d3 根据高度更改条形图颜色

标签 javascript html css d3.js charts

我创建了一个条形图,我可以通过鼠标拖动来扩展或减小每个条形的高度,它会根据拖动的值自动更改数据。我想改变颜色,当我扩展它的高度时,每个条形图都变得更红,当我降低它的高度时,每个条形图变得更绿。 我怎样才能实现它?

<!DOCTYPE html>
<html>
  <style>
    .selection {
      fill: steelblue;
      fill-opacity: 1;
    }

    body {
      width: 80%;
      margin: auto;
    }
  </style>
  <body >
    <script src="https://d3js.org/d3.v4.min.js"></script>

    <script>
      var data = [
        { index: 0, value: 18 },
        { index: 1, value: 20 },
        { index: 2, value: 19 },
      ];

      var widthY = 550,
        heightY = 600,
        delim = 4;

      var scaleY = d3.scaleLinear().domain([0, 21]).rangeRound([heightY, 0]);

      var x = d3.scaleLinear().domain([0, data.length]).rangeRound([0, widthY]);

      var svgY = d3
        .select("body")
        .append("svg")
        .attr("width", widthY)
        .attr("height", heightY)
        .attr("fill", "green")
        .append("g");

      var brushY = d3
        .brushY()
        .extent(function (d, i) {
          return [
            [x(i) + delim / 2, 0],
            [x(i) + x(1) - delim / 2, heightY],
          ];
        })
        .on("brush", brushmoveY)
        .on("end", brushendY);

      var svgbrushY = svgY
        .selectAll(".brush")
        .data(data)
        .enter()
        .append("g")
        .attr("class", "brush")
        .append("g")
        .call(brushY)
        .call(brushY.move, function (d) {
          return [d.value, 0].map(scaleY);
        });

      svgbrushY
        .append("text")
        .attr("y", function (d) {
          return scaleY(d.value) + 25;
        })
        .attr("x", function (d, i) {
          return x(i) + x(0.5);
        })
        .attr("dx", "-.60em")
        .attr("dy", -5)
        .style("fill", "white")
        .text(function (d) {
          return d3.format(".2")(d.value);
        });

      function brushendY() {
        if (!d3.event.sourceEvent) return;
        if (d3.event.sourceEvent.type === "brush") return;
        if (!d3.event.selection) {
          svgbrushY.call(brushY.move, function (d) {
            return [d.value, 0].map(scaleY);
          });
        }
      }

      function brushmoveY() {
        if (!d3.event.sourceEvent) return;
        if (d3.event.sourceEvent.type === "brush") return;
        if (!d3.event.selection) return;

        var d0 = d3.event.selection.map(scaleY.invert);
        var d = d3.select(this).select(".selection");

        d.datum().value = d0[0];

        update();
      }

      function update() {
        svgbrushY
          .call(brushY.move, function (d) {
            return [d.value, 0].map(scaleY);
          })
          .selectAll("text")
          .attr("y", function (d) {
            return scaleY(d.value) + 25;
          })
          .text(function (d) {
            return d3.format(".2")(d.value);
          });
      }
      
    </script>
  </body>
</html>

最佳答案

首先我们需要一个秤:

 var color = d3.scaleLinear().domain(scaleY.domain()).range(["lightgreen","crimson"])

现在我们需要在更新函数中更新拖动条的颜色:

 svgbrushY.selectAll(".selection").style("fill", function(d) { return color(d.value); })   

这几乎让我们一路走到了尽头 - 但最初的颜色并不正确。画笔的创建打破了 .selection 矩形的数据绑定(bind):如果你登录

svgbrushY.selectAll(".selection").each(function(d) { console.log(d); })

您会注意到数据在被拖动之前没有 value 属性。所以我们可以自己添加它,并像我们在更新功能期间一样设置栏的样式:

   svgbrushY.select(".selection")
     .datum(d=>d)
     .style("fill", function(d) { return color(d.value); })

这应该给我们类似的东西:

<!DOCTYPE html>
<html>
  <style>
    .selection {
      fill-opacity: 1;
    }

    body {
      width: 80%;
      margin: auto;
    }
  </style>
  <body >
    <script src="https://d3js.org/d3.v4.min.js"></script>

    <script>
      var data = [
        { index: 0, value: 18 },
        { index: 1, value: 20 },
        { index: 2, value: 19 },
      ];

      var widthY = 550,
        heightY = 200,
        delim = 4;

      var scaleY = d3.scaleLinear().domain([0, 21]).rangeRound([heightY, 0]);

      var x = d3.scaleLinear().domain([0, data.length]).rangeRound([0, widthY]);
      
      var color = d3.scaleLinear().domain(scaleY.domain()).range(["lightgreen","crimson"])

      var svgY = d3
        .select("body")
        .append("svg")
        .attr("width", widthY)
        .attr("height", heightY)
        .attr("fill", "green")
        .append("g");

      var brushY = d3
        .brushY()
        .extent(function (d, i) {
          return [
            [x(i) + delim / 2, 0],
            [x(i) + x(1) - delim / 2, heightY],
          ];
        })
        .on("brush", brushmoveY)
        .on("end", brushendY);

      var svgbrushY = svgY
        .selectAll(".brush")
        .data(data)
        .enter()
        .append("g")
        .attr("class", "brush")
        .append("g")
        .call(brushY)
        .call(brushY.move, function (d) {
          return [d.value, 0].map(scaleY);
        });
        
       svgbrushY.select(".selection")
         .datum(d=>d)
         .style("fill", function(d) { return color(d.value); })
        
       
       svgbrushY
        .append("text")
        .attr("y", function (d) {
          return scaleY(d.value) + 25;
        })
        .attr("x", function (d, i) {
          return x(i) + x(0.5);
        })
        .attr("dx", "-.60em")
        .attr("dy", -5)
        .style("fill", "white")
        .text(function (d) {
          return d3.format(".2")(d.value);
        });

      function brushendY() {
        if (!d3.event.sourceEvent) return;
        if (d3.event.sourceEvent.type === "brush") return;
        if (!d3.event.selection) {
          svgbrushY.call(brushY.move, function (d) {
            return [d.value, 0].map(scaleY);
          });
        }
      }

      function brushmoveY() {
        if (!d3.event.sourceEvent) return;
        if (d3.event.sourceEvent.type === "brush") return;
        if (!d3.event.selection) return;

        var d0 = d3.event.selection.map(scaleY.invert);
        var d = d3.select(this).select(".selection");

        d.datum().value = d0[0];

        update();
      }
      
   

      function update() {
        svgbrushY
          .call(brushY.move, function (d) {
            return [d.value, 0].map(scaleY);
          })
          .selectAll("text")
          .attr("y", function (d) {
            return scaleY(d.value) + 25;
          })
          .text(function (d) {
            return d3.format(".2")(d.value);
          });
   
           svgbrushY.selectAll(".selection").style("fill", function(d) { return color(d.value); })          
      }
      
    </script>
  </body>
</html>

(为片段 View 缩小)

关于javascript - d3 根据高度更改条形图颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72624100/

相关文章:

html - 在 CSS 中格式化 topnav

html - Bootstrap/CSS - 修复右浮动图像的跨浏览器边距不一致

javascript - HTML5 历史 API : cannot go backwards more than once

javascript - 如何淡入 jquery 中背景图像的背景位置更改?

javascript - 未添加完整日历资源额外参数

javascript - jQuery 单击事件影响同一类的所有标签

html - 隐藏光标不起作用 (CSS)

javascript - 如何获取 Iframe 的 documentElement

javascript - 如何在内联字段 Django 中添加属性?

javascript - 使用 Polymer 的 firebase-collection 更新 Firebase 数据