Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to customize fill color for each item inside the pattern ? #220

Open
devikanarmada opened this issue Aug 30, 2022 · 1 comment

Comments

@devikanarmada
Copy link

No description provided.

@greenstick
Copy link

greenstick commented Mar 6, 2024

I'd like to add to this – trying to figure this out and it's unclear how to do this efficiently with D3.

Key reason why this is important is that color and texture offer two separate dimensions for visualization. As an example, in my current project, fill is defined by the color dimension, which is mapped to the legend in my visualizations, and textures will ideally be defined to correspond to an interactive filter dimension (i.e. we have filters that let the user interact with the data and subset it to get a drilled down view).


For any future folks, one current work around is to duplicate each element – in my case, I first render the color data element and then, using D3's element cloning method, render the textured element on top of it. Any event bindings are then applied to the textured element that's rendered on top of its corresponding colored element. It works, but duplicating each SVG node corresponding to a data element is a pretty DOM heavy and inefficient approach.

Key code below (for a stacked bar graph):

import textures from "textures";

// Setup Texture Scale & Map Object
self.texturescale = D3.scaleOrdinal().domain(self.filters).range(self.textures);
self.texturesMap = Object.fromEntries(
    new Map(self.textures.map((texture) => [
        texture, 
        textures
            .paths()
            .d(texture)
            .shapeRendering("geometricPrecision")
            .lighter()
            .thinner()
            .fill("transparent")
    ]))
 );  

// ... Other chart code

self.bargroups
    .selectAll("rect")
    .data((d) => d)
    .enter()
    .append("rect")
        .attr("id", (d) => `bar-${d.id}`)
        .attr("class", (d) => `bar`)
        .attr("x", (d) => self.x(d.from))
        .attr("y", (d) => self.y(d.group))
        .attr("width", (d) => self.x(d.to) - self.x(d.from))
        .attr("height", self.y.bandwidth())
        .attr("fill", (d) => self.texturesMap[self.textureScale(d.filter)]
        .attr("opacity", 0.7)
    .clone(true) // Clone Rect Element
        .attr("class", "bar interactable")
        .attr("fill", (d) => self.texturesMap[self.textureScale(d.filter).url()]
        .attr("opacity", 1.0)
    .on("mouseover", (e, d) => self.mouseOverBar(e, d))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants