How do I get my area filled beneath my d3 line chart to be a gradient?
Asked Answered
P

2

5

I'm using d3 v4. I would like to create a line chart where the area beneath the graph is an area filled by a gradient going from dark at the top to light at the bottom. I thought this was the way to configure such a gradient

  svg.append("linearGradient")
        .attr("id", "area-gradient")
        .attr("gradientUnits", "userSpaceOnUse")
        .attr("x1", 0).attr("y1", y(0))
        .attr("x2", 0).attr("y2", y(1000))
    .selectAll("stop")
        .data([
            {offset: "0%", color: "navy"},
            {offset: "30%", color: "navy"},
            {offset: "45%", color: "navy"},
            {offset: "55%", color: "navy"},
            {offset: "60%", color: "navy"},
            {offset: "100%", color: "navy"}
        ])
    .enter().append("stop")
        .attr("offset", function(d) { return d.offset; })
        .attr("stop-color", function(d) { return d.color; });

and using this style

.area {                         
    fill: url(#area-gradient);                  
    stroke-width: 0px;          
}

but as you can see from my Fiddle -- https://jsfiddle.net/yw46ycse/3/, what I have instead is a solid area. What else do I need to do to get the area beneath the graph to be a gradient?

Popsicle answered 9/8, 2017 at 20:11 Comment(0)
G
5

Is this the version of the solution your looking for. You can use transparent as the stop-color {offset: "95%", color: "transparent"}.

Here is a modified version of your fiddle that i used to make it as you need it.

https://codepen.io/Nasir_T/pen/OjOWxz

Hope this helps.

Ginoginsberg answered 15/8, 2017 at 18:45 Comment(0)
P
4

a couple of issues to address:

  1. You have "navy" for every stop, so the gradient won't show
  2. It would be better in this instance to not .attr("gradientUnits", "userSpaceOnUse"). By using the default setting of objectBoundingBox (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/gradientUnits) then you can just use 0,0 0,1 to specify a vertical linear gradient.

For example:

svg.append("linearGradient")
        .attr("id", "area-gradient")
        .attr("x1", 0).attr("y1", 0)
        .attr("x2", 0).attr("y2", 1)
    .selectAll("stop")
        .data([
            {offset: "0%", color: "navy"},
            {offset: "100%", color: "red"}
        ])
    .enter().append("stop")
        .attr("offset", function(d) { return d.offset; })
        .attr("stop-color", function(d) { return d.color; })

Updated fiddle: https://jsfiddle.net/yw46ycse/4/

Pung answered 9/8, 2017 at 22:57 Comment(8)
THanks for this update. What I was going for was a gradient that starts at navy and then fades into nothing (transparent). Would I just replace "red" with "transparent"?Popsicle
developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stop-opacityPung
I tried to replace "stop-color" with "stop-opactiy" from your Fiddle but that leaves me with an area that is completely black without any gradient. If I were a CSS guy, I'd probably know better what to do with it.Popsicle
probably worth another SO question, or changing this. I imagine you need both colour and opacity for each stopPung
Could you not could specify color opacity with "rgba(0,0,128,0)"? Like this ? (rgb(0,0,128) is navy). You could then temper the tapering how you wanted like so here.Grizel
Hey @Andrew, how did you get the gradient to show up in your examples?Popsicle
I may be misunderstanding but I just set the stop color specifying the alpha channel which will modify your transparency (rgba vs rgb).Grizel
No you understood perfectly. Your examples are exactly what I was looking for.Popsicle

© 2022 - 2024 — McMap. All rights reserved.