A Chartist.js plugin to easily add a data crosshair to your charts!
bower install chartist-plugin-crosshaircursor
npm install chartist-plugin-crosshaircursor
yarn add chartist-plugin-crosshaircursor
var noop = function() {};
var defaultOptions = {
wrapChart: function(chart) {
var chartWrapper = document.createElement('div');
chartWrapper.className = "crosshairCursor-wrapper";
chart.container.parentNode.insertBefore(chartWrapper, chart.container);
chartWrapper.appendChild(chart.container);
chartWrapper.style.cursor = 'pointer';
chartWrapper.style.position = 'relative';
return chartWrapper;
},
x: true,
y: true,
click: noop,
hover: noop,
freezeChange: noop,
styles: {
x: {
backgroundColor: '#dedede',
width: '1px',
height: '95%'
},
y: {
backgroundColor: '#dedede',
width: '100%',
height: '1px'
}
}
};
In order for the plugin to work, the chart must be wrapped in a parent element. The default function provided to the wrapChart
option programmatically generates a parent element and wraps the chart for you, which by default is in a div
element with the class name crosshairCursor-wrapper
. If you want to change this behaviour, you can pass in your own chart wrapping function ensuring the parent element is returned.
The crosshair cursor type can be customized to an x-axis cursor, y-axis cursor or a full crosshair cursor spanning both axis. By default, both x
and y
are set to true
, creating a full crosshair. To generate an x-axis cursor, set only x
to true
. To generate a y-axis curusor, set only y
to true
. x
and y
cannot both be set to false
.
The click
option allows you to pass in a custom click function which provides you with two arguments: the crosshairCursor object, which exposes a bunch of functions you can use within the function, and the current data points you are hovered over (if any) at the moment of click. As an example, you can easily write a function that locks the crosshair cursor in place on click if that is the desired behaviour:
click: function(crosshairCursor, chartData) {
crosshairCursor.isFrozen() ? crosshairCursor.unfreeze() : crosshairCursor.freeze()
}
By default, the click
option is an empty function.
The hover
option allows you to pass in a custom function which is executed on mousemove
and allows you to receive any meta data on the data points you're hovered over. Like the click
function, it provides you with two arguments: the crosshairCursor object and the data points you are currently hovered over.
hover: function(crosshairCursor, chartData) {
// custom hover function
}
By default, the hover
option is an empty function.
The freezeChange
option allows you to pass in a custom function which is ran each time the crosshair cursor is frozen or unfrozen. The new frozen status is passed as the function argument and as demonstrated with the click
option example above, the crosshair cursor can be frozen and unfrozen really easily, if that behaviour is required.
freezeChange: function(status) {
// custom function
}
By default, the freezeChange
option is an empty function.
The styles
option is an object that defines the crosshair cursor's styling. You can set the cursor colour using the backgroundColor
attribute for each crosshair cursor type, as well as setting the width and height. If you don't define any styles
, it will default to the following:
styles: {
x: {
backgroundColor: '#dedede',
width: '1px',
height: '95%'
},
y: {
backgroundColor: '#dedede',
width: '100%',
height: '1px'
}
}
create
is executed when the chart is first created on the page. It wraps the chart in a container element and generates the crosshair cursors. You can call this method yourself if you've used the destroy
method below and need to recreate the crosshairCursor functionality.
destroy
unwraps the chart and deletes the crosshair cursors generated on create
. It restores your chart, as if the plugin wasn't in use. You can call create
to re-initialize the plugin setup.
wrapChart
is called within the create
method. If you've passed in your own custom chart wrapping function, it will be called here. if you don't pass in your own custom chart wrapping function, the default function will be used (see wrapChart
part in the Avilable options section above).
show
makes the crosshair cursors visible by css, if they are hidden.
hide
makes the crosshair cursors invisible by css: display: none;
, if they are visible.
reset
unfreezes the chart (if it's frozen) and hides the crosshair cursors.
freeze
freezes the crosshair cursor in place on the chart and calls the freezeChange
function (if the user has passed one into the options object).
unfreeze
unfreezes the crosshair cursor and calls the freezeChange
function (if the user has passed one into the options object).
isFrozen
returns the current frozen status of the chart.
currentPoints
returns a list of chart data points currently hovered over by the crosshair, if there are any.
element
returns the chart parent container, generated by the wrapChart
function. You can set your own event listeners to this element, if desired. For example, you could freeze the chart whenever the letter f gets pressed:
var freezeCursor = function(){
chart.crosshairCursor.isFrozen() ? chart.crosshairCursor.unfreeze() : chart.crosshairCursor.freeze()
};
chart.crosshairCursor.element().addEventListener('onkeydown', freezeCursor)
var chart = new Chartist.Line('.chart', {
labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
series: [
{
name: 'line',
data: [
{value: 12, meta: {id: 1, title: "First point"}},
{value: 9, meta: {id: 2, title: "Second point"}},
{value: 7, meta: {id: 3, title: "Third point"}},
{value: 9, meta: {id: 4, title: "Fourth point"}},
{value:5, meta: {id: 5, title: "Fifth point"}}
]
}
]
}, {
width: '600px',
height: '300px',
fullWidth: true,
chartPadding: { right: 40 },
plugins: [
Chartist.plugins.crosshairCursor({
x: true,
y: false,
click: function(crosshairCursor, chartData) {
crosshairCursor.isFrozen() ? crosshairCursor.unfreeze() : crosshairCursor.freeze()
},
hover: function(crosshairCursor, chartData) {
// custom hover function
}
})
]});
The data
array that gets passed into the series
option must contain a meta
object. The meta data contained in this object for each data point gets passed into the click
and hover
functions (defined in the options object) as the second argument.
The following events are available for use if needed:
chart.on('crosshairCursor:frozen', function (isFrozen) {
console.log("Chart is frozen?", isFrozen)
}, false);
chart.on('crosshairCursor:hovered', function(highlightedPoints) {
console.log("Highlighted points" highlightedPoints)
}, false);
chart.on('crosshairCursor:click', function(highlightedPoints) {
console.log("Highlighted points" highlightedPoints)
}, false);
.crosshairCursor-wrapper {} // the default chart wrapper class name, if a custom `wrapChart` function is not set
.crosshairCursor-x {} // the x-axis cursor (colour, width and height to be set in the "styles" option object)
.crosshairCursor-y {} // the y-axis cursor (colour, width and height to be set in the "styles" option object)
.ct-point.crosshairCursor-highlight {} // data point class name when the crosshair cursor highlights it
.crosshairCursor-wrapper {
height: 300px;
width: 600px;
}
.crosshairCursor-highlight {
stroke: #FFDA34 // the colour of any highlighted data points
}