寻找更好的方法来改变 d3.js v4 中轴组件的颜色

问题描述 投票:0回答:6

我想更改简单 d3.js (v4) 图表的轴颜色。下图中的y轴是成品示例;

enter image description here

我怀疑我用来实现这一点的方法有点难看,我相信根据下面的描述应该有一个我还不明白的替代方案。

axis 组件是文本、路径和线条元素的组合,需要更改各自的样式(描边和填充)。

此时,我发现更改组件颜色的唯一方法是在代码的

<style>
部分中单独设置样式...

.axisRed line{
  stroke: red;
}

.axisRed path{
  stroke: red;
}

.axisRed text{
  fill: red;
}

...并在稍后将其附加到 JavaScript 中时将该类应用到 y 轴;

  svg.append("g")
      .attr("class", "axisRed")
      .call(d3.axisLeft(y));

有没有一种方法可以让我通过

.style("<some style>", "<some value>")
行应用这些样式,同时附加 y 轴,而不是在
<style>
部分中声明?

代码示例是here

我尝试过尝试处理单个 DOM 组件,例如“domain”类,但没有成功。我怀疑我对轴组件的层次结构了解不够。

d3.js
6个回答
18
投票

在 D3 中,您有多种选项来设置元素的样式:

选项A:使用带有自分配类的样式标签:

<style>
.axisRed line,
.axisRed path {
  stroke: red;
}
.axisRed text
{
  fill: red;
}
</style>

// assign that class to the y axis
svg.append("g")
  .attr("class", "axisRed")
  .call(d3.axisLeft(y));

选项 B:使用样式标签与 D3 自动生成的类:

轴线是一个具有

<path>
类的
domain
元素。刻度位于具有刻度类的组
<g>
内,由用于刻度线的
<line>
元素和用于刻度标签的
<text>
元素组成:

<style>
path.domain,
.tick line {
  stroke: red;
}
.tick text {
  fill: red;
}
</style>

svg.append("g").call(d3.axisLeft(y));

// HTML code generated by D3 (example):
<path class="domain" stroke="currentColor" d="M-6,450.5H0.5V0.5H-6"></path>
<g class="tick" opacity="1" transform="translate(0,414)">
  <line stroke="currentColor" x2="-6" y1="0.5" y2="0.5"></line>
  <text fill="currentColor" x="-9" y="0.5" dy=".32em">50</text>
</g>

选项 C:在附加时内联

D3 V3中你可以做得更紧凑:

svg.append("line")
   .style({
      fill: "none",
      stroke: "#f00",
      "stroke-width": "10"
    });

但是在D3 V4中,它不再起作用了。所以我打开了一个“问题”:您可以在此处检查并跟踪进度:https://github.com/d3/d3-selection/issues/82

** 更新 ** 在 V4 中,您必须包含选择多重:

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v0.4.min.js"></script>

然后使用:

styles
代替
style
attrs
代替
attr

svg.append("line")
   .styles({
      fill:"none",
      stroke:"#f00",
      "stroke-width":"10"
    })

举个例子:

svg.selectAll(".domain")
   .styles({ fill:"none", stroke:"#f00",  "stroke-width":"1" });

现在您可以通过一种紧凑的方式来设计元素的样式。

额外:您可以设置任何元素的样式和属性:

 var svg = d3.select("body").append("svg")
        .attrs({width:600, height:600})
        .styles({
            border:"1px",
            "border-style":"solid",
            "border-color":"#f00"})

这是笨蛋


15
投票

要设置内联样式,只需保留对添加的轴的引用并选择组件即可:

  // Add the Y Axis
  var axis = svg.append("g")
    .call(d3.axisLeft(y));

  axis.selectAll("line")
    .style("stroke", "purple");

  axis.selectAll("path")
    .style("stroke", "green");

  axis.selectAll("text")
    .style("stroke", "blue");

完整示例:

<!DOCTYPE html>
<meta charset="utf-8">

