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

Add ability to use CSS classes on SVG charts #107

Open
LordMike opened this issue Nov 15, 2022 · 2 comments
Open

Add ability to use CSS classes on SVG charts #107

LordMike opened this issue Nov 15, 2022 · 2 comments

Comments

@LordMike
Copy link

Hey,

I was wondering if it was possible to replace this:

<span data-peity='{ "fill": ["red", "#eeeeee"],    "innerRadius": 10, "radius": 40 }'>1/7</span>

With perhaps this:

<span data-peity='{ "class": "my-class",    "innerRadius": 10, "radius": 40 }'>1/7</span>
.. or
<span data-peity='{ "class": ["my-class", "my-class2"],    "innerRadius": 10, "radius": 40 }'>1/7</span>

This way I can move all my colors etc. to other systems, like SASS.

I checked the code, and it seems like there explicitly isn't a way to add attributes to the rendered SVG elements, so I can't even workaround it :). Also, I noted that SVG is optional, so of course classes wouldn't work if Peity fell back to canvas rendering.. but I'm willing to lose that support :).

Mike.

@benpickles
Copy link
Owner

That's a really good idea (both adding a class option and exposing the added elements), I can't believe it hasn't been suggested before now 💯

You're right, there's nothing available that exposes the added elements directly but there is a possible workaround using the official (but undocumented 😬) after hook. The following includes two cases, styling based the segment position (simple and generic), and styling based on the value of the segment (a bit more complicated and app-specific).

CodeSandbox: https://codesandbox.io/s/happy-sara-y08767

$(".donut").peity("donut", {
  radius: 40,
  after() {
    const children = this.$svg.children();
    children.each(function () {
      this.removeAttribute("fill");
      let className;
      if (children.length === 2) {
        className = "slice";
      } else {
        const value = parseInt(this.getAttribute("data-value"));
        className = value > 30 ? "large" : "medium";
      }
      this.setAttribute("class", className);
    });
  }
});
.slice:nth-child(odd) {
  fill: purple;
}
.slice:nth-child(even) {
  fill: pink;
}

.medium:nth-child(odd) {
  fill: yellow;
}
.medium:nth-child(even) {
  fill: orange;
}

.large {
  fill: red;
}

If you only want to style based on the position of the segment then you'd only remove all fills in the after hook and could rely entirely on CSS selectors:

.donut + svg > path:nth-child(odd) {
  fill: yellow;
}

@LordMike
Copy link
Author

You could also add attributes or classes (by default) to the rendered items, which I can affect w/ CSS. Something like:

<svg ..>
  <path .. data-peity-part="1" /> <-- one slice of pie
  <path .. data-peity-part="2" /> <-- two slice of pie
</svg>

This could allow others to also interact with the SVG elements, like adding click handlers and whatnot. :)

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