beautiful or else.
bore
is a library built on top of D3 that lets you create extendible, reusable and stylistically consistent visualizations. It follows from the article "Towards Reusable Charts" written by Mike Bostock.
We use it for our data graphics at The Michigan Daily.
If you're familiar with D3, using bore
should be fairly intuitive because it follows from the function pattern in D3 (and jQuery).
const svg = d3.select("figure")
.append("svg")
.attr("width", width)
.attr("height", height);
const x = d3.scaleLinear()
.domain([0, 100])
.range([margin.left, width - margin.right])
const xAxis = svg.append("g")
.attr("transform", `translate(${margin.left}, 0)`)
.call(d3.axisLeft(x).ticks(width / 80));
Here we append a g
element to the svg
and call the axisLeft
function with the x
scale. We chain the ticks
function to modify the default behavior of the axis function.
The purpose of bore
is to create a higher-level API on top of D3 that can be used to create common chart types. Like how D3 has a built-in API for creating axes, bore
has a built-in API for creating charts.
In addition to providing chart types, bore
also exports several useful utility constructs such as a text-wrapping, styled axes and color schemes.
-
Add
bore
as a dependency:yarn add michigandaily/bore
You can use a specific version or branch of
bore
by adding a#
to the end and specifying a version or branch (e.g.,#v3.0.1
). -
Import
bore
:import * as bore from "@michigandaily/bore";
-
Bind your data to an SVG:
const svg = d3.select("figure") .append("svg") .datum(data);
This library is being made with maps* in mind, but it may also work with other iterables.
-
Call a
bore
chart on your SVG selection:svg.call( bore.build( new bore.BarChart() .color(color) .height(175) .label(d => `${d[1].toPrecision(3)}%`) .wrappx(75) ) );
Make note of the
new
keyword. Internally,bore
implements each chart type as a class. Thenew
keyword is necessary to create a new instance of a class (as is usual in OOP).Also make note of the
build
function that wraps the entireBarChart
construction. Internally, this is necessary to correctly bind thethis
context of the chart to itself instead of to the D3 selection.Using other chart types will follow a nearly identical pattern, though the functions that can be chained to a chart type may differ from chart to chart. Refer to the API Reference for more details or take a look at the examples.
* I initially chose maps over objects because I felt it'd be less ergonomic to have to specify an x or y accessor. However, it may be preferable to specify accessors in some chart types. I have not done research into the performance benefits of maps or objects.
TODO
Work on a branch if you plan on adding something to bore
-- the main
branch is protected.
- Clone
cookie
andbore
into the same directory. - Run
yarn install
incookie
and inbore
.
-
In
bore
, runyarn link
. -
In
cookie
, runyarn link "@michigandaily/bore"
. -
Import
bore
incookie
:// cookie/src/graphic/js/graphic.js import * as bore from "@michigandaily/bore";
In cookie
, run yarn dev
.
Whenever changes are made in bore
, the cookie
server will reload to reflect those changes.
When finished developing, unlink the repositories.
- In
cookie
, runyarn unlink "@michigandaily/bore"
. - In
bore
, runyarn unlink
.
- Update the version in
package.json
according to semantic versioning. - Create a pull request to
main
. - Once merged, create a new tag and release with the same version number in
package.json
prefxied withv
.