npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@gramex/radar

v1.0.0

Published

A radial beeswarm or dot plot.

Downloads

1

Readme

@gramex/radar

A radial beeswarm or dot plot.

Example

Given this 100 most popular movies on IMDb:

Table of 100 movies with name, genre, year, rating, and votes on IMDb

... we can render the following radar:

IMDb radar visual - playground

Installation

Install via npm:

npm install @gramex/radar@1

Use locally as an ES module:

<script type="module">
  import { radar } from "./node_modules/@gramex/radar/dist/radar.js";
</script>

Use locally as a script:

<script src="./node_modules/@gramex/radar/dist/radar.min.js"></script>
<script>
  gramex.radar(...)
</script>

Use via CDN as an ES Module:

<script type="module">
  import { radar } from "https://cdn.jsdelivr.net/npm/@gramex/radar@1";
</script>

Use via CDN as a script:

<script src="https://cdn.jsdelivr.net/npm/@gramex/radar@1/dist/radar.min.js"></script>
<script>
  gramex.radar(...)
</script>

Data is a list of levels and spokes

The data is a list of rows containing an ordered "level" category (going outwards) and an unordered "spoke" category . Each row is an object with keys for each column. For example:

const data = [
  { level: "low", spoke: "blue" },
  { level: "low", spoke: "orange" },
  { level: "low", spoke: "green" },
  { level: "medium", spoke: "blue" },
  { level: "medium", spoke: "orange" },
  { level: "medium", spoke: "green" },
  { level: "high", spoke: "blue" },
  { level: "high", spoke: "orange" },
  { level: "high", spoke: "green" },
];

Example

See how to use radar

Calling radar(el, { data }) will render the radar. You need to style the output.

Specify level and spoke columns

Use level and spoke parameters to customize the columns used for levels and spokes. For example, this employees data has:

| team | band | | ----------- | ------ | | Analytics | Band 1 | | Consulting | Band 2 | | Design | Band 3 | | Engineering | Band 4 | | ... | ... |

We use the level and spoke parameters to specify the columns:

  const graph = radar("#radar", {
    data,
    level: (d) => d.band.replace(/Band /, ""),
    spoke: (d) => d.team,
    ...
  });

The radar automatically adjusts the

Example

See how to specify level and spoke columns

Re-order levels and spokes

Radar auto-extracts levels and spokes from data. Use levels and spokes to:

  • Show only specific levels and spokes (even if they don't exist in the data)
  • Re-order levels and spokes

For example:

  const graph = radar("#radar", {
    data,
    // Show only the top 3 levels, in descending order
    levels: ["6", "5", "4"],
    // Show these levels in order, even though Legal doesn't exist
    spokes: ["Design", "Consulting", "Engineering", "Legal"],
    ...
  });

You can specificy levels and spokes dynamically with a function Map(key, count) => [...keys]. For example:

  const graph = radar("#radar", {
    data,
    // Sort levels in reverse (e.g. "6", "5", "4", ... "1")
    levels: (counter) => [...counter.keys()].sort(d3.descending),
    // Sort spokes in descending order of count, i.e. largest first
    spokes: (counter) => d3.sort([...counter.keys()], d => -counter.get(d)),
    ...
  });

Example

See how to customize levels and spokes

Resize levels and spokes

Radar distributes levels and spokes evenly within the container circle. Use levelScale and spokeScale to:

  • Create spacing between levels or spokes
  • Give more space to specific levels or spokes

For example:

  // Start and end radius in SVG units (pixels)
  const levelRange = [[0, 60], [66, 120], [125, 140], [145, 160], [165, 180], [185, 200]];
  // Start and end angle in degrees
  const spokeRange = [[180, 210], [210, 240], [240, 255], [255, 310], [310, 330], [330, 360]]
  const graph = radar("#radar", {
    data,
    levelScale: (level, index) => levelRange[index],
    spokeScale: (spoke, index) => spokeRange[index],
    ...
  });

You can also specify the center of the radar using cx and cy. It defaults to width / 2 and height / 2.

  const graph = radar("#radar", {
    data,
    cx: 100,
    cy: 100,
    ...
  });

Use graph.r to get the maximum non-overlapping radius of the nodes.

Example

See how to resize levels and spokes

Style the radar

The returned object has the following D3 selections:

  • cells: Arc paths for each level, spoke segment. (Used to style the background of the radar). The data includes:
    • level: The level
    • spoke: The spoke
    • levelIndex: The index of the level (0, 1, 2, ...)
    • spokeIndex: The index of the spoke (0, 1, 2, ...)
    • r0: The inner radius of the spoke
    • r1: The outer radius of the spoke
    • a0: The start angle of the spoke in radians
    • a1: The end angle of the spoke in radians
    • n: Number of data points in this cell
    • data: All data elements for this cell (i.e. level and spoke combination). Absent if n == 0
  • nodes: Circles for each data element. The data includes:
    • x: The x-coordinate of the node
    • y: The y-coordinate of the node
  • levelLabels: Text labels for each level. The data includes:
    • level: The level name / label
    • levelIndex: The index of the level (0, 1, 2, ...)
    • r0: The inner radius of the spoke
    • r1: The outer radius of the spoke
  • spokeLabels: Text labels for each spoke. The data includes:
    • spoke: The spoke name / label
    • spokeIndex: The index of the spoke (0, 1, 2, ...)
    • a0: The start angle of the spoke in radians
    • a1: The end angle of the spoke in radians

You can style these using D3 selections. For example:

// Color empty background cells pink, and filled cells white
graph.cells.attr("fill", (d) => (d.n ? "white" : "pink"));
// Color nodes with see-through black. Give them a bit more than the maximum non-overlapping size
graph.nodes.attr("fill", "rgba(0,0,0,0.2)").attr("r", graph.r * 1.5);
// Make labels bigger and red
graph.levelLabels.attr("font-size", 12).attr("fill", "red");
graph.spokeLabels.attr("font-size", 12).attr("fill", "red");

Example

See how to style the radar

Add tooltips

You can use Bootstrap tooltips.

  1. Add a data-bs-toggle="tooltip" title="..." attribute to each feature using update
  2. Call new bootstrap.Tooltip(element, {selector: '[data-bs-toggle="tooltip"]'}) to initialize tooltips

Example

See how to add tooltips

Bring your own D3

If you already have D3 loaded, or want to use a specific version / instance of D3, pass it to radar(el, { d3 }):

API

See API documentation

Release notes

  • 1.0.0: 24 Mar 2024. Initial release

Authors

License

MIT