Security News
The Unpaid Backbone of Open Source: Solo Maintainers Face Increasing Security Demands
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.
@elastic/charts
Advanced tools
🚨 WARNING While open source, the intended consumers of this repository are Elastic products. Read the FAQ for details.
This library is a complete rewrite of the current vislib in Kibana and EUISeriesChart in EUI. The rationale behind this refactoring is the need for a testable and decoupled architecture for displaying data within charts. The current EUI implementation is based on ReactVis, which directly manipulates the data series inside components without a clear rendering pipeline and without a clean way to extend it. Some of the downsides of using ReactVis are:
This new implementation revisits the concept of a charting library and tries to apply a unidirectional rendering flow to the concept of charting. The rendering flow is the following:
This controlled flow allows us to achieve the following points:
The rendering pipeline is achieved by revisiting the way a chart library is built. Instead of creating a chart library around a set of rendering components: bar series, axis etc., this new implementation decouples the specification of the chart from the rendering components. The rendering components are part of the internals of the library. We are exposing empty
react components to the developer, using the JSX format just as a declarative language to describe the specification of your chart and not as a set of real react components that will render something.
That is achieved using the following render function on the main Chart
component:
<Provider chartStore={this.chartSpecStore}>
<Fragment>
<SpecsParser>{this.props.children}</SpecsParser>
<ChartResizer />
{renderer === 'svg' && <SVGChart />}
{renderer === 'canvas' && <CanvasChart />}
{renderer === 'canvas_native' && <NativeChart />}
<Tooltips />
</Fragment>
</Provider>
Where all the children passed are rendered inside the SpecsParser
, that signal a state manager that we are updating the specification of the chart, but doesn't render anything.
The actual rendering is done by one of the rendered like the ReactChart
that is rendered after the rendering pipeline produced and saved the geometries on the state manager.
A spec can be something like the following:
<Chart renderer={renderer}>
<Settings rotation={rotation} animateData={true} />
<Axis id={getAxisId('bottom')} position={AxisPosition.Bottom} title={`Rendering test`} />
<Axis id={getAxisId('left')} position={AxisPosition.Left} />
<LineSeries
id={getSpecId('1')}
yScaleType={ScaleType.Linear}
xScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
data={BARCHART_1Y0G}
/>
<BarSeries
id={getSpecId('2')}
yScaleType={ScaleType.Linear}
xScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y1', 'y2']}
splitSeriesAccessors={['g']}
stackAccessors={['x', 'g']}
data={BARCHART_2Y1G}
/>
</Chart>
Fork, then clone the elastic-chart
repo and change directory into it
git clone git@github.com:<YOUR_GITHUB_NAME>/elastic-charts.git elastic-charts
cd kibana
Install the latest version of yarn
We depend upon the version of node defined in .nvmrc.
You will probably want to install a node version manager. nvm is recommended.
To install and use the correct node version with nvm
:
nvm install
Install all the dependencies
yarn install
We develop using storybook to document API, edge-cases, and usage of the library. A hosted version is available at https://elastic.github.io/elastic-charts. You can run locally at http://localhost:9001/ by running:
yarn storybook
note: there is no published package on NPM at the moment (30/01/2018). Will be part of the Roadmap #1.
To install the Elastic Charts into an existing project, use the yarn
CLI (npm
is not supported).
yarn add @elastic/charts
We are trying to enforce some good practices in this library:
dev
branch and then merge on master periodically.The following tools are used to ensure this convention:
commitlint
hook ensure that you are following correctly the conventionyarn cz
can be used to start commitizen
as a cli tool that prompts you with selections and questions
to help you in writing a conventional commitcommitlint-bot
is a github app that checks PR commits to help you on writing the correct commit message (not currently enabled on github)The concept of an axis in this library follow the following constraints:
As a constraint, we allow only one X-axis, but we provide the ability to add multiple Y-axes (also if it's a discouraged practice (see https://blog.datawrapper.de/dualaxis/ or http://www.storytellingwithdata.com/blog/2016/2/1/be-gone-dual-y-axis)).
Related to a dataset is the extent of a variable. It usually used to draw the position of the specific value/datum along one axis (vertical or horizontal). On a series chart, we always need to have at least two domains, representing the 2 dimensions of the data we are drawing.
It's an array of values, that will be used to compute the chart. Usually, each element must have at least 2 values to be charted. Multiple values can be used to specify how we want to split the chart by series and by y values.
Examples of datasets:
// 1 metric (y) and no groups/split series ===> 1 single series
const BARCHART_1Y0G = [{ x: 0, y: 1 }, { x: 1, y: 2 }, { x: 2, y: 10 }, { x: 3, y: 6 }];
// 2 metrics (2y) and 1 group/split series ===> 4 different data series
const BARCHART_2Y1G = [
{ x: 0, g: 'a', y1: 1, y2: 4 },
{ x: 0, g: 'b', y1: 3, y2: 6 },
{ x: 1, g: 'a', y1: 2, y2: 1 },
{ x: 1, g: 'b', y1: 2, y2: 5 },
{ x: 2, g: 'a', y1: 10, y2: 5 },
{ x: 2, g: 'b', y1: 3, y2: 1 },
{ x: 3, g: 'a', y1: 7, y2: 3 },
{ x: 3, g: 'b', y1: 6, y2: 4 },
];
These datasets can be used as input for any type of chart specification. These are the interfaces that make up a BasicSpec
(some sort of abstract specification)
export interface SeriesSpec {
/* The ID of the spec, generated via getSpecId method */
id: SpecId;
/* The ID of the spec, generated via getGroupId method, default to __global__ */
groupId: GroupId;
/* An array of data */
data: Datum[];
/* If specified, it constrant the x domain to these values */
xDomain?: Domain;
/* If specified, it constrant the y Domain to these values */
yDomain?: Domain;
/* The type of series you are looking to render */
seriesType: 'bar' | 'line' | 'area' | 'basic';
}
export interface SeriesAccessors {
/* The field name of the x value on Datum object */
xAccessor: Accessor;
/* An array of field names one per y metric value */
yAccessors: Accessor[];
/* An array of fields thats indicates the datum series membership */
splitSeriesAccessors?: Accessor[];
/* An array of fields thats indicates the stack membership */
stackAccessors?: Accessor[];
/* An optional array of field name thats indicates the stack membership */
colorAccessors?: Accessor[];
}
export interface SeriesScales {
/* The x axis scale type */
xScaleType: ScaleType;
/* The y axis scale type */
yScaleType: ScaleContinuousType;
/** if true, the min y value is set to the minimum domain value, 0 otherwise */
yScaleToDataExtent: boolean;
}
A BarSeriesSpec
for example is the following union type:
export type BarSeriesSpec = SeriesSpec &
SeriesAccessors &
SeriesScales & {
seriesType: 'bar';
};
A chart can be feed with data in the following ways:
data
props configured.data
props configured. In these case the data arrays are merged together as the following rules:
xScaleType
s, the main x scale type is coerced to ScaleType.Linear
if all the scales are continuous or to ScaleType.Ordinal
if one scale type is ordinal. Also, a temporal scale is, in specific cases, coerced to linear, so be careful to configure correctly the scales.splitAccessors
are split into different series. Each specification is treated in a separated manner: if you have one chart with 3 series merged to one chart with 1 series, this results in a chart that has each x value split in two (the number of specification used, two charts) than on split is used to accommodate 3 series and the other to accommodate the remaining series. If you want to treat each series in the same way, split your chart before and create 4 different BarSeries specs, so that these are rendered evenly on the x-axis.stackAccessor
are stacked together each stacked above their respective group (areas with areas, bars with bars, lines with lines. You cannot mix stacking bars above lines above areas).stackAccessors
are clustered together for the same x valuestackAccessors
are just drawn each one on their own layer (not stacked nor clustered).groupId
. For e.g. two bar charts, and two y-axes, each for a spec, one per bar value. The rendered bar heights are independent of each other, because of the two axes.On the current Visualize Editor
, you can stack or cluster in the following cases:
Small multiples are created using the <SmallMultiples>
component, that takes multiple <SplittedSeries>
component with the usual element inside. <SplittedSeries>
can contain only BarSeries
AreaSeries
and LineSeries
Axis and other configuration need to be configured outside the SplittedSeries
element.
In the case of small multiples, each SplittedSeries
computes its own x and y domains. Then the x domains are merged and expanded. The same happens with the main Y domains; they are merged together.
Each data series can have its own color.
The color is assigned through the colorAccessors
prop that specifies which data attributes are used to define the color,
for example:
colorAccessors
.colorAccessors
colorAccessors
will have only 3 colors.colorAccessors
is specified, splitAccessors
will be used to identify how to coloring the seriesApache Licensed. Read the FAQ for details.
FAQs
Elastic-Charts data visualization library
The npm package @elastic/charts receives a total of 32,585 weekly downloads. As such, @elastic/charts popularity was classified as popular.
We found that @elastic/charts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Solo open source maintainers face burnout and security challenges, with 60% unpaid and 60% considering quitting.
Security News
License exceptions modify the terms of open source licenses, impacting how software can be used, modified, and distributed. Developers should be aware of the legal implications of these exceptions.
Security News
A developer is accusing Tencent of violating the GPL by modifying a Python utility and changing its license to BSD, highlighting the importance of copyleft compliance.