1

I'm attempting to render arrows with segments of different colouring using D3 and the linearGradient element, by appending it to an SVG. However, I have found that in chrome, when there are a lot of segments, the division between each segment has a significant blur even when the offset is configured to not have blurring.

Appearance in Chrome

For comparison, Firefox renders it correctly. Chrome seems to also be alright as long as the number of divisions is three or less, but blurs significantly with larger arrows and more divisions. Is there any way to get around this?

Appearance in Firefox

This is my linear gradient code:

svg.append('linearGradient')
.attr('id', 'grad_' + id)
    .attr('x1', '0%').attr('y1', '0%')
    .attr('x2', '100%').attr('y2', '0%')
    .selectAll('stop')
    .data([{"offset":"0%","color":"#7A9D5B"},{"offset":"2%","color":"#7A9D5B"},{"offset":"2%","color":"black"},{"offset":"3%","color":"black"},{"offset":"3%","color":"#7A9D5B"},{"offset":"4%","color":"#7A9D5B"},{"offset":"4%","color":"black"},{"offset":"18%","color":"black"},{"offset":"18%","color":"#7A9D5B"},{"offset":"21%","color":"#7A9D5B"},{"offset":"21%","color":"black"},{"offset":"23%","color":"black"},{"offset":"23%","color":"#7A9D5B"},{"offset":"27%","color":"#7A9D5B"},{"offset":"27%","color":"black"},{"offset":"27%","color":"black"},{"offset":"27%","color":"#7A9D5B"},{"offset":"42%","color":"#7A9D5B"},{"offset":"42%","color":"black"},{"offset":"42%","color":"black"},{"offset":"42%","color":"#7A9D5B"},{"offset":"45%","color":"#7A9D5B"},{"offset":"45%","color":"black"},{"offset":"71%","color":"black"},{"offset":"71%","color":"#7A9D5B"},{"offset":"72%","color":"#7A9D5B"},{"offset":"72%","color":"black"},{"offset":"72%","color":"black"},{"offset":"72%","color":"#7A9D5B"},{"offset":"81%","color":"#7A9D5B"},{"offset":"81%","color":"black"},{"offset":"87%","color":"black"},{"offset":"87%","color":"#7A9D5B"},{"offset":"99%","color":"#7A9D5B"},{"offset":"99%","color":"black"}])
    .enter().append('stop')
    .attr('offset', function (d) { return d.offset })
    .attr('stop-color', function (d) { return d.color })
    .attr("stop-opacity", 1)

svg.append('svg:polygon')
    .attr('points', p)
    .attr('fill', 'url(#grad_' + id + ')')

EDIT: This is the SVG.

<svg class="row open" preserveAspectRatio="xMinYMin meet" viewBox="0 0 960 320">
    <linearGradient id="grad_P0DTC1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="black" stop-opacity="1"></stop><stop offset="0.22701475595913734%" stop-color="black" stop-opacity="1"></stop><stop offset="0.22701475595913734%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="2.8830874006810445%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="2.8830874006810445%" stop-color="black" stop-opacity="1"></stop><stop offset="3.2917139614074915%" stop-color="black" stop-opacity="1"></stop><stop offset="3.2917139614074915%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="4.0862656072644725%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="4.0862656072644725%" stop-color="black" stop-opacity="1"></stop><stop offset="18.59250851305335%" stop-color="black" stop-opacity="1"></stop><stop offset="18.59250851305335%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="21.08967082860386%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="21.08967082860386%" stop-color="black" stop-opacity="1"></stop><stop offset="23.223609534619747%" stop-color="black" stop-opacity="1"></stop><stop offset="23.223609534619747%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="27.17366628830874%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="27.17366628830874%" stop-color="black" stop-opacity="1"></stop><stop offset="27.94551645856981%" stop-color="black" stop-opacity="1"></stop><stop offset="27.94551645856981%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="42.701475595913735%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="42.701475595913735%" stop-color="black" stop-opacity="1"></stop><stop offset="42.95119182746879%" stop-color="black" stop-opacity="1"></stop><stop offset="42.95119182746879%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="45.87968217934166%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="45.87968217934166%" stop-color="black" stop-opacity="1"></stop><stop offset="71.9182746878547%" stop-color="black" stop-opacity="1"></stop><stop offset="71.9182746878547%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="72.5539160045403%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="72.5539160045403%" stop-color="black" stop-opacity="1"></stop><stop offset="72.62202043132804%" stop-color="black" stop-opacity="1"></stop><stop offset="72.62202043132804%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="81.11237230419978%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="81.11237230419978%" stop-color="black" stop-opacity="1"></stop><stop offset="87.55959137343928%" stop-color="black" stop-opacity="1"></stop><stop offset="87.55959137343928%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="99.70488081725311%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="99.70488081725311%" stop-color="black" stop-opacity="1"></stop></linearGradient>

    <polygon points="0,20,0,40,946.6666666666666,40,946.6666666666666,43.333333333333336,960,30,946.6666666666666,16.666666666666664,946.6666666666666,20" fill="url(#grad_P0DTC1)" id="P0DTC1" title="P0DTC1" transform="translate(0,0)"><title>Polyprotein 1a</title></polygon>
</svg>

For comparison, this one with less divisions works fine.

<svg class="row open" preserveAspectRatio="xMinYMin meet" viewBox="0 0 960 320">
    <linearGradient id="grad_P0DTC1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" stop-color="black" stop-opacity="1"></stop><stop offset="18.59250851305335%" stop-color="black" stop-opacity="1"></stop><stop offset="18.59250851305335%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="42.701475595913735%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="42.701475595913735%" stop-color="black" stop-opacity="1"></stop><stop offset="71.9182746878547%" stop-color="black" stop-opacity="1"></stop><stop offset="71.9182746878547%" stop-color="#7A9D5B" stop-opacity="1"></stop><stop offset="81.11237230419978%" stop-color="#7A9D5B" stop-opacity="1"></linearGradient>

    <polygon points="0,20,0,40,946.6666666666666,40,946.6666666666666,43.333333333333336,960,30,946.6666666666666,16.666666666666664,946.6666666666666,20" fill="url(#grad_P0DTC1)" id="P0DTC1" title="P0DTC1" transform="translate(0,0)"><title>Polyprotein 1a</title></polygon>
</svg>
  • You could try reporting the issue to [Chrome's bugtracker](https://bugs.chromium.org/p/chromium/issues/list) unless it's already been reported. – Robert Longson Jun 30 '21 at 07:03
  • Could you post the resulting svg so we could try it - I assume it's a Chrome error but just in case, and it's very weird it fails after 3 items rather than consistently. – A Haworth Jun 30 '21 at 07:43
  • @AHaworth Yes of course. I just added this information to the post. – Alana Huang Jul 02 '21 at 04:03
  • This seems to be related: [link]https://stackoverflow.com/questions/26652661/blurry-linear-gradient-stops-in-chrome though talking about CSS rather than SVG - one workaround there is to split the background, another is to overlap the % values. – A Haworth Jul 02 '21 at 06:31

0 Answers0