bsr
bsr

Reputation: 58742

D3.js setting multiple styles dynamically

D3's operation on selection are versatile (likeattr) that it takes a value, or a function with the data passed on. I wanted to set few style parameters based on the current selection.

From the doc: From what I understand, below scenarios will work

sel.style("stroke", "#000")
sel.style({"stroke": "#000", "stroke-width": "0.5"})
sel.style("stroke", function(d){return "#000"})

but, what I need is it to take an object returned by a fn.

var fn = function(d){
return {"stroke": "#000", "stroke-width": "0.5"}
}
sel.style( fn)

Above example, I don't do anything with d, but ,in my case, I would make decision based on d passed.

I am sure, I may be able to do something like,

sel.style(`fill`, fillFn)
sel.style(`stroke`, strokeFn)

But, I am trying to make my code generic, so I may not know what style I need to set ahead of time.

Edit:

I also tried, selection.property,

sel.property("style", fn);

but got error

TypeError: Object [object Array] has no method 'property'

but, on the same selection, if I do

sel.style({"stroke": "#000", "stroke-width": "0.5"})

it works fine. What could be wrong?

Upvotes: 3

Views: 6218

Answers (2)

user7739271
user7739271

Reputation:

My answer relates to css almost but I think it's a good idea to solve the problem.

    d3.selection.prototype.css = function (...arr) {
        if (arr.length === 2) {
            this.style(arr[0], arr[1]);
        } else if (arr.length === 1 && typeof arr[0] === 'object') {
            let properties = arr[0];

            for (let prop in properties) {
                this.style(prop, properties[prop]);
            }
        }
        return this;
    };

Useage:

    d3.select('body').css('text-decoration', 'underline').css({
        'color': '#f00',
        'font-size': '20px'
    });

p/s: I'm just learning d3 about 2 hours ago. Good luck :)

Upvotes: 1

Lars Kotthoff
Lars Kotthoff

Reputation: 109292

In this case, I would use the .each() function (or maybe .call()) to run a function on each (or all at once) selected elements. In this function, you can, based on data or something else, add styles, attributes etc.

The basic code would look like this.

sel.each(someFunc);
function someFunc(d) {
    if(d.something) { d3.select(this).style("foo", "bar"); }
    if(d.somethingElse) { d3.select(this).attr("bar", "foo"); }
}

Upvotes: 5

Related Questions