Apply multiple styles with .style() method in D3.js
Edit (2021):
Note: I claimed (in initial version of this answer) that there's no embedded method to solve the OP's problem. And, as of D3 v6.7.0 you still cannot pass your styles as an object directly to
.style()
method
Two options you got by the time of this writing:
- loop through your styles object and apply the styles incrementally
const style = {"width":"100px","height":"100px","background-color":"lightgreen"}
Object.entries(style).forEach(([prop,val]) => d3.select("#test").style(prop,val))
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script><div id="test"></div>
How to apply a CSS style sheet to a D3 force-directed graph?
Your code has 2 errors:
- Class is missing for the node elements. Fix it by:
const node = svg.selectAll(".node")
.data(json.nodes)
.enter()
.append("g")
.classed("node", true)
.call(force.drag);
- You cannot create a
<div>
under<g>
. You can append a<text>
:
node.append('rect')
.attr('x', -50)
.attr('y', -30)
.attr('width', 100)
.attr('height', 60)
.style('fill', 'blue');
node.append('text')
.classed('ui ...', true)
.text('NODE')
.attr('alignment-baseline', 'middle')
.attr('text-anchor', 'middle')
.style('fill', 'white');
... or insert a <div>
under a <foreignObject>
;
D3: adding style and class to DIV results in styles discarded
You just forget the "px":
var aWindow = d3.select(parent)
.append("div")
.attr("class",aClass)
// <div style="top:30px; left:40px; width:50px; height:50px;"></div>
.style("top",y + "px")
.style("left",x + "px")
.style("width",width + "px")
.style("height",height + "px");
Can selectAll() in d3 js take css style also as parameter?
d3.selectAll(selector)
Selects all elements that match the specified selector string. The elements will be selected in document order (top-to-bottom). If no elements in the document match the selector, or if the selector is null or undefined, returns an empty selection. For example, to select all paragraphs:
var paragraph = d3.selectAll("p");
1) In your example, .legend
is a class selector. It is being passed as an argument to selectAll
to match all DOM elements that have a class of legend
.
2) .legend
is not a CSS style itself. But it can be used in CSS as a selector to apply some style properties to the elements that match said selector.
3) selectAll
accepts only one argument: a selector string. That could simply be "p"
or it could be ".content .items > li"
.
Have a look below how we can use both CSS & D3 to apply different styles.
d3.selectAll(".highlight")
.style({
"color": "green"
})
nav a {
color: red
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<nav>
<ul>
<li><a href="#nowhere" title="Lorum ipsum dolor sit amet">Lorem</a></li>
<li><a href="#nowhere" title="Aliquam tincidunt mauris eu risus">Aliquam</a></li>
<li><a href="#nowhere" title="Morbi in sem quis dui placerat ornare" class="highlight">Morbi</a></li>
<li><a href="#nowhere" title="Praesent dapibus, neque id cursus faucibus">Praesent</a></li>
<li><a href="#nowhere" title="Pellentesque fermentum dolor" class="highlight">Pellentesque</a></li>
</ul>
</nav>
D3: How to assign style css to a specified id
countValues
is not a D3 selection, but a simple JavaScript array. For using selection.each, which...
Invokes the specified function for each selected element
... you have to chain it in a D3 selection.
That being said, you have to use a forEach
, not an each
. Then, inside the forEach
, you select the element by ID and apply the style:
countValues.forEach(function(d) {
d3.select("#" + d.name).style("fill", colorScale(d.counts));
});
Here is the demo:
var countValues = [{ "name": "polygon_1", "counts": 1}, { "name": "polygon_2", "counts": 2}];
var vis = d3.select("body").append("svg") .attr("width", 750) .attr("height", 920);
var colorLow = "yellow", colorMed = "blue";
var colorScale = d3.scale.linear() .domain([1, 2]) .range([colorLow, colorMed]);
countValues.forEach(function(d) { d3.select("#" + d.name).style("fill", colorScale(d.counts));});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.4/d3.min.js"></script><svg id="svgOne" width="750" height="920" style="position:absolute;"><polygon id="polygon_1" points="168, 20 213, 20 213, 73 168, 73 " fill="transparent"/> <polygon id="polygon_2" points="214, 20 259, 20 259, 73 214, 73 " fill="transparent"/> <polygon id="polygon_3" points="169, 73 212, 73 212, 133 169, 133 " fill="transparent"/></svg>
d3 Classed / Styling with Multiple IDs
The comments below the question have all the information to fix the problem. However, for future readers, I'd like to write some points here.
First of all: always read the documentation. With few exceptions, it has all information you need. For instance, let's see what it says about select:
Selects the first element that matches the specified selector string. (emphases mine)
Now let's see your code:
d3.select('#id1','#id2')
// ^--------- two strings, separated by a comma
That's not a string. This is a string:
d3.select('#id1, #id2')
// ^--------- just one string here!
Second problem: select
selects the first element that matches the string. So, you want selectAll
, not select
.
Solution: it has to be:
d3.selectAll("#id1, #id")
Here is a demo, click the button:
d3.select("button").on("click", function() { d3.selectAll("#c2, #c5").attr("fill", "brown");})
<script src="https://d3js.org/d3.v4.min.js"></script><button>Click me</button><svg> <circle id="c1" cx="20" cy="30" r="10" fill="teal"></circle> <circle id="c2" cx="60" cy="30" r="10" fill="teal"></circle> <circle id="c3" cx="100" cy="30" r="10" fill="teal"></circle> <circle id="c4" cx="140" cy="30" r="10" fill="teal"></circle> <circle id="c5" cx="180" cy="30" r="10" fill="teal"></circle></svg>
Replace the last bit of jQuery with d3.js - a selection with css-attribute change
I would change .attr("fill", "yellow")
to .style("fill", "yellow")
Using .attr() results in <rect fill="yellow" ...>
instead of <rect style="fill: yellow;" ...>
which might be causing your problem.
A d3.select... equivalent to jQuery.children()
There's no equivalent to jQuery.children()
. This is usually handled by assigning a distinguishing class to the elements you want to select together, e.g. something like this.
svg.selectAll("g").data(data)
.enter()
.append("g")
.attr("class", "parent")
.append("g")
.attr("class", "child");
svg.selectAll("g"); // all g elements
svg.selectAll("g.parent"); // only parents
svg.selectAll("g.child"); // only children
add custom elements based on css styles not images to chart D3.js
You should draw lines with the data like so:
chart.append('svg:g')
.selectAll('line')
.data(lineData.flags)
.enter()
.append('line')
.attr('x1', function(d) { return xScale(d.date); })
.attr('y1', function(d) { return yScale(d.value); })
.attr('x2', function(d) { return xScale(d.date); })
.attr('y2', height - 20)
chart.append('svg:g')
.selectAll('image')
.data(lineData.flags)
.enter()
.append('image')
.attr("xlink:href", img_icon_flag.src)
.attr("width", img_icon_flag.width)
.attr("height", img_icon_flag.height)
.attr("x", function(d) { return xScale(d.date); } )
.attr("y", function(d) { return yScale(d.value); } )
To see the lines you should put in your css
line {
stroke-width: 2;
stroke: #BFC1C1;
}
Related Topics
Remove CSS Rules by JavaScript
How to Get CSS Transform Rotation Value in Degrees with JavaScript
How to Make a Rotated Element Height:100% of Its Parent
Import JavaScript Files with CSS
How to Remove an Important CSS Property
Losing Mouseup Event If Releasing Not Over the Same Element
Css3 Keyframe Animations: End and Stay on the Last Frame
Using JavaScript Calculated Values in Less
Trigger Event Using Jquery on CSS Change
Make a Div Scroll When I Reach a Certain Point
Force Address Bar to Show in Mobile Chrome App
Parse CSS Gradient Rule with JavaScript Regex
How to Get CSS Class by Name from Stylesheet