@nebula.js/sn-line-chart
v1.31.13
Published
Line chart supernova
Downloads
39,148
Readme
@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';
// 'app' is an enigma app model
const nuked = embed(app, {
types: [
{
// register line chart
name: 'line-chart',
load: () => Promise.resolve(line),
},
],
});
nuked.render({
element: document.querySelector('.lines'),
type: 'line-chart',
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
// Overrides default properties
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)'],
// Overrides default properties
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)'],
// Overrides default properties
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',
// Two dimensions, one measure
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)'],
// Overrides default properties
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.
// Step 1: define the plugin
// Modifying the look of the minor axis title
const minorAxisTitlePlugin = {
info: {
name: 'minor-axis-title-plugin',
type: 'component-definition',
},
fn: ({ keys, layout }) => {
const componentDefinition = {
type: 'data-title',
// Provide the same name as the exisiting component to override it
key: keys.COMPONENT.MINOR_AXIS_TITLE,
style: {
fontFamily: 'Tahoma, san-serif',
fontSize: '15px',
},
};
return componentDefinition;
},
};
// Step 2: passing the plugin definition into the render function
// Rendering a line chart with plugins
nuked.render({
element: document.querySelector('#object'),
type: 'sn-line-chart',
plugins: [majorAxisTitlePlugin],
fields: ['Date.autoCalendar.YearMonth', '=Avg(Gold)', '=Avg(Bitcoin)'],
// eslint-disable-next-line no-undef
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
.
// Structure of 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.
// Implement a custom min/max labels plugin, so that we can use it later
// to show the min/max of Bitcoin price since 2018
const minMaxLabelsPluginImplementation = {
info: {
componentName: 'custom-labels-plugin',
name: 'custom-labels-plugin',
type: 'custom-component',
},
fn: ({ keys }) => {
const implementation = {
require: ['chart', 'renderer'],
render() {
// We are only interested in data of Bitcoin after year 2018
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;
},
};
// Using the min/max labels plugin, defined above
const minMaxLabelsPlugin = {
info: {
name: 'labels',
type: 'component-definition',
},
fn: ({ keys }) => {
const componentDefinition = {
// The type has to match with the componentName of the labels plugin definition above
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)
// Modifying the look of the existing line component
const linePlugin = {
info: {
name: 'line-plugin',
type: 'component-definition',
},
fn: ({ layout, keys }) => {
const componentDefinition = {
type: 'line',
// Provide the same name as the exisiting line component to override it
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.