@nebula.js/sn-line-chart
The line chart is a common, widely used visualization. It is often used to show trends over time.
Requirements
Requires @nebula.js/stardust
version 1.7.0
or later.
Installing
If you use npm: npm install @nebula.js/sn-line-chart
. You can also load through the script tag directly from https://unpkg.com.
Usage
import { embed } from '@nebula.js/stardust';
import line from '@nebula.js/sn-line-chart';
const nuked = embed(app, {
types: [
{
name: 'line-chart',
load: () => Promise.resolve(line),
},
],
});
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
properties: {
title: 'Price of Gold and Bitcoin',
dataPoint: {
show: true,
showLabels: true,
},
gridLine: {
auto: false,
},
dimensionAxis: {
show: 'all',
dock: 'near',
},
measureAxis: {
spacing: 0.5,
dock: 'near',
show: 'all',
logarithmic: true,
},
},
});
More examples
One dimension, two measures, area styling
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
properties: {
lineType: 'area',
},
});
One dimension, two measures, vertical orientation
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.Quarter', 'Date.autoCalendar.Year', '=Avg(Bitcoin)'],
properties: {
orientation: 'vertical',
dimensionAxis: {
continuousAuto: false,
dock: 'near',
},
dataPoint: {
show: true,
showLabels: true,
},
preferContinuousAxis: false,
},
});
Two dimensions, one measure
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.Quarter', 'Date.autoCalendar.Year', '=Avg(Bitcoin)'],
properties: {
measureAxis: {
dock: 'near',
show: 'all',
logarithmic: true,
},
dataPoint: {
show: true,
showLabels: true,
},
},
});
One dimension, two measures, two reference lines
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
properties: {
refLine: {
refLines: [
{
label: '',
paletteColor: {
color: 'green',
},
refLineExpr: {
value: 52500,
},
show: true,
},
{
label: '',
paletteColor: {
color: 'red',
},
refLineExpr: {
value: 3570,
},
show: true,
},
],
},
measureAxis: {
dock: 'near',
show: 'all',
logarithmic: true,
},
dataPoint: {
show: true,
},
},
});
});
Line chart plugins
A plugin can be passed into a line chart to add or modify its capability
or visual appearance.
A plugin needs to be defined before it can be rendered together with the chart.
const minorAxisTitlePlugin = {
info: {
name: 'minor-axis-title-plugin',
type: 'component-definition',
},
fn: ({ keys, layout }) => {
const componentDefinition = {
type: 'data-title',
key: keys.COMPONENT.MINOR_AXIS_TITLE,
style: {
fontFamily: 'Tahoma, san-serif',
fontSize: '15px',
},
};
return componentDefinition;
},
};
nuked.render({
element: document.querySelector('#object'),
type: 'sn-line-chart',
plugins: [majorAxisTitlePlugin],
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
properties: {
title: 'History Price of Gold vesus Bitcoin (USD)',
measureAxis: { show: 'all', logarithmic: true },
},
});
The plugin definition is an object, with two properties info
and fn
.
The fn
returns a picasso.js
component. To build this component,
some important chart internals are passed into the argument object of fn
.
const pluginArgs = {
layout,
keys: {
SCALE: {
MAIN: {
MINOR,
MAJOR,
},
},
COMPONENT: {
LINE,
MAJOR_AXIS,
MAJOR_AXIS_TIME_INNER,
MAJOR_AXIS_TITLE,
MINOR_AXIS,
MINOR_AXIS_TITLE,
},
COLLECTION: {
MAIN,
},
},
};
With plugins, you can either add new components or modify existing components
of the line chart.
Add new components
The new component can be a standard Picasso component
or a custom Picasso component. Here we demo a custom component
which add labels to the min/max positions of the line.
const minMaxLabelsPluginImplementation = {
info: {
componentName: 'custom-labels-plugin',
name: 'custom-labels-plugin',
type: 'custom-component',
},
fn: ({ keys }) => {
const implementation = {
require: ['chart', 'renderer'],
render() {
const items = this.chart
.component(keys.COMPONENT.LINE)
.data.items.filter((item) => item.line.value === 1 && item.label >= '2018');
const scale = this.chart.scales();
const timeScale = scale[keys.SCALE.MAIN.MAJOR];
const lineScale = scale[keys.SCALE.MAIN.MINOR];
const { width, height } = this.rect;
const min = Math.min(...items.map((item) => item.end.value));
const max = Math.max(...items.map((item) => item.end.value));
const labels = [];
items.forEach((item) => {
if (item.end.value === min) {
labels.push({
type: 'text',
text: `min: ${item.end.label}`,
x: timeScale(item.major.value) * width,
y: lineScale(item.end.value) * height + 15,
anchor: 'middle',
fontFamily: 'Tahoma, san-serif',
fontSize: '15px',
fill: 'darkred',
});
} else if (item.end.value === max) {
labels.push({
type: 'text',
text: `max: ${item.end.label}`,
x: timeScale(item.major.value) * width,
y: lineScale(item.end.value) * height - 15,
anchor: 'middle',
fontFamily: 'Tahoma, san-serif',
fontSize: '15px',
fill: 'darkgreen',
});
}
});
return labels;
},
};
return implementation;
},
};
const minMaxLabelsPlugin = {
info: {
name: 'labels',
type: 'component-definition',
},
fn: ({ keys }) => {
const componentDefinition = {
type: 'custom-labels-plugin',
key: 'my-labels',
};
return componentDefinition;
},
};
Modify existing components
As an example, the appearance of the line can be
modified by plugin.
To overide an existing component, fn
should returns a picasso.js
component
that has the same key
as the existing component (keys.COMPONENT.LINE
in
this example)
const linePlugin = {
info: {
name: 'line-plugin',
type: 'component-definition',
},
fn: ({ layout, keys }) => {
const componentDefinition = {
type: 'line',
key: keys.COMPONENT.LINE,
settings: {
layers: { curve: 'monotone', line: { strokeWidth: 3 } },
},
};
return componentDefinition;
},
};
Plugins disclaimer
- The plugins API is still experimental.
- We can not guarantee our charts to be compatible with all different settings, especially when modifying existing components.