I want to change the colour of an axis for a simple d3.js (v4) graph. The y axis in the following image is an example of the finished product;
I suspect that the method I am using to achieve this a bit ugly and I believe that there should be an alternative per the description below that I do not yet understand.
The axis component is a combination of text, path and line elements which require alteration of their respective styles (stroke and fill).
At this point the only method I have found to change the colour of the components is by individually setting styles in the <style>
section of the code...
.axisRed line{
stroke: red;
}
.axisRed path{
stroke: red;
}
.axisRed text{
fill: red;
}
...and applying that class to the y axis when appending it later in the JavaScript;
svg.append("g")
.attr("class", "axisRed")
.call(d3.axisLeft(y));
Is there a way that I can apply these styles via .style("<some style>", "<some value>")
lines while appending the y axis rather than declaring in the <style>
section?
An example with code is here.
I have tried trying to address the individual DOM components such as the 'domain' class, but without success. I suspect that I do not understand the hierarchy of the axis component well enough.
In D3 you have several options to style the elements:
Option A: Using style tag with self-assigned class:
<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));
Option B: Using style tag with the classes auto-generated by D3:
The axis line is a <path>
element with class domain
. The ticks are inside a group <g>
with class tick, consisting of a <line>
element for the tick line and a <text>
element for the tick label:
<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>
Option C: Inline at appending time
In D3 V3 you could do a more compact:
svg.append("line")
.style({
fill: "none",
stroke: "#f00",
"stroke-width": "10"
});
But in D3 V4, it doesn't work anymore. So I opened an 'Issue': you can check and follow the progress here: https://github.com/d3/d3-selection/issues/82
** UPDATE ** In V4 you must include 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>
and then use: styles
instead of style
and attrs
instead attr
:
svg.append("line")
.styles({
fill:"none",
stroke:"#f00",
"stroke-width":"10"
})
for your example:
svg.selectAll(".domain")
.styles({ fill:"none", stroke:"#f00", "stroke-width":"1" });
Now you got a compact way to style your elements.
Extra: you could style and attr any element:
var svg = d3.select("body").append("svg")
.attrs({width:600, height:600})
.styles({
border:"1px",
"border-style":"solid",
"border-color":"#f00"})