Charts using canvas
This script uses HTML canvas to draw scatter charts and line charts (also known as scatter graphs and line graphs). It should be noted that canvas does not allow selection and copying of text, find-in-page, or reading of text with a screen reader, and therefore this script has limited accessibility. However the script was originally intended for personal use in situations where that was not a problem. In cases where accessibility is needed, perhaps seek an alternative option using SVG. Canvas also cannot cope with being resized; zooming is relatively harmless, even if the canvas will look more pixelated, but any changes in dimensions of the canvas will cause its rendering to disappear. If the page dimensions change, and the chart needs to be drawn with different dimensions, the canvas will need to be deleted, and the chart will need to be recreated. Fortunately, this is relatively easy to do. Canvas does, however, allow browsers to easily offer saving or copying of the rendered chart, and most browsers offer this as a feature.
Being made in canvas makes this script relatively fast, and allows it to cope with vast numbers of data points; charts containing several million data points can be rendered in a reasonable amount of time, while an SVG version might be limited to much lower numbers. (In testing, all browsers managed to render 25'000 data points in under a second. Chromium based browsers like Chrome, Vivaldi, Edge and Opera managed to render 10'000'000 data points in under a minute, while Gecko based browsers like Firefox managed it in just 25 seconds.) Turning off the data point symbols can allow it to perform much faster, and cope with even larger data sets.
A major update allowed the script to be much more generic, and therefore beneficial enough to be released for wider use. Enjoy.
To download the script(s), see the script license, and check details like browser compatibility, use the links on the navigation panel at the top of this page.
Simple use
This is an example of how to create a simple chart, whose width will be taken from its parentElement:
<script type="text/javascript">
window.onload = function () {
var parentElement = document.getElementById('chartgoeshere');
var dataSet1 = {
name: 'Oranges',
data: [
{ x: 0.5, y: 17.3 },
{ x: 1.22, y: 31.9 },
{ x: 3.75, y: 52.4 }
]
};
var dataSet2 = {
name: 'Apples',
data: [
{ x: 0.35, y: 15.4 },
{ x: 0.9, y: 37.2 },
{ x: 1.75, y: 45.9 }
]
};
lineChart( parentElement, 'Price', 'Weight', [ dataSet1, dataSet2 ] );
};
</script>
...
<div id="chartgoeshere"></div>
Chart with bands
This is an example of how to create a chart with X and Y bands:
<script type="text/javascript">
window.onload = function () {
var parentElement = document.getElementById('chartgoeshere');
var dataSet1 = {
name: 'Oranges',
data: [
{ x: 0.5, y: 17.3 },
{ x: 1.22, y: 31.9 },
{ x: 3.75, y: 52.4 }
]
};
var dataSet2 = {
name: 'Apples',
data: [
{ x: 0.35, y: 15.4 },
{ x: 0.9, y: 37.2 },
{ x: 1.75, y: 45.9 }
]
};
var xBands = [
{ name: 'Convenient size', start: 0.25, end: 1.25 },
{ name: 'Heavy', start: 1.6, end: 3.75 }
];
var yBands = [
{ name: 'Consumer preference', start: 30, end: 40 },
{ name: 'Best value', start: 44, end: 54 }
];
lineChart( parentElement, 'Price', 'Weight', [ dataSet1, dataSet2 ], null, xBands, yBands );
};
</script>
...
<div id="chartgoeshere"></div>
Chart with second Y axis
The charts can have a second Y axis, displayed to the right of the plot area. This will automatically appear whenever a data set is associated with it, whenever a yBand is associated with it, whenever a dataRelated option uses it, or whenever a yTitle is provided for it. It will not appear in response to any styles being used. It appears when one of the following conditions matches:
- If the yTitle property is an object with its second property set.
- If at least one data set with usable data has its yAxis property set to 'second'.
- If at least one yBand with valid start and end properties has its yAxis property set to 'second'.
- If the ySecondStart option is set to a valid number, 'auto' or 'auto0'.
- If the ySecondEnd option is set to a valid number, 'auto' or 'auto0'.
- If the ySecondGrid option is set to a valid number or 'auto'.
- If the ySecondConverter option is set to an Object.
If one of these causes the second Y axis to appear, but there is no data associated with it, a notification will appear in the console. If there is data associated with the second Y axis, but no data associated with the first Y axis, a notification will appear in the console.
When a second axis is in use, there is nothing automatic to help understand which data set belongs to which axis (just like almost any other charting application). However, there are several approaches that can be used:
- Use the Y axis titles and data set names to show the relationship between data set and axis.
- Set the colours of the axis titles and labels, to match the colours of the data sets that apply to them - this is not hepful for colour blind visitors.
- Set the dash patterns of the data sets and axis grid lines to match each other, perhaps using solid lines for the first Y axis, and dashed lines for the second.
Using a Y axis converter
The ySecondConverter option is designed to allow two separate sets of units and values to be associated with the same data. For example, a chart of temperature could have Celsius on the first Y axis, and Fahrenheit on the second Y axis. A chart of lengths could have feet on the first Y axis, and metres on the second Y axis. In this case, any data set will be associated with both the first Y axis and the second Y axis. Its yAxis property sets which axis to use for scale when drawing the chart. So for example, one data set might have its data supplied in Celsius, and another data set might have its data supplied in Fahrenheit, but once rendered, the data relates to both Y axes at the same time. It is even possible to have a negative ratio, so that a chart could, for example, show the distance from an origin, and the proximity to a destination, at the same time. In this case, the second Y axis will have its labels counting in reverse.
When using a Y axis converter, an offset and a ratio can optionally be supplied. When converting data values or axis limits from the first Y axis to the second Y axis, the offset will be subtracted, then the result will be multiplied by the ratio. When converting data values from the second Y axis to the first Y axis, the value will be divided by the ratio, then the offset will be added to the result. This will always make it possible to apply linear conversions, but if using a conversion formula that is specified in a different order, you might need to rearrange the formula to allow the operations to be performed in that order. The offset can be thought of as the number on the first Y axis that will correspond to 0 on the second Y axis. A change of 1 on the first Y axis corresponds to a change of ratio on the second Y axis.
When using the ySecondConverter option, the ySecondStart and ySecondEnd options cannot be used. The limits are taken from the first Y axis instead.
The following can be used to show data in both Fahrenheit on the first Y axis, and Celsius on the second Y axis. The formula to convert between Celsius and Fahrenheit is: °F = °C * ( 9 / 5 ) - 32
options.dataRelated.ySecondConverter = {
offset: 32,
ratio: 0.5555555555555556
};
Or the same could be done using fractions to make it easier to understand:
options.dataRelated.ySecondConverter = {
offset: 32,
ratio: 5 / 9
};
Or to have Celsius on the first Y axis and Fahrenheit on the second:
options.dataRelated.ySecondConverter = {
offset: -17.77777777777778,
ratio: 1.8
};
Or the same could be done using fractions to make it easier to understand:
options.dataRelated.ySecondConverter = {
offset: -32 * 5 / 9,
ratio: 9 / 5
};
Creating a chart
The script provides a single function, which creates the charts:
lineChart( parentElement, xTitle, yTitle[, dataSets[, options[, xBands[, yBands]]]] )
- parentElement
- Element: the element where the chart should be placed. The chart's container will be appended to the parentElement. Invalid element references will cause an error to appear in the console, and the function will return null.
- xTitle
- String: the title of the X axis of the chart.
- yTitle
- String: the title of the first and second Y axes of the chart. Using this option does not cause a second Y axis to appear.
- Object: an object with the following properties:
- first
- String: the title of the first Y axis of the chart. If a second Y axis is needed, and the second property of the yTitle object has not been provided, then this title will be used for the second Y axis as well. This property does not cause a second Y axis to appear.
- second (optional)
- String: the title of the second Y axis of the chart. If this property is provided, then the second Y axis will appear, even if there is no data using it.
- undefined or null: (default) use the first Y axis title as the title of the second Y axis of the chart. Using this option does not cause a second Y axis to appear.
- dataSets (optional)
- Array: the data sets to plot on the chart. An empty array will cause a notification to appear in the console.
- null, undefined or any other value that equates to false: (default) do not draw any data.
- options (optional)
- Object: optional settings to control the display of the chart.
- null, undefined or any unrecognised value: (default) use default options.
- xBands (optional)
- Array: the coloured vertical bands to show on the chart.
- null, undefined or any other value that equates to false: (default) do not draw any vertical bands.
- yBands (optional)
- Array: the coloured horizontal bands to show on the chart.
- null, undefined or any other value that equates to false: (default) do not draw any horizontal bands.
Returns null if the chart could not be drawn. If the browser does not support the required HTML canvas APIs, an error will also appear in the console, and a written notice will appear on the page instead of the chart. The detection is fairly simple, and although the browser may pass the API checks, that does not mean that it can definitely run the rest of the script. It is therefore possible for the script to throw an error in an outdated browser, rather than returning null. If the script was unable to draw the chart because of JavaScript's number limits, a different error will appear in the console.
If the script was successful, it returns an object with the following properties:
- canvas
- Element: a reference to the CANVAS element where the chart is drawn. It is possible to use the standard canvas API methods to draw more content onto this canvas, which will then appear on the chart. However, if hoverTooltip is enabled, and crosshairLineWidth is not set to 0, any additional content will be erased whenever a crosshair is shown or removed. The workingCanvas can be used to make changes persistent, when crosshairs are being used.
- workingCanvas
- Element: a reference to a second CANVAS element which is not appended to the document, provided when hoverTooltip is enabled, and crosshairLineWidth is not set to 0. This is used to draw the chart out of sight, and copy it to the main canvas when drawing or erasing a crosshair. Drawing onto both this canvas and the main canvas element, will ensure that the changes will be kept.
- Undefined: value when hoverTooltip is disabled or crosshairLineWidth is set to 0.
- tooltip
- Element: a reference to the DIV element containing the tooltip markup, provided when hoverTooltip is enabled.
- Undefined: value when hoverTooltip is disabled.
If the script failed, it will append a simple paragraph element with a class of 'linecharterror', to the parentElement, instead of the canvas.
If the parentElement has any styles that can cause its width to collapse, such as display:block, position:absolute or float:left, or being inside a table cell, the chartWidth or plotWidth style options will need to be set explicitly, rather than relying on automatic width calculations.
If the chartWidth and plotWidth options are not being used, a temporary DIV element will be added to the parentElement then removed. That element is used for calculating the available width, so it is very important that any styles that will affect the width of the canvas, such as width, margins, padding and borders (all of which can be used with a canvas), are applied exactly the same way to the DIV element as they will be to the canvas itself. The DIV element will have the following markup:
<div class="linechartcanvas"> </div>
The main chart's canvas will then be appended to the parentElement, with a class of 'linechartcanvas':
<canvas width="..." height="..." class="linechartcanvas" style="cursor: crosshair;"></canvas>
Data sets
The dataSets parameter, if specified, should be an array of data set objects, containing the data and details of the data set. Each data set is a line of data that gets plotted on the chart. These are drawn in the specified order, so the last one specified will be displayed on top if they overlap each other. Data set objects can have the following properties:
- name
- String: the name of the data set. This is displayed in the key below the chart.
- data
- Array: the data points that are used to draw the data line and scatter points. Invalid values or an empty array will cause a notification to appear in the console.
- yAxis (optional)
- String: 'first' to associate this data set with the first Y axis. 'second' to associate this data set with the second Y axis. If this property is set to 'second' and the data set has usable data points, then the second Y axis will appear.
- undefined, null or any unrecognised value: (default) causes this data set to be associated with the first Y axis.
- colour or color (optional)
- String: CSS colour to use for the data line and points. Set to 0 to hide the edge lines. If both the en-GB property (colour) and the en-US property (color) are specified, then the en-GB version will be used.
- undefined, null or any other value that equates to false: (default) a default colour is calculated, with its hue based on the number of data sets.
- lineWidth (optional)
- Positive number: width of data line for this data set, in pixels. Overrides the global dataLineWidth option. Set to 0 to hide the data line so that it becomes a basic scatter chart. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) use the global dataLineWidth option.
- pointSize (optional)
- Positive number: radius of the data point symbols for this data set, in pixels. Overrides the global pointSize option. Set to 0 to hide the data point symbols so that it becomes a basic line chart, which can dramatically improve performance with large data sets. Negative numbers are treated as positive. If symbols are made too large, they can overlap the labels and titles around the edges of the plot area. Enabling xGridTicks, yGridTicks and ySecondGridTicks, can provide a little more space, and so can enlarging the various grid lines.
- undefined, null or any unrecognised value: (default) use the global pointSize option.
- pointSymbol (optional)
- Integer 0-5: says which of the predefined data point symbols to use for this data set. Other numbers will be rounded, made positive and modulo divided by 6. If a pointRenderer is being used, then the number can be any positive integer. Other numbers will be rounded and made positive.
- undefined, null or any unrecognised value: (default) if a pointRenderer is not being used, a predefined data point symbol is selected automatically for the data set (cycling through the 6 predefined symbols in sequence, one for each data set).
- pointRenderer (optional)
- Function: point renderer function that can draw point symbols, instead of using the predefined symbols. Overrides the global pointRenderer option.
- null, undefined or any unrecognised value: (default) use the global pointRenderer option.
- dashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the data line. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the data line. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) uses a solid line for the data line.
- 'no', Boolean false or any other value that equates to false: show the data set in the data key below the chart. Overrides the global dataKeyHidden option.
- 'yes', Boolean true or any value other than 'no' and 'empty' that casts to true: hide the data set in the data key. Overrides the global dataKeyHidden option.
- 'empty': hide the data set in the data key if it has no data. Show the data set in the data key if it has data. Overrides the global dataKeyHidden option.
- undefined or null: (default) use the global dataKeyHidden option.
The data property of a data set object must be an array of data point objects. Data point objects must have the following properties:
- x
- Number: the X (horizontal) value of the data point. When the xType option is set to 'datetime' or 'datetimeutc', this should be a Unix timestamp specified in milliseconds - the standard JavaScript Date object timestamp. When the xType option is set to 'duration', this should be a 0-based time span, specified in milliseconds, such as 60000 to indicate a one minute time value. Invalid values will cause a warning to appear in the console.
- y
- Number: the Y (vertical) value of the data point. Invalid values will cause a warning to appear in the console.
A complete example would look like this:
var dataSets = [ {
name: 'Data set name',
yAxis: 'second',
colour: 'red',
lineWidth: 4,
pointSize: 20,
pointSymbol: 3,
dashPattern: [2,10,2,5],
keyHidden: false,
pointRenderer: function ( context, x, y, pointSize, pointSymbol, dataSetIndex, pointIndex ) {
/* draw a symbol with radius of pointSize */
}
data: [ {
x: 5,
y, -4
}, /* more data points */ ]
}, {
/* details of the second data set */
} ];
Bands
The xBands and yBands parameters, if specified, should be an array of band objects. Each band is a shaded block of colour that gets drawn on the chart. For example, bands might be used to show the normal tidal range on a tide chart, or the sunrise and sunset times on a daily temperature chart. These are drawn in the specified order, so the last one specified will be displayed on top if they overlap each other. Horizontal bands are drawn after vertical bands. Band shading is drawn before any grid lines, so that the grid lines are visible. Band edges are drawn after any grid lines, so that they are visible over any grid lines. Band edges are drawn with one of six dash patterns, to help distinguish between similar coloured bands. Band objects can have the following properties:
- name
- String: the name of the band. This is displayed in the key below the chart.
- start
- Number: the value on the chart where the band starts. This number must be equal to or lower than the end number. Invalid values, or a value higher than the end, will cause a warning to appear in the console.
- end
- Number: the value on the chart where the band ends. This number must be equal to or higher than the start number. Invalid values, or a value lower than the start, will cause a warning to appear in the console.
- yAxis (optional)
- String: 'first' to associate this band with the first Y axis. 'second' to associate this band with the second Y axis. Only used for yBands, ignored for xBands. If this property is set to 'second' and the yBand has valid start and end properties, then the second Y axis will appear.
- undefined, null or any unrecognised value: (default) causes this data set to be associated with the first Y axis. Only used for yBands, ignored for xBands.
- colour or color (optional)
- String: CSS colour to use for the edges of the colour band, and the text of the band's key. If both the en-GB property (colour) and the en-US property (color) are specified, then the en-GB version will be used.
- undefined (or other value that equates to false): (default) a default colour is calculated for the edges of the colour band, and the text of the band's key, with its hue based on the number of bands.
- backgroundColour or backgroundColour (optional)
- String: CSS colour to use for the main block of the colour band. If both the en-GB property (backgroundColour) and the en-US property (backgroundColor) are specified, then the en-GB version will be used.
- undefined (or other value that equates to false): (default) a default colour is calculated for the main block of the colour band, with its hue based on the number of bands.
- lineWidth (optional)
- Positive number: width of the band's edge lines, in pixels. Overrides the global bandLineWidth option. Set to 0 to hide the edge lines. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) use the global bandLineWidth option.
- dashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the band edges. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the band edges. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) select the predefined dash pattern automatically for the band edges (cycling through the 6 predefined dash patterns in sequence).
- 'no', Boolean false or any other value that equates to false: show the band in the band key below the chart. Overrides the global bandKeyHidden option.
- 'yes', Boolean true or any value other than 'no' that casts to true: hide the band in the band key. Overrides the global bandKeyHidden option.
- undefined or null: (default) use the global bandKeyHidden option.
A complete example would look like this:
var yBands = [ {
name: 'Band name',
start: 3,
end: 7,
yAxis: 'first',
colour: '#f0f',
backgroundColour: 'fuchsia',
lineWidth: 2,
dashPattern: 4,
keyHidden: true
}, {
/* details of the second X band */
} ];
Options
The charts support a detailed set of options, which provide a lot of control over the rendering of the chart. The options parameter is specified as an object with the following properties, all of which are optional:
- Object: data related options to exand or restrict the data range, and set the spacing of the X and Y axis grid.
- null (or other value that equates to false): use default options.
- styles (optional)
- Object: style options to control the dimensions of the chart, fonts, font sizes, line widths and dashes, grid lengths and ticks, symbol sizes, colours, and display of the labels and key.
- null (or other value that equates to false): use default options.
- strings (optional)
- Object: strings to use in place of the default strings, to allow translation of the chart.
- null (or other value that equates to false): use default strings.
- dateFormat (optional)
- Object: date format options to control the localisation of dates produced by the chart, when the xType option is set to 'datetime' or 'datetimeutc'.
- null (or other value that equates to false): use default options.
- handlers (optional)
- Object: handler functions to allow further localisation, or custom data point symbols.
- null (or other value that equates to false): use default options.
- interaction (optional)
- Object: interaction options to allow the chart to respond to input devices (eg. mouse).
- null (or other value that equates to false): use default options.
- debug (optional)
- Object: debug options to aid development.
- null (or other value that equates to false): use default options.
Within those sections, there are far more options than you would normally need for a single script, so it is best to include only the ones that you will actually be using, since all options are optional. However, this shows a full set of options, but note that some of these option combinations will cause warnings to appear in the console:
var options = {
dataRelated: {
xType: 'duration',
weekStartDay: 1,
xStart: -123,
xEnd: 'auto0',
yStart: -1,
yEnd: 20,
ySecondStart: 'auto',
ySecondEnd: 120,
xGrid: 'auto',
yGrid: 15,
ySecondGrid: 20,
ySecondConverter: {
offset: 23,
ratio: 123.45
}
},
styles: {
chartWidth: 500,
chartHeight: 750,
plotWidth: 200,
plotHeight: 150,
chartBackgroundColour: 'white',
plotTopColour: '#f99',
plotBottomColour: '#99f',
titleFontSize: 25,
titleFontFamily: 'sans-serif',
xTitleColour: 'red',
yTitleColour: 'red',
ySecondTitleColour: 'blue',
xLabels: 'ends',
yLabels: true,
ySecondLabels: false,
labelFontSize: 12,
labelFontFamily: 'monospace',
xLabelColour: 'green',
yLabelColour: 'green',
ySecondLabelColour: 'blue',
keyFontSize: 12,
keyFontFamily: 'serif',
dataKeyHidden: 'empty',
bandKeyHidden: 'yes',
xGridColour: '#444',
yGridColour: '#444',
ySecondGridColour: 'navy',
xGridZeroColour: 'hsla(50,50%,20%,0.5)',
yGridZeroColour: '#777',
ySecondGridZeroColour: 'black',
xGridLength: '10',
yGridLength: '75',
ySecondGridLength: 'short',
xGridTicks: false,
yGridTicks: true,
ySecondGridTicks: true,
xGridDashPattern: 1,
yGridDashPattern: 0,
ySecondGridDashPattern: [1,10],
xGridZeroDashPattern: [10,1],
yGridZeroDashPattern: [8,2],
ySecondGridZeroDashPattern: [7,3],
pointSize: 15,
dataLineWidth: 2,
bandLineWidth: 3,
gridLineWidth: 4,
crosshairLineWidth: 1,
crosshairDashPattern: [2,2]
},
strings: {
oldBrowser: 'Mae angen i chi diweddaru',
numberLimit: "Mae'r rifau yn rhy anodd",
years: ' - blynyddoedd',
months: ' - misoedd',
weeks: ' - wythnosau',
days: ' - dyddiau',
hours: ' - oriau',
minutes: ' - munudau',
seconds: ' - eiliadau',
milliseconds: ' - milieiliadau',
dataSet: 'Llinell data'
},
dateFormat: {
locales: 'en-GB',
year: 'numeric',
month: 'long',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 'none',
era: 'long',
timeZoneName: 'long'
},
handlers: {
pointRenderer: function ( context, x, y, pointSize, pointSymbol, dataSetIndex, pointIndex ) {
/* do something using canvas operations */
},
xTextReplacer: function ( value, xAxisInfo, yAxisInfo, dataPointInfo ) { return value; },
yTextReplacer: function ( value, xAxisInfo, yAxisInfo, dataPointInfo ) {
if( value == 20 ) {
return 'Text!';
}
return value;
},
ySecondTextReplacer: function ( value, xAxisInfo, yAxisInfo, dataPointInfo ) {
if( dataPointInfo && value > 30 && value < 50 ) {
return 'Untrustworthy';
}
return value;
}
},
interaction: {
hoverTooltip: 10
},
debug: {
time: true
}
};
Data related options
Data related options can be thought of as options that relate to the specific data that is being shown on this specific chart; it is unlikely that these options will be relevant for several different charts at once. The data related options control the displayed data range, and set the spacing of the X and Y axis grid. Most of these settings can be specified separately for the X (horizontal), first Y (vertical) and second Y (also vertical) axes. The X axis has its labels and title below the plot area, and the first Y axis has its labels and title to the left side of the plot area. The second Y axis, when in use, has its labels and title to the right side of the plot area. The X grid lines are the vertical ones that progress along the X axis, and the Y grid lines are the horizontal ones that progress along the Y axis. Data related options are specified as a child object of the options object, with the following properties, all of which are optional:
- 'number', null or any unrecognised value: (default) the data point x values are treated as basic numbers.
- 'duration': the data point x values are treated as times in milliseconds. The X axis stepping is calculated using the most appropriate time-based quantity (years, months, weeks, days, hours, minutes or seconds), and shown as a number of years, months, weeks, days, hours, minutes or seconds as needed. These are based on average lengths, so a day is always 24 hours, a month is always 30.436875 days long, and a year is always 365.4525 days long. The data point x values are scaled accordingly using a divisor, eg. 2629746000 when working in months.
- 'datetime': the data point x values are treated as a Unix timestamp specified in milliseconds - the standard JavaScript Date object timestamp. The X axis stepping is calculated using the most appropriate time-based quantity (years, months, weeks, days, hours, minutes or seconds), with the X axis labels showing as a date or time to the appropriate level of detail. The times are calculated using the user's local timezone, including any daylight savings changes. When using this option, it is important to note that the display of the chart will therefore depend on the user's computer settings, and it will not look the same on everyone's computer. The grid alignment will be different, and the data points may appear to be related to a different time or day.
- 'datetimeutc': the data point x values are treated as a Unix timestamp specified in milliseconds - the standard JavaScript Date object timestamp. The X axis stepping is calculated using the most appropriate time-based quantity (years, months, weeks, days, hours, minutes or seconds), with the X axis labels showing as a date or time to the appropriate level of detail. The times are calculated using the global UTC (~GMT) timezone, without any daylight savings changes. When using this option, the display of the chart does not depend on the user's computer settings, and it will look the same on everyone's computer. The grid alignment will match, and the data points will relate to the same time. However, this will not match the user's timezone, unless they happen to be in the GMT timezone.
- Integer 0-6: says which day of the week to draw grid lines when the xType option is set to 'datetime' or 'datetimeutc', and the grid spacing is weekly. 0 is Sunday, 6 is Saturday. Other numbers will be rounded, made positive and modulo divided by 6. Infinity and negative infinity are not permitted.
- undefined, null or any unrecognised value: (default) uses Sunday as the first day of the week.
- 'auto', null or any unrecognised value: (default) use the lowest data point x value or xBands start value, whichever is lower. The value will then be reduced to line up with the xGrid spacing, if one is used. This is used as the X axis value at the left side of the plot area.
- 'auto0': use the lowest data point x value or xBands start value or 0, whichever is lowest. The value will then be reduced to line up with the xGrid spacing, if one is used. This is used as the X axis value at the left side of the plot area.
- Number: value that should be used as the X axis value at the left side of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. This is given in the same units as the x property of a data point. Infinity and negative infinity are not permitted. Invalid values, or a value higher than the xEnd, will cause a warning to appear in the console.
- 'auto', null or any unrecognised value: (default) use the highest data point x value or xBands end value, whichever is higher. The value will then be increased to line up with the xGrid spacing, if one is used. This is used as the X axis value at the right side of the plot area.
- 'auto0': use the highest data point x value or xBands end value or 0, whichever is highest. The value will then be increased to line up with the xGrid spacing, if one is used. This is used as the X axis value at the right side of the plot area.
- Number: value that should be used as the X axis value at the right side of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. This is given in the same units as the x property of a data point. Infinity and negative infinity are not permitted. Invalid values, or a value lower than the xStart, will cause a warning to appear in the console.
- 'auto', null or any unrecognised value: (default) use the lowest data point y value or yBands start value (for data sets and bands associated with the first Y axis), whichever is lower. The value will then be reduced to line up with the yGrid spacing, if one is used. This is used as the first Y axis value at the bottom of the plot area.
- 'auto0': use the lowest data point y value or yBands start value or 0 (for data sets and bands associated with the first Y axis), whichever is lowest. The value will then be reduced to line up with the yGrid spacing, if one is used. This is used as the first Y axis value at the bottom of the plot area.
- Number: the lowest Y (vertical) value that should be used at the bottom of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. Infinity and negative infinity are not permitted. Invalid values, or a value higher than the yEnd, will cause a warning to appear in the console.
- 'auto', null or any unrecognised value: (default) use the highest data point y value or yBands end value (for data sets and bands associated with the first Y axis), whichever is higher. The value will then be increased to line up with the yGrid spacing, if one is used. This is used as the first Y axis value at the top of the plot area.
- 'auto0': use the highest data point y value or yBands end value or 0 (for data sets and bands associated with the first Y axis), whichever is highest. The value will then be increased to line up with the yGrid spacing, if one is used. This is used as the first Y axis value at the top of the plot area.
- Number: the highest Y (horizontal) value that should be used at the top of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. Infinity and negative infinity are not permitted. Invalid values, or a value lower than the yStart, will cause a warning to appear in the console.
- 'auto', null or any unrecognised value: (default) use the lowest data point y value or yBands start value (for data sets and bands associated with the second Y axis), whichever is lower. The value will then be reduced to line up with the ySecondGrid spacing, if one is used. This is used as the second Y axis value at the bottom of the plot area. Setting this option to 'auto' will cause the second Y axis to appear.
- 'auto0': use the lowest data point y value or yBands start value or 0 (for data sets and bands associated with the second Y axis), whichever is lowest. The value will then be reduced to line up with the ySecondGrid spacing, if one is used. This is used as the second Y axis value at the bottom of the plot area. This is used as the second Y axis value at the bottom of the plot area. Setting this option will cause the second Y axis to appear.
- Number: the lowest Y (vertical) value that should be used at the bottom of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. Infinity and negative infinity are not permitted. Invalid values, or a value higher than the ySecondEnd, will cause a warning to appear in the console. Setting this option will cause the second Y axis to appear.
- 'auto', null or any unrecognised value: (default) use the highest data point y value or yBands end value (for data sets and bands associated with the second Y axis), whichever is higher. The value will then be increased to line up with the ySecondGrid spacing, if one is used. This is used as the second Y axis value value at the top of the plot area. Setting this option to 'auto' will cause the second Y axis to appear.
- 'auto0': use the highest data point y value or yBands end (for data sets and bands associated with the second Y axis), whichever is highest. The value will then be increased to line up with the ySecondGrid spacing, if one is used. This is used as the second Y axis value at the top of the plot area. Setting this option will cause the second Y axis to appear.
- Number: the highest Y (horizontal) value that should be used at the top of the plot area. Can be used to show only a subset of the data, or to extend the chart beyond the data. Infinity and negative infinity are not permitted. Invalid values, or a value lower than the ySecondStart, will cause a warning to appear in the console. Setting this option will cause the second Y axis to appear.
- 'auto', null or any unrecognised value: (default) automatically calculates the best grid spacing, to give a good number of horizontal lines between the left and right sides of the plot area. When the xType option is set to 'datetime' or 'datetimeutc', this will be aligned to the start of the relevant year, month, week, day, hour, minute or second as needed. (Implementation note; there is no year 0 in the standard Gregorian calendar, so the year -1 is treated as year 0 - this means that when working in BCE, the year alignments will be on year numbers offset by -1.) With any other chart type, this will be aligned to 0 (lines will be in multiples of the grid spacing).
- Positive number, non-0: specifies a desired grid spacing for the X axis grid. This will be aligned to 0 (lines will be in multiples of the grid spacing). Negative numbers will be treated as positive. This value cannot be used when xType option is set to 'datetime' or 'datetimeutc', and will be treated as 'auto', which will cause a warning to appear in the console.
- 'none': removes the grid lines, grid ticks and associated grid labels for the X axis. Grid labels will then be shown only at the two ends of the X axis, and will be shown horizontally if there is space.
- 'auto', null or any unrecognised value: (default) automatically calculates the best grid spacing for the first Y axis grid lines, to give a good number of vertical lines between the top and bottom of the plot area. This will be aligned to 0 (lines will be in multiples of the grid spacing).
- Positive number, non-0: specifies a desired grid spacing for the first Y axis grid lines. This will be aligned to 0 (lines will be in multiples of the grid spacing). Negative numbers will be treated as positive.
- 'none': removes the grid lines, grid ticks and associated grid labels for the first Y axis grid. Grid labels will then be shown only at the two ends of the X axis.
- 'auto', null or any unrecognised value: (default) automatically calculates the best grid spacing for the second Y axis grid lines, to give a good number of vertical lines between the top and bottom of the plot area. This will be aligned to 0 (lines will be in multiples of the grid spacing). Setting this option to 'auto' will cause the second Y axis to appear.
- Positive number, non-0: specifies a desired grid spacing for the second Y axis grid lines. This will be aligned to 0 (lines will be in multiples of the grid spacing). Negative numbers will be treated as positive. Setting this option will cause the second Y axis to appear.
- 'none': removes the grid lines, grid ticks and associated grid labels for the second Y axis grid. Grid labels will then be shown only at the two ends of the X axis. Setting this option will not cause the second Y axis to appear, but also will not cause it to disappear; the second Y axis title and end labels will still appear if they were made to appear because of some other option or parameter.
- Object: Setting this option will cause the second Y axis to appear, with its scale taken from the first Y axis. Overrides the ySecondStart and ySecondEnd options; a warning will be issued in the console if they are combined. The object can have the following properties, all of which are optional:
- Number: the number on the first Y axis that will correspond to 0 on the second Y axis. NaN is not a valid value, and will be treated as undefined.
- undefined, null or any other value that equates to false: (default) 0 on the first Y axis corresponds to 0 on the second Y axis.
- Number: the scale of the second Y axis, compared with the first Y axis. A change of 1 on the first Y axis will correspond to a change of ratio on the second Y axis. (Basically, this is a multiplier.) Negative numbers are allowed, and will cause the grid to count in reverse. NaN and 0 are not valid values, and will be treated as undefined.
- undefined, null or any other value that equates to false: (default) the ratio between the first and second Y axes is set to 1.
- null, undefined or any other value that equates to false: (default) the ySecondStart and ySecondEnd options are used instead. Setting this option will not cause the second Y axis to appear.
Style options
Styles can be thought of as a theme that can be used on multiple charts. The size of the chart or plot area can be set. Every type of line can have its colour, thickness and dash pattern controlled. Grid lines can also have their length and ticks controlled. All text can have its colour, size and font controlled. The background colours of the chart area, plot area and bands can be set separately. The size of data point symbols can be controlled. Individual data sets and bands can be controlled separately in their own configuration, but the defaults for many things are controlled globally (everything except the colour and dash patten, since these are used to distinguish between the objects). Axis labels can be hidden and the key can also be hidden either globally, or individual data sets and bands can override te global setting.
Many style options can be set for the X axis, first Y axis and second Y axis separately. Setting styles for second Y axis will not cause the second Y axis to appear. Those styles can effectively be thought of as "if the second Y axis is in use, then style it like this", just like how regular CSS works. The X axis has its labels and title below the plot area, and the first Y axis has its labels and title to the left side of the plot area. The second Y axis, when in use, has its labels and title to the right side of the plot area. The X grid lines are the vertical ones that progress along the X axis, and the Y grid lines are the horizontal ones that progress along the Y axis.
Style options are specified as a child object of the options object, with the following properties, all of which are optional:
- chartWidth (optional)
- Positive integer: the outer width of the chart (and thus the width of the canvas) in pixels. If this width is not enough for at least two X axis labels, then the width is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas width is restricted to the browser's limits. Non-integers will be rounded to the nearest integer. Negative numbers act like 0. Overrides the plotWidth option; a warning will be issued in the console if both are used.
- undefined, null or any unrecognised value: (default) if the plotWidth option is in use, then that will be used instead. If not, then the outer width of the chart (and thus the width of the canvas) is taken as the available (inner) width of the parentElement (not recommended inside elements whose width is taken from its contents, such as positioned or floating elements, or table cells). If this width is not enough for at least two X axis labels, then the width is increased to provide enough space for two labels. This will cause the canvas to overflow the parentElement. The maximum canvas width is restricted to the browser's limits. When using this option, it is important to ensure that the page layout is complete (ie. run the script onload), so that the available width can be accurately measured.
- chartHeight (optional)
- Positive integer: the outer height of the chart (and thus the height of the canvas) in pixels. If this height is not enough for at least two Y axis labels, then the height is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas height is restricted to the browser's limits. Non-integers will be rounded to the nearest integer. Negative numbers act like 0. Overrides the plotHeight option; a warning will be issued in the console if both are used.
- undefined, null or any unrecognised value: (default) if the plotHeight option is in use, then that will be used instead. If not, then the height of the plot area of the chart is taken as 5 / 8 of the width of the plot area of the chart. The height of the padding, X axis title, X axis labels and key are then added on, to work out the height of the canvas. If this height is not enough for at least two Y axis labels, then the height is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas height is restricted to the browser's limits.
- plotWidth (optional)
- Positive integer: the width of the plot area of the chart in pixels. The width of the Y axis titles and labels are then added on, to work out the width of the canvas. If this width is not enough for at least two X axis labels, then the width is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas width is restricted to the browser's limits. Non-integers will be rounded to the nearest integer. Negative numbers act like 0. Cannot be used at the same time as the chartWidth option; a warning will be issued in the console if both are used.
- undefined, null or any unrecognised value: (default) if the chartWidth option is also not used, then the outer width of the chart (and thus the width of the canvas) is taken as the available (inner) width of the parentElement (not recommended inside elements whose width is taken from its contents, such as positioned or floating elements, or table cells). If this width is not enough for at least two X axis labels, then the width is increased to provide enough space for two labels. This will cause the canvas to overflow the parentElement. The maximum canvas width is restricted to the browser's limits. When using this option, it is important to ensure that the page layout is complete (ie. run the script onload), so that the available width can be accurately measured.
- plotHeight (optional)
- Positive integer: the outer height of the chart (and thus the height of the canvas) in pixels. The height of the padding, X axis title, X axis labels and key are then added on, to work out the height of the canvas. If this height is not enough for at least two Y axis labels, then the height is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas height is restricted to the browser's limits. Non-integers will be rounded to the nearest integer. Negative numbers act like 0. Cannot be used at the same time as the chartHeight option; a warning will be issued in the console if both are used.
- undefined, null or any unrecognised value: (default) if the chartHeight option is also not used, then the height of the plot area of the chart is taken as 5 / 8 of the width of the plot area of the chart. The height of the padding, X axis title, X axis labels and key are then added on, to work out the height of the canvas. If this height is not enough for at least two Y axis labels, then the height is increased to provide enough space for two labels. This may cause the canvas to overflow the parentElement. The maximum canvas height is restricted to the browser's limits.
- chartBackgroundColour or chartBackgroundColor (optional)
- String: the background colour of the entire chart. This must be a CSS colour value. While optional, this style option is recommended, because without it, using the browser's context menu to copy an image of the chart will normally give black for the unrendered parts of the chart. If both the en-GB property (chartBackgroundColour) and the en-US property (chartBackgroundColor) are specified, then the en-GB version will be used. Note that when setting this background colour, it will not be used in any padding that has been applied to the canvas with CSS. Therefore, if padding and the chartBackgroundColour option are both used, then the CSS may also need to set the background colour of the canvas element itself, if it is different from the page around it.
- undefined, null or '': (default) sets the colour of the top of the plot area to 'transparent'.
- plotTopColour or plotTopColor (optional)
- String: the colour of the plot area background, at the top of the plot area. This must be a CSS colour value. If both the en-GB property (plotTopColour) and the en-US property (plotTopColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the top of the plot area to 'white'.
- plotBottomColour or plotBottomColor (optional)
- String: the colour of the plot area background, at the bottom of the plot area. This must be a CSS colour value. If both the en-GB property (plotBottomColour) and the en-US property (plotBottomColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the bottom of the plot area to '#eee'.
- titleFontSize (optional)
- Positive integer: the font size of the X and Y axis titles, in pixels. Negative numbers act like positive numbers. Non-integers are rounded. Infinity, 0 and invalid numbers act like undefined.
- undefined, null, 0 or any unrecognised value: (default) sets the font size of the X and Y axis titles to 20.
- titleFontFamily (optional)
- String: the font family of the X and Y axis titles. This must be a CSS font family.
- undefined, null or '': (default) sets the font family of the X and Y axis titles to 'serif'.
- xTitleColour or xTitleColor (optional)
- String: the colour of the X axis title. This must be a CSS colour value. If both the en-GB property (xTitleColour) and the en-US property (xTitleColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the X axis title to 'black'.
- yTitleColour or yTitleColor (optional)
- String: the colour of the first Y axis title. This must be a CSS colour value. If both the en-GB property (xTitleColour) and the en-US property (yTitleColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the first Y axis title to 'black'.
- ySecondTitleColour or ySecondTitleColor (optional)
- String: the colour of the second Y axis title. This must be a CSS colour value. If both the en-GB property (ySecondTitleColour) and the en-US property (ySecondTitleColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the second Y axis title to 'black'.
- labelFontSize (optional)
- Positive integer: the font size of the X and Y axis labels, in pixels. This also sets the size of the padding around the plot area of the chart, which is made big enough to allow the labels not to intersect. Negative numbers act like positive numbers. Non-integers are rounded. Infinity, 0 and invalid numbers act like undefined.
- undefined, null, 0 or any unrecognised value: (default) sets the font size of the X and Y axis labels to 16.
- labelFontFamily (optional)
- String: the font family of the X and Y axis labels. This must be a CSS font family.
- undefined, null or '': (default) sets the font family of the X and Y axis labels to 'serif'.
- xLabels (optional)
- 'on', Boolean true or any unrecognised value: (default) show labels for the X axis grid lines. These will be selectively omitted if there is not enough space to draw them, but even in extreme cases, at least two X axis labels will always be drawn. If there are not enough grid lines to allow for two labels to be shown, then an additional label will be added at one end of the axis. Labels will be rotated vertically if xGrid is not set to 'none'. If xGrid is set to 'none' then this will act exactly like 'ends'.
- 'ends': removes the grid labels associated with X axis grid lines, and shows grid labels only at the two ends of the X axis. These will be shown horizontally if there is space, or rotated vertically if not.
- 'off' or Boolean false: grid labels are not shown on the X axis for any values.
- yLabels (optional)
- 'on', Boolean true or any unrecognised value: (default) show labels for the first Y axis grid lines. These will be selectively omitted if there is not enough space to draw them, but even in extreme cases, at least two first Y axis labels will always be drawn. If there are not enough grid lines to allow for two labels to be shown, then an additional label will be added at one end of the axis.
- 'off' or Boolean false: grid labels are not shown on the first Y axis for any values.
- ySecondLabels (optional)
- 'on', Boolean true or any unrecognised value: (default) show labels for the second Y axis grid lines. These will be selectively omitted if there is not enough space to draw them, but even in extreme cases, at least two second Y axis labels will always be drawn. If there are not enough grid lines to allow for two labels to be shown, then an additional label will be added at one end of the axis. The exception here is that when using the ySecondConverter option when the ySecondGrid option not set to 'none', the script will not place labels at the ends of the axis, since that could cause unwanted gaps in other situations. If using the ySecondConverter option, ensure that the grid spacing and chart size will allow enough labels to appear. Using this value will not cause the second Y axis to appear.
- 'off' or Boolean false: grid labels are not shown on the second Y axis for any values.
- xLabelColour or xLabelColor (optional)
- String: the colour of the X axis labels. This must be a CSS colour value. If both the en-GB property (xLabelColour) and the en-US property (xLabelColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the X axis labels to 'black'.
- yLabelColour or yLabelColor (optional)
- String: the colour of the first Y axis labels. This must be a CSS colour value. If both the en-GB property (yLabelColour) and the en-US property (yLabelColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the first Y axis labels to 'black'.
- ySecondLabelColour or ySecondLabelColor (optional)
- String: the colour of the second Y axis labels. This must be a CSS colour value. If both the en-GB property (ySecondLabelColour) and the en-US property (ySecondLabelColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the second Y axis labels to 'black'.
- keyFontSize (optional)
- Positive integer: the font size of the data and band key below the chart, in pixels. Negative numbers act like positive numbers. Non-integers are rounded. Infinity, 0 and invalid numbers act like undefined.
- undefined, null, 0 or any unrecognised value: (default) sets the font size of the data and band key to 16.
- keyFontFamily (optional)
- String: the font family of the data and band key below the chart. This must be a CSS font family.
- undefined, null or '': (default) sets the font family of the data and band key to 'serif'.
- keyColour or keyColor (optional)
- String: the colour of the data and band key. This must be a CSS colour value. If both the en-GB property (keyColour) and the en-US property (keyColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the data and band key to 'black'.
- 'no', Boolean false, undefined, null or any other value that casts to false: (default) show the data key below the chart.
- 'yes', Boolean true or any value other than 'no' and 'empty' that casts to true: hide the data key.
- 'empty': hide data sets in the data key if they have no data. Show data sets in the data key if they have data.
- 'no', Boolean false, undefined, null or any other value that casts to false: (default) show the band key below the chart.
- 'yes', Boolean true or any value other than 'no' that casts to true: hide the band key.
- xGridColour or xGridColor (optional)
- String: the colour of the normal X axis grid lines. This must be a CSS colour value. If both the en-GB property (xGridColour) and the en-US property (xGridColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the normal X axis grid lines to '#ccc'.
- yGridColour or yGridColor (optional)
- String: the colour of the normal first Y axis grid lines. This must be a CSS colour value. If both the en-GB property (yGridColour) and the en-US property (yGridColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the normal first Y axis grid lines to '#ccc'.
- ySecondGridColour or ySecondGridColor (optional)
- String: the colour of the normal second Y axis grid lines. This must be a CSS colour value. If both the en-GB property (ySecondGridColour) and the en-US property (ySecondGridColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the normal second Y axis grid lines to '#ccc'.
- xGridZeroColour or xGridZeroColor (optional)
- String: the colour of the 0 valued X axis grid line. This must be a CSS colour value. If both the en-GB property (xGridZeroColour) and the en-US property (xGridZeroColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the 0 valued X and Y axis grid lines to 'black'.
- yGridZeroColour or yGridZeroColor (optional)
- String: the colour of the 0 valued first Y axis grid line. This must be a CSS colour value. If both the en-GB property (yGridZeroColour) and the en-US property (yGridZeroColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the 0 valued first Y axis grid lines to 'black'.
- ySecondGridZeroColour or ySecondGridZeroColor (optional)
- String: the colour of the 0 valued second Y axis grid line. This must be a CSS colour value. If both the en-GB property (ySecondGridZeroColour) and the en-US property (ySecondGridZeroColor) are specified, then the en-GB version will be used.
- undefined, null or '': (default) sets the colour of the 0 valued second Y axis grid lines to 'black'.
- xGridLength (optional)
- Number 0-100: the length of the X axis grid lines, in percentage of the chart's plot area height. Numbers are constrained between 0 and 100. Lines are drawn touching the bottom of the Y axis, so for numbers lower than 100, the gap will be at the top.
- 'short': sets the length of the X axis grid lines the the same as the labelFontSize.
- undefined, null or any unrecognised value: (default) sets the length of the X axis grid lines to the full height of the chart's plot area.
- yGridLength (optional)
- Number 0-100: the length of the first Y axis grid lines, in percentage of the chart's plot area width. Numbers are constrained between 0 and 100. Lines are drawn touching the left side of the X axis, so for numbers lower than 100, the gap will be on the right.
- 'short': sets the length of the first Y axis grid lines the the same as the labelFontSize.
- undefined, null or any unrecognised value: (default) sets the length of the first Y axis grid lines to the full width of the chart's plot area.
- ySecondGridLength (optional)
- Number 0-100: the length of the second Y axis grid lines, in percentage of the chart's plot area width. Numbers are constrained between 0 and 100. Lines are drawn touching the right side of the X axis, so for numbers lower than 100, the gap will be on the left.
- 'short', undefined, null or any unrecognised value: (default) sets the length of the second Y axis grid lines the the same as the labelFontSize.
- xGridTicks (optional)
- Boolean: false, undefined, null or any other value that casts to false (default) to hide grid ticks, true to show grid ticks at the bottom of the X axis grid lines, pointing towards the X axis labels.
- yGridTicks (optional)
- Boolean: false, undefined, null or any other value that casts to false to hide grid ticks, true to show grid ticks at the left end of the first Y axis grid lines, pointing towards the first Y axis labels.
- undefined or null: (default) when a second Y axis is in use, this defaults to true. When a second Y axis is not in use, this defaults to false.
- ySecondGridTicks (optional)
- Boolean: false, undefined, null or any other value that casts to false to hide grid ticks, true to show grid ticks at the left end of the second Y axis grid lines, pointing towards the second Y axis labels.
- undefined or null: (default) when a second Y axis is in use, this defaults to true. When a second Y axis is not in use, this defaults to false.
- xGridDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the normal X axis grid lines. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the normal X axis grid lines. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the normal X axis grid lines.
- yGridDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the normal first Y axis grid lines. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the normal first Y axis grid lines. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the normal first Y axis grid lines.
- ySecondGridDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the normal second Y axis grid lines. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the normal second Y axis grid lines. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the normal second Y axis grid lines.
- xGridZeroDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the 0 valued X axis grid line. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the 0 valued X axis grid line. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the 0 valued X axis grid lines.
- yGridZeroDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the normal 0 valued Y axis grid line. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the 0 valued first Y axis grid line. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the 0 valued first Y axis grid line.
- ySecondZeroGridDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the 0 valued second Y axis grid line. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the 0 valued second Y axis grid line. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the normal 0 valued Y axis grid lines.
- pointSize (optional)
- Positive number: radius of the data point symbols for all data sets, in pixels. Set to 0 to hide the data point symbols so that it becomes a basic line chart, which can dramatically improve performance with large data sets. This option also influences the size of the padding around the plot area of the chart, which is made big enough to allow the symbols not to fall off the edge of the canvas. If symbols are made too large, they can overlap the labels and titles around the edges of the plot area. Enabling xGridTicks, yGridTicks and ySecondGridTicks, can provide a little more space, and so can enlarging the various grid lines.
- undefined, null or any unrecognised value: (default) uses 5 as the radius of the data point symbols for all data sets.
- dataLineWidth (optional)
- Positive number: width of data lines. Set to 0 to hide data lines, so that it becomes a basic scatter chart. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) data line width is set to 1.
- bandLineWidth (optional)
- Positive number: width of band edge lines. Set to 0 to hide band edge lines. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) band edge line width is set to 1.
- gridLineWidth (optional)
- Positive number: width of X and Y axis grid lines. Set to 0 to hide grid lines; this does not cause the grid labels to disappear though. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) grid line width is set to 1.
- crosshairLineWidth (optional)
- Positive number: width of data point hover crosshair lines, shown only when the hoverTooltip option is enabled. Set to 0 to hide crosshair. Negative numbers are treated as positive.
- undefined, null or any unrecognised value: (default) data point hover crosshair line width is set to 1, shown only when the hoverTooltip option is enabled.
- crosshairDashPattern (optional)
- Integer 0-5: says which of the predefined dash patterns to use for the data point hover crosshair lines, shown only when the hoverTooltip option is enabled. Other numbers will be rounded, made positive and modulo divided by 6.
- Array: array of numbers, specifying the canvas dash pattern segments to use for the data point hover crosshair lines, shown only when the hoverTooltip option is enabled. Numbers are specified in pixel lengths, with odd indexes saying how many pixels to draw, and even indexes saying how many pixels to leave as a gap. Dash patterns are not checked for validity.
- undefined, null or any unrecognised value: (default) use a solid line for the data point hover crosshair lines, shown only when the hoverTooltip option is enabled.
Strings
Static strings can be changed using a simple option. Dynamic strings, such as numbers and axis labels, may need the user of a text replacer function, a type of handler function. String options are specified as a child object of the options object, with the following properties, all of which are optional:
- oldBrowser (optional)
- String: a message saying that the browser is too old to support basic canvas functionality.
- undefined, null or any unrecognised value: (default) use the default string.
- numberLimit (optional)
- String: a message saying that the chart needed numbers with higher precision than JavaScript can cope with, and the script failed to limit it correctly.
- undefined, null or any unrecognised value: (default) use the default string.
- years (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in years.
- undefined, null or any unrecognised value: (default) use the default string ' (years)'.
- months (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in months.
- undefined, null or any unrecognised value: (default) use the default string ' (months)'.
- weeks (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in weeks.
- undefined, null or any unrecognised value: (default) use the default string ' (weeks)'.
- days (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in days.
- undefined, null or any unrecognised value: (default) use the default string ' (days)'.
- hours (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in hours.
- undefined, null or any unrecognised value: (default) use the default string ' (hours)'.
- minutes (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in minutes.
- undefined, null or any unrecognised value: (default) use the default string ' (minutes)'.
- seconds (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in seconds.
- undefined, null or any unrecognised value: (default) use the default string ' (seconds)'.
- milliseconds (optional)
- String: words to add to the end of the X axis title when the xType option is set to duration, and the X axis stepping is in milliseconds.
- undefined, null or any unrecognised value: (default) use the default string ' (ms)'.
- dataSet (optional)
- String: title of the data set column in the data point tooltip.
- undefined, null or any unrecognised value: (default) use the default string 'Data set'.
Date format options
When the xType option is set to 'datetime' or 'datetimeutc', the script displays dates and times in X axis labels and tooltips. It uses Intl.DateTimeFormat in modern browsers to produce the date and time as a string, falling back to basic non-localised output in older browsers. Intl.DateTimeFormat translates dates into the format suggested by the user's locale, so that each user can understand the date and time as it is presented to them. It offers a lot of customisation options, such as whether the month name should be spelled out as text, or whether the month should be given only as a number. Date options can be specified as a child object of the options object, with the following properties, that all accept the same values as the same named properties of Intl.DateTimeFormat itself, all of which are optional:
- locales (optional)
- String: the locales string that sets the language/locale of the date output. This can be used to translate the output, as well as specifying the locale format.
- Array of strings: a set of locales strings that can be used as fallback locales, to set the language/locale of the date output. This can be used to translate the output, as well as specifying the locale format.
- undefined, null or empty array: (default) use the user's own locale.
- year (optional)
- String: the format to use for the year portion of a date string.
- 'none': do not show the year.
- undefined or null: (default) use the default year option 'numeric'.
- month (optional)
- String: the format to use for the month portion of a date string.
- 'none': do not show the month.
- undefined or null: (default) use the default month option 'short' when working in months, or '2-digit' otherwise.
- day (optional)
- String: the format to use for the day portion of a date string.
- 'none': do not show the day.
- undefined or null: (default) use the default day option '2-digit'.
- hour (optional)
- String: the format to use for the hour portion of a date string.
- 'none': do not show the hours.
- undefined or null: (default) use the default hour option '2-digit'.
- minute (optional)
- String: the format to use for the minute portion of a date string.
- 'none': do not show the minutes.
- undefined or null: (default) use the default minute option '2-digit'.
- second (optional)
- String: the format to use for the second portion of a date string.
- 'none': do not show the seconds.
- undefined or null: (default) use the default second option '2-digit'.
- fractionalSecondDigits (optional)
- Integer 0-3: the number of digits to use for the millisecond portion of a date string.
- 'none': do not show the milliseconds (equivalent to setting the value to 0).
- undefined or null: (default) use the default second option 3.
- era (optional)
- String: the format to use for the era (BCE/CE) of a date string.
- 'none': do not show the era.
- undefined or null: (default) use the default era option 'short' when at least one data point is before year 1, and omit it otherwise.
- timeZoneName (optional)
- String: the format to use for the timezone of a date string.
- 'none': do not show the timezone.
- undefined or null: (default) use the default timeZoneName option 'short'.
Handler functions
Handler functions are functions that will be called whenever a certain task needs to be done. Handler function options can be specified as a child object of the options object, with the following properties, all of which are optional:
- pointRenderer (optional)
- Function: point renderer function that can be used to draw custom data point symbols, instead of using the predefined ones.
- null, undefined or any unrecognised value: (default) use the predefined data point symbols.
- xTextReplacer (optional)
- Function: text replacer function that can be used to perform more localisation of generated numbers, add units to data point tooltip x values, or show words instead of numbers as the X axis labels.
- null, undefined or any unrecognised value: (default) use the standard generated text for data point tooltip x values, and the X axis labels.
- yTextReplacer (optional)
- Function: text replacer function that can be used to perform more localisation of generated numbers, add units to data point tooltip y values for data points associated with the first Y axis, or show words instead of numbers as the first Y axis labels.
- null, undefined or any unrecognised value: (default) use the standard generated text for data point tooltip y values, and the first Y axis labels.
- ySecondTextReplacer (optional)
- Function: text replacer function that can be used to perform more localisation of generated numbers, add units to data point tooltip y values for data points associated with the second Y axis, or show words instead of numbers as the second Y axis labels. Setting this option will not cause the second Y axis to appear.
- null, undefined or any unrecognised value: (default) use the standard generated text for data point tooltip y values, and the second Y axis labels.
Interaction options
Interaction options to allow the chart to respond to input devices, such as a mouse. Interaction options can be specified as a child object of the options object, with the following properties, all of which are optional:
- hoverTooltip (optional)
- Boolean: false, undefined, null or any other value that casts to false (default) not to show a tooltip when hovering a data point. true or any non-numeric value that casts to true to show a tooltip when the mouse hovers over a data point. The reaction radius is set to the pointSize for each data point.
- Number: show a tooltip when the mouse hovers over a data point, and enlarge the reaction radius over a data point by the specified number of pixels. This can be used to make targeting easier when using a touchscreen, and makes it possible to use the effect when the pointSize is set to 0. Negative numbers are allowed. 0 will act like
Boolean false.
When a hoverTooltip is enabled, hovering the mouse over any data points will cause a tooltip to be displayed, and a crosshair to appear, showing the position of the data point. In many touchscreen browsers, tapping on the data point will also cause them to be displayed, but this will depend on the touchscreen browser. It selects the nearest data point from every data set that is within the specified reaction radius, so the tooltip could contain details from multiple data sets if they are all within the reaction radius. The tooltip is created as a DIV element containing a table of the data point data. The DIV element is appended to the document root (the HTML element), not the BODY, since this allows the BODY to be positioned. (They are not put inside the container, since that would cause subsequent charts to overlap the tooltip.)
The DIV is given a class of 'linecharttooltip', which can be used to style the tooltip. If the parentElement has an ID, then this is used to construct a second class for the DIV, appended to 'linecharttooltip'. So for example, if the parentElement has an ID of 'foo', the tooltip DIV would have to classes, 'linecharttooltip' and 'linecharttooltipfoo'. This allows charts in different parentElements to have their tooltips styled differently, and sibling selectors could even be used to style them differently within the same parentElement. The specified styles of the tooltip are all essential, as they are used to keep it near the mouse and within the viewport, so they must not be changed. Other styles can be added as needed, however.
The tooltip HTML will be as follows:
<div class="linecharttooltip linecharttooltip[parentElement.id]" style="position: absolute; white-space: nowrap; display: none; left: ...px; top: ...px;">
<table style="white-space: nowrap;">
<thead>
<tr><th>[options.strings.dataSet]</th><th>[xTitle]</th><th>[yTitle]</th></tr>
</thead>
<tbody>
<tr><th>[data set.name]</th><th>[data point.x]</th><th>[data point.y]</th></tr>
...
</tbody>
</table>
</div>
An additional column may be added if the chart has a second Y axis, whenever the tooltip is showing results for two data sets at once that use different Y axes, or whenever the tooltip is showing a result for a data set using the first Y axis when the ySecondConverter option is being used. The data point's x value will be in the appropriate format for the X axis (but with full precision when the xType option is set to 'datetime' or 'datetimeutc'), and both the x and y values will have been replaced by their respective replacer functions, if they have been provided.
Some suggested styling for the tooltip:
.linecharttooltip table {
background: white;
color: black;
border: 1px solid black;
border-collapse: collapse;
}
.linecharttooltip th, .linecharttooltip td {
border: 1px solid black;
padding: 4px;
}
.linecharttooltip thead th {
background: grey;
color: white;
}
.linecharttooltip tbody th {
background: silver;
}
Debug options
Debug options can be specified as a child object of the options object, with the following properties, all of which are optional:
- time (optional)
- Boolean: false, undefined, null or any other value that casts to false (default) to disable time debugging. true to enable time debugging. When enabled, this will log the time at various points during the display of the chart, so that bottlenecks can be identified. This is particularly useful when using a pointRenderer to display custom symbols, as this is usually the slowest part when displaying large data sets.
Point renderer functions
Point renderer functions can be used to draw custom data point symbols, instead of using the predefined ones. This is done using the standard canvas API methods. The canvas context drawing state is saved before a point renderer is called, so in theory, context changes (line thicknesses, rotation, etc.) that happen in a point renderer function will not have any effect on the code that runs after the function returns. The strokeStyle, fillStyle, lineWidth and line dash pattern are intentionally left set to the values that would normally be used for the data lines and symbols, so that the point renderer function can continue working with the same settings.
Point renderer functions can either be specified globally as a handler function, or specified individually for a single data set. When used, they will be called with the following parameters:
- context
- The CanvasRenderingContext2D for the chart's canvas. This can be used to draw symbols.
- x
- The horizontal position on the canvas where the point should be drawn.
- y
- The vertical position on the canvas where the point should be drawn.
- pointSize
- Positive number: the radius of the point, as set by either the pointSize property of the data set, or the global pointSize option. Note that drawing larger than this radius could cause parts of the symbol to be cropped where it extends beyond the limits of the plot area.
- pointSymbol
- Integer: the pointSymbol value for the data set, or the 0-based index of the data set if a pointSymbol value was not specified.
- dataSetIndex
- Integer: the 0-based index of the data set.
- pointIndex
- Integer: the 0-based index of the data point within its data set, or -1 when drawing the point in the key.
This is the most performance critical part of chart drawing, so it should be kept as fast as possible when dealing with large data sets. To speed up rendering, when a symbol will need to be drawn multiple times, it can be drawn once on a separate canvas, held entirely in memory, then copied repeatedly onto the chart canvas whenever it is needed using:
context.drawImage( otherCanvas, x - offset, y - offset )
In this example, the offset would be the position of the symbol's centre, from the top left corner of the separate canvas. During performance testing, Chromium based browsers were found to be twice as fast when drawing the first 37300 symbols directly to the main canvas. However, after that, they became twice as fast when using the copying approach. Gecko based browsers like Firefox were consistently much faster when using the copying approach for 2 or more symbols. Clearly, Chromium has some unusual optimisation that only works for a while. This optimisation could depend on the complexity or size of the symbol, or the size of the chart, or the performance of the computer. It should not be relied upon.
Text replacer functions
Text replacer functions can be used to perform more localisation of generated numbers, add units to tooltips, or show words instead of numbers on the X and Y axes. For example, the function could provide the numbers in Arabic numerals, or the date in a specific, verbose format. These must return a string, which will be used instead of the text that was going to be displayed. Return values are cached to avoid repeated calls for the same data point, but the same values may be requested several times if they relate to different data points. These calls may occur in high quantities if the user rapidly moves their mouse over multiple data points, so replacer functions need to be able to respond very quickly.
Text replacer functions can be specified globally as handler functions. When used, they will be called with the following parameters:
- value
- Number: the relevant x or y value of a data points, or the numeric axis value, that needs to be replaced. When the xType option is set to 'duration', and the value relates to the X axis, or is the x value of a data point, the value will already have been scaled by the divisor. When the value has been created by converting the y value of a data point using a ySecondConverter, this value will have had any floating point errors removed. This will have caused the value of any floating point number to be reduced to a maximum precision of 14 significant figures, even if it did not originally have any floating point error. If the raw value is needed without any precision loss, use the raw value of the dataPointInfo instead.
- xAxisInfo
- Object: provided if the value relates to the X axis, or is the x value of a data point. Testing for this object can be used to determine which axis the value relates to. The object will have the following properties:
- xType
- String: the xType option being used for the chart. This will use 'number' for all values that resolve to 'number'.
- divisor
- Integer: if the X value has been scaled (eg. when the xType option is set to 'duration'), this number is the amount that it has been divided by. When the X value has not been scaled, this will be 1.
- datePrecision
- String: when the xType option is set to 'datetime', 'datetimeutc' or 'duration', this suggests the appropriate precision that should be used for the returned date string. For X axis labels, this will be the grid alignment units: 'years', 'months', 'weeks', 'days', 'hours', 'minutes' or 'seconds'. For data points, this will be the string 'milliseconds'.
- undefined: value when the xType option is set to 'number'.
- dateFormat
- Object: the dateFormat option that was given when calling lineChart. This is passed by reference. If no object was given to the chart, then an empty object will be given as the value.
- null: provided if the value relates to the Y axis, or is the y value of a data point.
- yAxisInfo
- Object: provided if the value relates to the Y axis, or is the y value of a data point. Testing for this object can be used to determine which axis the value relates to. The object will have the following properties:
- yAxis
- String: 'first' if the data point or label relates to the first Y axis, 'second' if the data point or label relates to the second Y axis. For data points, this will normally be the yAxis option for the data set, using 'first' for all values that resolve to 'first'. If the value has been generated by applying a ySecondConverter to the y value of a data point, then this will be the target Y axis that the converted value relates to, not the Y axis that the data set originally related to.
- null: provided if the value relates to the X axis, or is the x value of a data point.
- dataPointInfo
- Object: provided if the value relates to a data point. Testing for this object can be used to determine if it relates to a data point or axis label. The object will have the following properties:
- x
- Number: the x value of the data point, without being divided by any divisor.
- y
- Number: the y value of the data point. This is the original y value, before any converters have been applied.
- ySecondConverted
- Object: provided if the value has been generated by applying a ySecondConverter to the y value of a data point. Testing for this object can be used to determine if the value relates to the original data point data, or a converted value. The object will have the following properties:
- dataSetYAxis
- String: 'first' if the data point originally related to the first Y axis, 'second' if the data point originally related to the second Y axis. This will be the value of the yAxis option for the data point's data set, using 'first' for all values that resolve to 'first'.
- raw
- Number: the converted y value of the data point, after the converter has been applied. This will be the value directly created by the converter, in its original precision, and can have floating point errors created by JavaScript's numerical limitations.
- null: provided if the value has not been converted using a ySecondConverter.
- dataSetIndex
- Integer: the 0-based index of the data set.
- dataSetName
- String: the name property of the data set.
- pointIndex
- Integer: the 0-based index of the data point within its data set.
- null: provided if the value relates to an axis label.
Browser compatibility
The script is designed to work in browsers that have reasonable support for the HTML Canvas element. This covers all major browser engines, including Chromium (Chrome, Vivaldi, Opera, many others), Gecko (Firefox, many others) and WebKit (Safari, almost all iOS browsers, KDE-based browsers).
It also works well in EdgeHTML versions of Edge, and Internet Explorer 9+, even though both of those browsers have been discontinued. In Internet Explorer 9 and 10, it uses an international date format, while later versions can use a localised date format with date formatting options. Opera 10.5-12.18 can also run most of the script, but can only use an international date format, and cannot use dash patterns. The script only tries to use dash patterns if the browser supports them, so it manages to run in Opera's presto engine without them. Earlier versions do not support the required canvas state saving, or text rendering. These discontinued browsers are not explicitly supported, and might run into canvas size limits that have not been accounted for when dealing with data extremes, but it is nice to see that the script can work in those browsers in normal conditions.
The script does not work in Konqueror when using the legacy KHTML rendering engine, because it does not support font rendering on HTML Canvas, despite supporting a large amount of other Canvas functionality.
Limits
Browsers have limits to how big a canvas can get, and the maximum size is enforced by the script. This is just over 16000 pixels wide or high in Chromium based browsers, just over 11000 pixels in Gecko based browsers and just over 8000 pixels in Internet Explorer. Safari is memory dependent, so although it should in theory be able to cope with over 16000 pixels, in practice it can choke above 14000 pixels, so this is the limit that the script enforces. If the chart is allowed to be too big, the browser silently ignores any attempt to draw on the canvas, without letting the script know that nothing is happening. As a result, enforcing these limits, which are browser dependent, clumsy and undetectable, becomes very important, and is done with browser detection.
All browsers have limits to how far outside the canvas they are allowed to paint lines. This can happen when using xStart, xEnd, yStart, yEnd, ySecondStart or ySecondEnd to show only a subset of the data. If any line points are too far outside the area, the browser will either draw the whole line in the wrong place (Safari is the only one to do this), or fail to paint the entire line, including the parts that are inside the canvas. As a result, the script has to impose limits on the calculated coordinates outside the viewable area of the chart.
This is browser dependent again, with browsers choosing some very odd limits. Chromium's limit changes depending on how close to the edge of the canvas a line starts - the closer to the edge of the canvas, the worse the limit will be. In the worst case, it allows coordinates in the range of -1x109 to 3.4x1038 (128 bits). Safari allows coordinates in the range of -5.76x1017 to 3.4x1038. Firefox and Internet Explorer allow coordinates in the range of -5.649x1035 to 5.649x1035 (119 bits but not completely used - very weird). To avoid these problems, the script forces the coordinates to remain within the browser's limits. This means that if a line starts at a data point inside the plot area, and extends to a data point beyond the browser's limits, the line might be drawn at the wrong angle. This probably does not matter much in reality.
JavaScript itself has limits in the handling of numbers. Within JavaScript, 1.7976931348623157x10308 is the maximum number that can be handled, and everything above that is considered to be infinity. However, this script needs to potentially be able to chart a range consisting of both positive and negative numbers, and needs to be able to calculate a scaling factor for the positions between them. This means that it needs to be able to subtract the highest number from the lowest number, and get a positive number that works. As a result, the script can only cope with numbers at a maximum of half JavaScript's maximum number. The limit on data values is therefore -8.988465674311579e+307 to 8.988465674311579e+307. Anything beyond those values will be treated as infinite. Infinity itself is not a value that can really be shown on a chart, so the script will simply clamp infinite numbers to the maximum number it can actually cope with. This applies both to the data itself, and the options that control the range of data being shown. Using data or options above this range will cause the script to emit a warning in the console. If the script somehow fails to protect against these values being used, a written notice will appear on the page instead of the chart, and an error will appear in the console.
JavaScript also has limits to the maximum size of an array, and since arrays are how data is passed to the script, this will limit how much data can be passed to the script. The maximum number of cells in any array is normally 2x1032-1; that is 4294967295 cells, or 4 billion cells. That means a maximum of 4 billion dataSets, a maximum of 4 billion data points per data set, a maximum of 4 billion xBands, and a maximum of 4 billion yBands. Hopefully that will be enough. The script cannot detect if you try to step past this limit, because it is a limit within JavaScript itself, and the script therefore will not see if the array tried to get any longer than that, because JavaScript will have ignored any attempt to make it longer.
When drawing the grid, JavaScript needs to be able to calculate the positions of each grid line. At numbers above JavaScript's maximum safe integer (9007199254740991) or below its negative equivalent, JavaScript cannot reliably count in whole numbers any more, because it lacks the numeric precision. This gets worse with larger numbers. When trying to show a chart over a very small numeric range at extremely high numbers, such as between 9007199254740992 and 9007199254740994, it will not be possible for the script to calculate any grid lines between them, which will also cause a warning to appear in the console. It also would not be possible to show data points in the correct positions between these numbers, as the precision loss will make the data points appear to have the same values as each other. This effect can happen with sufficiently small ranges at lower numbers too, where the script cannot add on the fraction of a step between the numbers. Therefore, while the script can cope with very big numbers, it is only really usable if the data values themselves are also spread over a wide enough range not to be badly affected by the precision loss. This is a fundamental limitation of IEEE 754 double precision floating point numbers, which is what JavaScript uses.
With dates and times, JavaScript has much lower limits. All dates and times are represented by integer timestamps in milliseconds, either side of 1 January 1970 00:00:00.000 UTC. The maximum and minimum integers supported by JavaScript Date objects are -8.64x1015 to 8.64x1015, around 20 April 271821 BCE to 13 September 275760 CE. This script is therefore limited to those same values when the xType option is set to 'datetime' or 'datetimeutc'. The plot area ends are also limited to those same values. At the limits, the grid stepping can be unusual, as the script might not be able to calculate the position of the first grid line properly.
Changelogs
Changes in version 1.2.1, 03/04/2022
- Corrected handling of hour ranges when xType option is set to 'datetime' or 'datetimeutc'.
Changes in version 1.2, 12/09/2022
- Added ySecondConverted information when using a text replacer function.
- Added workingCanvas to the returned object.
- Avoided a floating point error with converted data point tooltips.
- Improved performance of showing tooltips when crosshairLineWidth is set to 0.
Changes in version 1.1, 02/09/2022
- Added ySecondConverter option.
- Moved the weekStartDay option to the correct place.
- Corrected creation of date-based X axis labels when working in days, so that it can start on the correct day of the month, and starts drawing grid lines at the correct date.
- Corrected use of date-based X axis when working in weeks.
Changes in version 1.0.2, 29/08/2022
- Allowed 'auto0' options to work.
- Avoided clipping lines too early at the bottom of the plot area, and avoid clipping thick lines at all edges of the plot area.
Changes in version 1.0.1, 28/08/2022
- Avoided a floating point error which could cause grid labels to go missing.
Changes in version 1.0, 09/08/2022
- Renamed to Line Chart Script.
- New data structure now uses objects instead of nested arrays, which improves clarity.
- Charts can now be inserted anywhere, not just in one location per page.
- Charts no longer create a heading element.
- Charts can be created and re-created on demand at any point after document loading.
- Charts can now use numbers and time-based durations as well as the original dates for the X axis.
- Date based charts can now optionally work in local timezone, not just UTC (with support for local DST shifts).
- Date based charts can now work in appropriate units of time, depending on the data range.
- Date based charts now give axis labels only in years when working in years, not years-and-months.
- Date based charts now use locale-aware date formatting.
- Negative X and Y values are now supported.
- Infinite X and Y values are no longer treated as invalid.
- Multiple X bands can now be used.
- Y bands can now be used.
- A second Y axis can now be used.
- New options structure allows easier future updates.
- Colours can now be changed. For everything.
- Fonts and font sizes can now be changed.
- Line thicknesses can now be changed for data sets, bands and grids.
- Line dash patterns can now be set for data sets, bands and each of the different axis grids, to differentiate between them.
- Data point symbol size can now be changed.
- Data point symbols can now be changed for each data set.
- Custom data point symbols can now be created.
- Chart height and width can be explicitly set instead of just automatic.
- The chart's canvas can now have its margin, border and padding set with CSS, even when using automatic width.
- Automatic chart height is now based on the plot area only.
- X axis can now have labels for every grid line, not just at the ends of the chart.
- X axis end labels now choose their orientation based on the available space.
- X and Y axis labels are now selectively shown only when there is space for them.
- X and Y axis labels can now have their text controlled and replaced.
- Both X and Y axes can take their maximum and minimum values automatically from the grid spacing, or can be set to specific values.
- Both X and Y axes can optionally show only the range containing the data, or be extended to include 0.
- Grid lines can be set to shorter lengths, rather than the entire plot area.
- Grid lines can have grid ticks (short lines) next to their labels.
- Grid lines can now cope with numbers to any precision, compared with the previous limit of 1x10-3.
- Axis labels can optionally be hidden.
- Data point x and y values can now be shown in a tooltip on hover, with a crosshair to highlight the position.
- Added performance debugging option.
- Older browsers are no longer explicitly supported, though the charts do work in some older browsers (Opera 9-10.20 can no longer work, even with a text rendering library).