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

<defs> not allowed inside <svg> #23

Open
cblaettl opened this issue Dec 1, 2021 · 1 comment
Open

<defs> not allowed inside <svg> #23

cblaettl opened this issue Dec 1, 2021 · 1 comment

Comments

@cblaettl
Copy link

cblaettl commented Dec 1, 2021

Hi 👋,

First of all thank you very much for this awesome library, I like it a lot!

But I got a question: I'd like to fill the backrgound of my sparkline with a gradient, like so:

<svg
  width="300"
  height="60"
  stroke-width="3"
  style="fill: url(#fade)"
>
  <defs>
    <linearGradient id="fade" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="currentColor" />
      <stop offset="100%" stop-color="transparent" />
    </linearGradient>
  </defs>
</svg>

But this throws the following error, because sparkline tries to remove all children of the element first.

Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Do you have any idea how to prevent this error?

Thanks,
Christian

@dulacp
Copy link

dulacp commented Nov 7, 2024

For posterity (three years later), as a workaround you can inject the <defs> tag after the sparkline has been created.

For example:

sparkline(svgEl, props.data, options)

// Inject the gradient
const svgNS = "http://www.w3.org/2000/svg"
const defs = document.createElementNS(svgNS, "defs")

const linearGradient = document.createElementNS(svgNS, "linearGradient")
linearGradient.setAttribute("id", "verticalGradient")

// Make the gradient vertical
linearGradient.setAttribute("x1", "0%")
linearGradient.setAttribute("y1", "0%")
linearGradient.setAttribute("x2", "0%")
linearGradient.setAttribute("y2", "100%")

const stop1 = document.createElementNS(svgNS, "stop")
stop1.setAttribute("offset", "0%")
stop1.setAttribute("stop-color", "var(--color-stop)")

const stop2 = document.createElementNS(svgNS, "stop")
stop2.setAttribute("offset", "30%")
stop2.setAttribute("stop-color", "var(--color-stop)")

const stop3 = document.createElementNS(svgNS, "stop")
stop3.setAttribute("offset", "95%")
stop3.setAttribute("stop-color", "var(--color-bot)")

linearGradient.appendChild(stop1)
linearGradient.appendChild(stop2)
linearGradient.appendChild(stop3)
defs.appendChild(linearGradient)
svgEl.appendChild(defs)

Styling

#verticalGradient {
  --color-stop: red;
  --color-bot: #ffffff;
}

.sparkline--fill {
  fill: url(#verticalGradient);
}

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