billboard.js 3.9 release: arc.needle, dark theme 🌘 & more!

Jae Sung Park
6 min readJul 3, 2023

--

New 3.9 release 🥳 out today! This release comes with 7 new features and 3 bug fixes.

For the detailed release info, please checkout the release note:
https://github.com/naver/billboard.js/releases/tag/3.9.0

What’s New?

arc.needle

Needle can be used to point certain point of data value, within arc shape.

Demos: https://naver.github.io/billboard.js/demo/#DonutChartOptions.DonutNeedle
https://naver.github.io/billboard.js/demo/#GaugeChartOptions.GaugeNeedle

The needle shape can be fully customized by your own(in this case it needs specify path value), or just simply update the length or top/bottom radii.

Checkout full option interface and its comments to understand each options.

[donut | gauge]: {
// when 'arc.needle.show=true' is set, will able to use template to reflect needle value
title: "{=NEEDLE_VALUE}"
},
arc: {
needle: {
show: true,
color: "red", // any valid CSS color

// for customized needle
path: function(length) {
const len = length - 20;

// will return upper arrow shape path
// Note: The path should begun from '0,0' coordinate to top center.
const path = `M 0 -${len + 20}
L -12 -${len}
L -5 -${len}
L -5 0
A 1 1 0 0 0 5 0
L 5 -${len}
L 12 -${len} Z`;

return path;
},

value: 40, // will make needle to point value 40.
length: 80, // needle length in percentages relative to radius.

top: {
// rx and ry are the two radii of the ellipse;
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#elliptical_arc_curve
rx: 1,
ry: 1,
width: 5
},

bottom: {
// rx and ry are the two radii of the ellipse;
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d#elliptical_arc_curve
rx: 1,
ry: 1,
width: 10
len: 10
}
}
}

The first donut chart uses customized needle and initial value specified. In this case, when some dataseries is hidden, the needle will updating to point given value.

And the second chart, initialized with 0 value, and the needle value is updated dynamically.

To update needle value dynamically, it provides simple API method to update current needle value by chart.$.needle.updateHelper().

// Update arc needle position
const chart = bb.generate({
data: {
type: "donut"
},
arc: {
needle: {
show: true,
...
}
}
});

chart.$.needle.updateHelper(70); // update needle position to point value 70.

// update needle position to point value 70 and the config value.
// NOTE: updating config value, will update needle pointer initial value too.
chart.$.needle.updateHelper(70, true);

// update needle point position every 1 second
let i = 0;
setInterval(() => {
chart.$.needle.updateHelper(i += 10);
}, 1000)

Dark theme

Dark mode are quite common these days, and to facilitate will provide dark theme from this release.

Of course as other themes, it can be used as a starter to apply your own styles based on dark theme.

dark theme will be distributed as single css file and see in action from the example page by selecting it from the left side navigation “Theme” section.

point.sensitivity

point.sensitivity option will let customize the distance(from data point’s x/y coordinate)to be interacted.

Demo: https://naver.github.io/billboard.js/demo/#Point.PointSensitivity

When sensitivity value is 3, it means the interaction will happen when mouse pointer enters 3px boundaries starting from exact x/y coordinate.

But for bubble type, specifying absolute value can’t make to interact smoothly, because each bubble radius will vary on its value.

To improve this, will provide radius option, to reflect the sensitivity depend on each bubble radius. And also, provides callback option which can add some conditional to control it in more detail way.

point: {
// having lower value, means how closer to be for interaction
sensitivity: 3,

// sensitivity based on point's radius
sensitivity: "radius",

// callback for each point to determine the sensitivity
sensitivity: function(d) {
// ex. of argument d:
// ==> {x: 2, value: 55, id: 'data3', index: 2, r: 19.820624179302296}

// returning d.r, will make sensitivity same as point's radius value.
return d.r;
}
}

The below example, illustrate when sensitivity value is specified as absolute value and when is specified radius value.

data.labels.position

Another enhancement option to control the position of data label text.

Demo: https://naver.github.io/billboard.js/demo/#Data.DataLabelPosition

Just simply return corresponding x/y coordinate value for each data text element as you want.

data: {
...
labels: {
show: true,
/**
* The arguments are:
* - `type` coordinate type string, which will be 'x' or 'y'.
* - `v` is the value of the data point where the label is shown.
* - `id` is the id of the data where the label is shown.
* - `i` is the index of the data series point where the label is shown.
* - `texts` is the array of whole corresponding data series' text labels.
*/
position: function(type, v, id, i, texts) {
let pos = 0;
const len = texts.size() / 2 - 1;

if (type === "x" && (i === 0 || i === len)) {
pos = i === 0 ? 20 : -20;
}

return pos;
}
}
}

bar.front

When various shape types with bar type are used in single chart, usually bar shapes are positioned in behind of other shapes elements to not make overlap and interrupt the visibility.

Controlling z-order is not easy in “svg world”, because the z-order will be following relative of DOM tree structure.

The only way to control this, it needs control DOM tree structure which is not an easy task.

Demo: https://naver.github.io/billboard.js/demo/#BarChartOptions.BarFront

Enabling this option, will simply make bar shapes to appear at the front of other shapes elements.

bar: {
front: true
}

Easily can notice the differences from below example.

legend.item.interaction

By default, legend items will have toggle and over/out interaction. But sometimes there’re needs to disable it.

From this release, will provide new options to control it.

Demo: https://naver.github.io/billboard.js/demo/#Legend.LegendItemInteraction

Will provide 2 way to control:

  • Enable or disable the default legend interaction
  • Provide a “double click” interaction, which in this case, double clicking will make focusing clicked dataseries and hiding others.
legend: {
item: {
// will disable default interaction (mouse hover effect and click to hide clicked dataseries)
interaction: false | {
/**
* Set legend item to interact on double click.
* - **NOTE:**
* - Double clicking will make focused clicked dataseries only, hiding all others.
* - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect.
* - To return initial state(which all dataseries are showing), double click current focused legend item again.
* - for single click case, `click + altKey(Win)/optionKey(Mac OS)` to have same effect.
* - In this case, default `click` interaction will be disabled.
*/
dblclick: true
},

// when set below callback option value, will work regardless of 'interaction=false' is set
onclick: function(id) { ... },
onover: function(id) { ... },
onout: function(id) { ... }
}
}

See in action when dblclick option is enabled. “Double clicking” legend item, will make appearing clicked dataseries only and hiding the others.

To return initial states, double click focused legend item again.

Closing

The number of downloads are continuously growing, and it reached 100k downloads per month!

This proves competitiveness among other options, and this is somehow delightful 😆 to see more more developers around the worlds are choosing billboard.js for the data visualization.

We’ll continuously making improvements from your supports!

--

--

Jae Sung Park
Jae Sung Park

Written by Jae Sung Park

Front-end engineer at NAVER, creator of billboard.js

No responses yet