Not just applicable to Column Series, but also Error Bars Series, Candlestick and OHLC Series, the dataPointWidth and dataPointWidthMode properties allow controlling of spacing of bars on a 2D JavaScript Chart.
In previous articles we've shown how dataPointWidth can be used to change the width of bar-style series, for example Columns, Error Bars and Candlesticks/OHLC.
By default, dataPointWidth sets the width of columns/bars as a fraction of available space, with valid values from 0.0 - 1.0.
New to SciChart.js v3.4 and above, a new property dataPointWidthMode has been added. This has values of Absolute, Range and Relative. These define how the dataPointWidth is interpreted on these series types:
| EDataPointWidthMode.Absolute | Interprets Data Point Width as an absolute pixel value |
| EDataPointWidthMode.Range | Interprets Data Point Width as the x data range per column. This is useful if you are plotting sparse columns on a NumericAxis |
| EDataPointWidthMode.Relative | Interprets Data Point Width as a relative to the full width which is axis length / number of columns. This assumes that there are no gaps in the data. If you are plotting sparse columns on a NumericAxis, consider Range mode |
Here's an example of their use below. They can be very useful to change how sparsely populated column series behave.
Given a dataset with sparse values like this:
And three column series with different dataPointWidthModes:
The result is the following output:
<div id="scichart-root"></div>
body {
margin: 0;
}
#scichart-root {
width: 100%;
height: 100vh;
}
async function simpleColumnChart(divElementId) {
// Demonstrates how to create a Column chart with SciChart.js
const {
SciChartSurface,
NumericAxis,
FastColumnRenderableSeries,
XyDataSeries,
SciChartJsNavyTheme,
EDataPointWidthMode,
RightAlignedOuterVerticallyStackedAxisLayoutStrategy,
NumberRange,
EXyDirection,
MouseWheelZoomModifier,
ZoomExtentsModifier,
} = SciChart;
// or, for npm, import { SciChartSurface, ... } from "scichart"
const { wasmContext, sciChartSurface } = await SciChartSurface.create(
divElementId,
{
theme: new SciChartJsNavyTheme(),
title: "Column Chart with DataPointWidthModes",
titleStyle: { fontSize: 20, color: "white" },
}
);
const options = {
axisTitleStyle: { fontSize: 16, color: "white" },
growBy: new NumberRange(0, 0.1),
};
sciChartSurface.xAxes.add(new NumericAxis(wasmContext));
sciChartSurface.yAxes.add(
new NumericAxis(wasmContext, {
axisTitle: "Absolute (8px)",
id: "Absolute",
...options,
})
);
sciChartSurface.yAxes.add(
new NumericAxis(wasmContext, {
axisTitle: "Range (8units)",
id: "Range",
...options,
})
);
sciChartSurface.yAxes.add(
new NumericAxis(wasmContext, {
axisTitle: "Relative (80%)",
id: "Relative",
...options,
})
);
sciChartSurface.layoutManager.rightOuterAxesLayoutStrategy =
new RightAlignedOuterVerticallyStackedAxisLayoutStrategy();
// To make it clearer what's happening, colour the axis backgrounds & borders
const axisColors = ["#50C7E0", "#EC0F6C", "#30BC9A"];
sciChartSurface.yAxes.asArray().forEach((yAxis, index) => {
yAxis.backgroundColor = axisColors[index] + "22";
yAxis.axisBorder = { color: axisColors[index], borderLeft: 1 };
});
// #region ExampleA
// Create some data with gaps
const xValues = [0, 10, 30, 70, 80, 90, 110, 120, 150, 180, 190];
const yValues = [0.2, 0.4, 0.8, 1.5, 2.4, 8.1, 13.7, 6.4, 3.5, 1.4, 0.4];
const dataSeries = new XyDataSeries(wasmContext, { xValues, yValues });
// #endregion
// #region ExampleB
// Create and add three column series to demonstrate the different EDataPointWidthModes
const columnSeries0 = new FastColumnRenderableSeries(wasmContext, {
fill: "#50C7E077",
stroke: "#50C7E0",
strokeThickness: 2,
yAxisId: "Absolute",
dataPointWidthMode: EDataPointWidthMode.Absolute,
// When dataPointWidthMode=Absolute, this is the width of each column in pixels
dataPointWidth: 8,
dataSeries,
});
const columnSeries1 = new FastColumnRenderableSeries(wasmContext, {
fill: "#EC0F6C77",
stroke: "#EC0F6C",
strokeThickness: 2,
yAxisId: "Range",
dataPointWidthMode: EDataPointWidthMode.Range,
// When dataPointWidthMode=Range, this is the width of each column in range units
dataPointWidth: 8,
dataSeries,
});
const columnSeries2 = new FastColumnRenderableSeries(wasmContext, {
fill: "#30BC9A77",
stroke: "#30BC9A",
strokeThickness: 2,
yAxisId: "Relative",
dataPointWidthMode: EDataPointWidthMode.Relative,
// When dataPointWidthMode=Range, this is the width of each column in relative units of available space
dataPointWidth: 0.8,
dataSeries,
});
sciChartSurface.renderableSeries.add(columnSeries0);
sciChartSurface.renderableSeries.add(columnSeries1);
sciChartSurface.renderableSeries.add(columnSeries2);
// #endregion
// Add some interactivity
sciChartSurface.chartModifiers.add(
new MouseWheelZoomModifier({ xyDirection: EXyDirection.XDirection }),
new ZoomExtentsModifier()
);
}
simpleColumnChart("scichart-root");
async function builderExample(divElementId) {
// #region ExampleB
// Demonstrates how to create a Column chart with SciChart.js using the Builder API
const { chartBuilder, ESeriesType, EThemeProviderType, EDataPointWidthMode } =
SciChart;
// or, for npm, import { chartBuilder, ... } from "scichart"
// Create some data with gaps
const xValues = [0, 10, 30, 70, 80, 90, 110, 120, 150, 180, 190];
const yValues = [0.2, 0.4, 0.8, 1.5, 2.4, 8.1, 13.7, 6.4, 3.5, 1.4, 0.4];
const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(
divElementId,
{
surface: { theme: { type: EThemeProviderType.Dark } },
series: [
{
type: ESeriesType.ColumnSeries,
xyData: {
xValues,
yValues,
},
options: {
fill: "rgba(176, 196, 222, 0.5)",
stroke: "rgba(176, 196, 222, 1)",
strokeThickness: 2,
// Use this with sparse data
dataPointWidthMode: EDataPointWidthMode.Range,
// This is now "x range per column"
dataPointWidth: 8,
},
},
],
}
);
// #endregion
}
// Uncomment this to use the builder example //builderExample("scichart-root");
Breaking this down:
EDataPointWidthMode.Relative was the previous default (and only) value prior to v3.4. This would calculate the available space for a column and render each bar as a fraction of that availble space (from 0.0 - 1.0). The problem with this mode was that when x-values were unevenly spaced or the dataset was sparse, then
EDataPointWidthMode.Absolute has been added post v3.4 which renders each bar as a pixel width. This is perfect for handling sparse datasets, except the bar will not scale as the chart is zoomed in or out.
EDataPointWidthMode.Relative has also been added post v3.4. This mode renders each bar as a x-Range, so if the xAxis has a range of 0-200 and you specify a value of 8, then a bar will occupy exactly 8 data units. Using this mode, bars or columns will never overlap.