@gramex/radar
v1.0.0
Published
A radial beeswarm or dot plot.
Downloads
11
Readme
@gramex/radar
A radial beeswarm or dot plot.
Example
Given this 100 most popular movies on IMDb:
... we can render the following radar:
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" },
];
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
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)),
...
});
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.
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 levelspoke
: The spokelevelIndex
: The index of the level (0, 1, 2, ...)spokeIndex
: The index of the spoke (0, 1, 2, ...)r0
: The inner radius of the spoker1
: The outer radius of the spokea0
: The start angle of the spoke in radiansa1
: The end angle of the spoke in radiansn
: Number of data points in this celldata
: 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 nodey
: The y-coordinate of the node
levelLabels
: Text labels for each level. The data includes:level
: The level name / labellevelIndex
: The index of the level (0, 1, 2, ...)r0
: The inner radius of the spoker1
: The outer radius of the spoke
spokeLabels
: Text labels for each spoke. The data includes:spoke
: The spoke name / labelspokeIndex
: The index of the spoke (0, 1, 2, ...)a0
: The start angle of the spoke in radiansa1
: 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");
Add tooltips
You can use Bootstrap tooltips.
- Add a
data-bs-toggle="tooltip" title="..."
attribute to each feature usingupdate
- Call
new bootstrap.Tooltip(element, {selector: '[data-bs-toggle="tooltip"]'})
to initialize 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
Release notes
- 1.0.0: 24 Mar 2024. Initial release
Authors
- Anand S [email protected]