<body>

  <!-- load the d3.js library -->
  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script>
    // set the dimensions and margins of the graph
    var margin = {
        top: 20,
        right: 20,
        bottom: 30,
        left: 50
      },
      width = 960 - margin.left - margin.right,
      height = 500 - margin.top - margin.bottom;

    // parse the date / time
    var parseTime = d3.timeParse("%d-%b-%y");

    // set the ranges
    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);

    // define the line
    var valueline = d3.line()
      .x(function(d) {
        return x(d.date);
      })
      .y(function(d) {
        return y(d.close);
      });

    // append the svg obgect to the body of the page
    // appends a 'group' element to 'svg'
    // moves the 'group' element to the top left margin
    var svg = d3.select("body").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 + ")");

    var data = [{
      "date": "1-May-12",
      "close": "58.13"
    }, {
      "date": "30-Apr-12",
      "close": "53.98"
    }, {
      "date": "27-Apr-12",
      "close": "67.00"
    }, {
      "date": "26-Apr-12",
      "close": "89.70"
    }, {
      "date": "25-Apr-12",
      "close": "99.00"
    }, {
      "date": "24-Apr-12",
      "close": "130.28"
    }, {
      "date": "23-Apr-12",
      "close": "166.70"
    }, {
      "date": "20-Apr-12",
      "close": "234.98"
    }, {
      "date": "19-Apr-12",
      "close": "345.44"
    }, {
      "date": "18-Apr-12",
      "close": "443.34"
    }, {
      "date": "17-Apr-12",
      "close": "543.70"
    }, {
      "date": "16-Apr-12",
      "close": "580.13"
    }, {
      "date": "13-Apr-12",
      "close": "605.23"
    }, {
      "date": "12-Apr-12",
      "close": "622.77"
    }, {
      "date": "11-Apr-12",
      "close": "626.20"
    }, {
      "date": "10-Apr-12",
      "close": "628.44"
    }, {
      "date": "9-Apr-12",
      "close": "636.23"
    }, {
      "date": "5-Apr-12",
      "close": "633.68"
    }, {
      "date": "4-Apr-12",
      "close": "624.31"
    }, {
      "date": "3-Apr-12",
      "close": "629.32"
    }, {
      "date": "2-Apr-12",
      "close": "618.63"
    }, {
      "date": "30-Mar-12",
      "close": "599.55"
    }, {
      "date": "29-Mar-12",
      "close": "609.86"
    }, {
      "date": "28-Mar-12",
      "close": "617.62"
    }, {
      "date": "27-Mar-12",
      "close": "614.48"
    }, {
      "date": "26-Mar-12",
      "close": "606.98"
    }];

    // format the data
    data.forEach(function(d) {
      d.date = parseTime(d.date);
      d.close = +d.close;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function(d) {
      return d.date;
    }));
    y.domain([0, d3.max(data, function(d) {
      return d.close;
    })]);

    // Add the valueline path.
    svg.append("path")
      .data([data])
      .attr("class", "line")
      .attr("d", valueline)
      .style("fill", "none")
      .style("stroke", "steelblue");

    // Add the X Axis
    svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x));

    // Add the Y Axis
    var axis = svg.append("g")
      .call(d3.axisLeft(y));

    axis.selectAll("line")
      .style("stroke", "purple")

    axis.selectAll("path")
      .style("stroke", "green")

    axis.selectAll("text")
      .style("stroke", "blue")
  </script>
</body>


3
投票

对于 v5,您可以使用以下代码,选择域并定义您需要的轴的笔画并附加到 svg。

 yAxis = (g) =>
          g
            .attr("transform", `translate(${50} ${0})`)
            .call((g) =>
              g
                .selectAll(".domain")
                .attr("stroke-width", 0.3)
                .attr("stroke", d3.schemePaired[7])
            );

  svg.append("g").call(yAxis);
      

2
投票

如果您将 D3.js V5 与 DC.js 一起使用,则使用以下代码:

chart.on('pretransition', (chart) => {
    const svg = chart.select('svg');
    svg.selectAll("line").style("stroke", "purple");
    svg.selectAll("path").style("stroke", "green");
    svg.selectAll("text").style("stroke", "blue");
});

0
投票

如果您不想使用样式标签,像这样的事情怎么样:

 svg.append("g")
      .attr("class", "axisRed") // don't need this anymore but just re-suing your code
      .call(d3.axisLeft(y))
      .select("path")
      .attr("stroke","red")

0
投票

聚会有点晚了,但(至少在

[email protected]
中),轴、刻度线和刻度线的
stroke
设置为
currentColor
。这意味着您可以将包装
color
元素上的
g
设置为您喜欢的任何颜色,并且轴、刻度线和刻度线将继承该颜色。

例如

  svg.append("g")
      .style("color", "red")
      .call(d3.axisLeft(y))
© www.soinside.com 2019 - 2024. All rights reserved.