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

时间:2016-07-16 19:40:05

标签: d3.js

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

enter image description here

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

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

此时我发现改变组件颜色的唯一方法是在代码的<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));

有没有办法可以在追加y轴而不是在.style("<some style>", "<some value>")部分声明时通过<style>行应用这些样式?

代码示例为here

我试图尝试解决各个DOM组件,例如&#39;域&#39;上课,但没有成功。我怀疑我不太了解轴组件的层次结构。

5 个答案:

答案 0 :(得分:7)

在D3上你有几个选项来设置元素的样式:

选项A :在您的班级中使用样式标记:

axisRed line{
  stroke: red;
}

.axisRed path{
  stroke: red;
}

.axisRed text{
  fill: red;
}
// apply applying that class to the y
 svg.append("g")
      .attr("class", "axisRed")
      .call(d3.axisLeft(y));

选项B :将样式标记与自动生成类一起使用:

D3为轴线分配domain类,并在组内&#39; g&#39;对于每个tick类tick行和text。没有定义特定的类:

<style>
    path.domain  {
    stroke: red;
}
   .tick text {
    fill:blue
}
</style
.
.
 svg.append("g").call(d3.axisLeft(y));

// generate code 
<path class="domain" stroke="#000" d="M-6,450.5H0.5V0.5H-6"></path>
<g class="tick" opacity="1" transform="translate(0,414)">
      <line stroke="#000" x2="-6" y1="0.5" y2="0.5"></line>
      <text fill="#000" 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 上,不起作用。所以我打开一个问题&#39;:你可以在这里查看并关注进度:https://github.com/d3/d3-selection/issues/82

** 更新 ** 在V4上,您必须包含selection-multi:

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

然后使用:styles intead styleattrs代替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"})

Here's the plunker

答案 1 :(得分:5)

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

  // 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>

答案 2 :(得分:1)

如果您将 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");
});

答案 3 :(得分: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")

答案 4 :(得分:0)

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