第三章 图表配置
图表配置主要用来配置图表的行为。主要包括对样式、字体、图例等的属性配置。
3.1 全局配置
全局配置的概念在Chart.js1.0版本中就已经引进来了,主要是为了使配置选项遵守DRY原则(Don't repeat yourself)。它允许在整个图表中对图表进行配置,这样就可以避免为每一个图表实例进行配置。全局通用选项配置定义在Chart.defaults.global属性中。不同图表类型的默认配置将在相关图表类型章节中讲解。
下面实例将所有图表的鼠标悬停模式设置为nearest,该配置会被特定类型图表的相关配置选项所覆盖(如果有设置的话):
Chart.defaults.global.hover.mode = 'nearest';
// 鼠标悬停模式设置为'nearest'模式,因为没有被覆盖
var chartHoverModeNearest = new Chart(ctx, {
type: 'line',
data: data
});
// 此图表的鼠标悬停模式被设置为‘index’模式,因为在特定配置选项中覆盖了全局的配置
var chartDifferenHoverMode = new Chart(ctx, {
type: 'line',
data: data,
options: {
hover: {
// 覆盖全局设置
mode: 'index'
}
}
});
3.2 动画
Chart.js提供了一些配置选项用来指定动画的样式以及动画的持续时间。
动画配置
动画的全局配置在Chart.defaults.global.animation属性中设置,有以下可用的动画配置选项:
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
duration | Number | 1000 | 动画的持续时间(以毫秒为单位) |
easing | String | 'easeOutQuart' | 动画时间曲线 |
onProgress | Function | null | 动画每一帧完成时的回调函数 |
onComplete | Function | null | 动画最后一帧完成时的回调函数 |
动画时间曲线
easing属性可选的值有:
- 'linear'
- 'easeInQuad'
- 'easeOutQuad'
- 'easeInOutQuad'
- 'easeInCubic'
- 'easeOutCubic'
- 'easeInOutCubic'
- 'easeInQuart'
- 'easeOutQuart'
- 'easeInOutQuart'
- 'easeInQuint'
- 'easeOutQuint'
- 'easeInOutQuint'
- 'easeInSine'
- 'easeOutSine'
- 'easeInOutSine'
- 'easeInExpo'
- 'easeOutExpo'
- 'easeInOutExpo'
- 'easeInCirc'
- 'easeOutCirc'
- 'easeInOutCirc'
- 'easeInElastic'
- 'easeOutElastic'
- 'easeInOutElastic'
- 'easeInBack'
- 'easeOutBack'
- 'easeInOutBack'
- 'easeInBounce'
- 'easeOutBounce'
- 'easeInOutBounce'
动画回调函数
动画回调函数会被传入一个Chart.Animation实例作为参数,该实例具有如下属性:
{
// Chart对象
chart: Chart,
// 当前帧
currentStep: Number,
// 总帧数
numSteps: Number,
// 动画时间曲线
easing: String,
// 用来绘制图表的render()函数
render: Function,
// 用户回调函数
onAnimationProgress: Function,
// 用户回调函数
onAnimationComplete: Function
}
下面实例在图表的动画进行期间更新进度条:
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
animation: {
onProgress: function(animation) {
progress.value = animation.animationObject.currentStep / animation.animationObject.numSteps;
}
}
}
});
另一个使用动画回调函数的例子请见GitHub:此实例显示了一个进度条,用于展示动画的进度。
3.3 布局配置
布局配置在options.layout属性中进行设置。图表布局配置的全局属性是Chart.defaults.global.layout。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
padding | Number 或 Object | 0 | 添加到图表中的内边距 |
内边距
如果内边距的值是数值类型的,它将会同时应用于图表的四个方向(上下左右),如果内边距的值是一个对象,则left属性定义了左内边距,right属性定义了右内边距,top属性定义了上内边距,bottom属性定义了下内边距。
假设你想要设置图表画布的左内边距为50px,你可以按照如下方式:
let chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
layout: {
padding: {
left: 50,
right: 0,
top: 0,
bottom: 0
}
}
}
});
3.4 图例配置
图例配置使用options.legend属性进行设置。图例配置的全局属性是Chart.defaults.global.legend。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
display | Boolean | true | 是否显示图例 |
position | String | 'top' | 图例显示的位置 |
fullWidth | Boolean | true | 图例是否占据画布的整个宽度,通常使用中无需更改此属性的值 |
onClick | Function | 图例标签点击事件的回调函数 | |
onHover | Function | 'mousemove'事件的回调函数 | |
reverse | Boolean | false | 数据集合对应的图例是否逆向排序 |
labels | Object | 请参阅图例标签配置部分 |
位置(Position)
用于设置图例显示的位置,可选值有:
- 'top'
- 'left'
- 'bottom'
- 'right'
图例标签配置
图例标签配置使用options.legend.labels属性进行设置。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
boxWidth | Number | 40 | 图例中颜色框的宽度 |
fontSize | Number | 12 | 图例文本的字体大小 |
fontStyle | String | 'normal' | 图例文本的粗细样式 |
fontColor | Color | '#666' | 图例文本的颜色 |
fontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | 图例文本的字体类型 |
padding | Number | 10 | 颜色框之间的行距 |
generateLabels | Function | ||
filter | Function | null | 过滤图例中的图例项。该函数接收两个参数,第一个参数是图例项,第二个参数是图表数据 |
usePointStyle | Boolean | false | 标签样式是否匹配对应点的样式 |
图例项接口
传递到图例的onClick回调函数中的图例项是由labels.generateLabels函数返回的。这些图例项必须实现以下接口:
{
// 将要显示的标签内容
text: String,
// 图例盒填充的颜色
fillStyle: Color,
// 如果设置为true,那么此项表示一个隐藏的数据集合。标签会被渲染为具有删除线的效果
hidden: Boolean,
// 用于控制颜色盒的边框
lineCap: String,
// 用于控制颜色盒的边框
lineDash: Array<Number>,
// 用于控制颜色盒的边框
lineDashOffset: Number,
// 用于控制颜色盒的边框
lineJoin: String,
// 颜色盒边框的宽度
lineWidth: Number,
//图例颜色盒边框的颜色
strokeStyle: Color,
// 图例颜色盒的点样式(只有在usePointStyle为true时有效)
pointStyle: String
}
实例
下面实例创建的图表具有图例配置,并且将所有的图例标签颜色设置为红色。
var chart = new Chart(ctx, {
type: 'bar',
data: data,
options: {
legend: {
display: true,
labels: {
fontColor: 'rgb(255, 99, 132)'
}
}
}
});
自定义图例标签被点击时的行为
实际的项目开发中,有一个很常见的需求是在点击图例标签项时触发不同的行为。这可以通过在配置对象中使用回调函数实现。
默认的图例点击处理函数为:
function(e, legendItem) {
var index = legendItem.datasetIndex;
var ci = this.chart;
var meta = ci.getDatasetMeta(index);
meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
ci.update();
}
假如我们想要在点击图例时更改前两个数据集合的显示状态,我们可以按照如下方式改变点击事件的回调函数。
var defaultLegendClickHandler = Chart.defaults.global.legend.onClick;
var newLegendClickHandler = function(e, legendItem) {
var index = legendItem.datasetIndex;
if(index > 1) {
defaultLegendClickHandler(e, legendItem);
} else {
let ci = this.chart;
[ci.getDatasetMeta(0), ci.getDatasetMeta(1)].forEach(function(meta) {
meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
});
ci.update();
}
}
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
legend: {
onClick: newLegendClickHandler
}
}
});
现在当你点击图表中的图例时,前两个数据集合的显示状态就会同步了。
HTML图例
有时候你可能需要一个非常复杂的图例。在这种情况下,生成HTML格式的图例是一个更加合适的方案。Chart.js在其原型(prototype)上提供了一个generateLegend()方法,该方法可以返回HTML格式的字符串作为图例。
要配置图例的生成方式,可以使用legendCallback属性:
var chart = new Chart(ctx, {
type: 'line',
options: {
legendCallback: function(chart) {
// 返回HTML字符串
}
}
});
需要注意的是:legendCallback不会被自动调用,因此,如果 想要使用此方法创建图例时,必须在代码中主动调用generateLegend()函数。
3.5 标题
图表标题用于定义在图表上方绘制的文本。
标题配置
标题配置通过options.title属性进行设置。在全局配置中,使用Chart.defaults.global.title属性进行设置。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
display | Boolean | false | 是否显示图表标题 |
position | String | 'top' | 标题显示的位置 |
fontSize | Number | 12 | 字体大小 |
fontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | 标题的字体类型 |
fontColor | Color | '#666' | 标题的字体颜色 |
fontStyle | String | 'bold' | 标题的字体粗细 |
padding | Number | 10 | 标题的上下边距 |
lineHeight | Number/String | 1.2 | 标题的行高 |
text | String/String[] | '' | 要显示的标题文本内容,如果值为数组,文本会分多行显示 |
位置
图表标题的position属性可选值有:
- 'top'
- 'left'
- 'right'
- 'bottom'
用法举例
下面创建一个图表,图表的标题显示为“Custom Chart Title”。
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
title: {
display: true,
text: 'Custom Chart Title'
}
}
});
3.6 提示框
提示框配置
提示框配置通过options.tooltips属性进行设置。在全局配置中,使用Chart.defaults.global.tooltips属性进行设置。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
enabled | Boolean | true | 是否激活提示框,如果设置为true,当鼠标位于数据区域之上时,会显示相关的数据描述信息 |
custom | Function | null | 请参阅自定义提示框部分 |
mode | String | 'nearest' | 用于设置如何判断提示框中应显示哪一个元素的信息 |
intersect | Booelean | true | 如果设置为true,提示框只在鼠标位置位于元素之上时才会应用提示框的mode属性,如果设置为false,则一直使用mode属性 |
position | String | 'average' | 提示框位置模式 |
callbacks | Object | 请参阅回调部分 | |
itemSort | Function | 对提示项进行排序 | |
filter | Function | 对提示项进行过滤 | |
backgroundColor | Color | 'rgba(0, 0, 0, 0.8)' | 提示框的背景颜色 |
titleFontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | 提示框标题的字体类型 |
titleFontSize | Number | 12 | 提示框标题的字体大小 |
titleFontStyle | String | 'bold' | 提示框标题的字体粗细 |
titleFontColor | Color | '#fff' | 提示框标题的字体颜色 |
titleSpacing | Number | 2 | 提示框标题行的上下边距 |
titleMarginBottom | Number | 6 | 提示框标题的下外边距 |
bodyFontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | 提示框主体文本的字体类型 |
bodyFontSize | Number | 12 | 提示框主体文本的字体大小 |
bodyFontStyle | String | 'normal' | 提示框主体文本的字体粗细 |
bodyFontColor | Color | '#fff' | 提示框主体文本的字体颜色 |
bodySpacing | Number | 2 | 提示框主体文本的上下内边距 |
footerFontFamily | String | "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif" | 提示框底部文本的字体类型 |
footerFontSize | Number | 12 | 提示框底部文本的字体大小 |
footerFontStyle | String | 'bold' | 提示框底部文本的字体粗细 |
footerFontColor | Color | '#fff' | 提示框底部文本的字体颜色 |
footerSpacing | Number | 2 | 提示框底部文本行的上下内边距 |
footerMarginTop | Number | 6 | 提示框底部文本的上外边距 |
xPadding | Number | 6 | 提示框的左右内边距 |
yPadding | Number | 6 | 提示框的上下内边距 |
caretPadding | Number | 2 | 提示框箭头尾部距离提示点的距离 |
caretSize | Number | 5 | 提示框箭头的大小(以px为单位) |
multiKeyBackground | Color | '#fff' | 当有多个项在提示框内时,提示框内颜色盒所在位置的背景色 |
displayColors | Boolean | true | 如果设置为true,则在提示框内会显示和数据区域对应的颜色盒 |
borderColor | Color | 'rgba(0, 0, 0, 0)' | 边框颜色 |
borderWidth | Number | 0 | 边框宽度 |
位置模式
可能的模式有:
- 'average'
- 'nearest'
'average'模式会将提示框的位置设置为当前数据集的平均位置。
'nearest'模式会将提示框的位置设置为离触发点最近的位置。
除了这两种模式外,还可以通过为Chart.Tooltip.positioners添加函数来自定义模式。如下所示:
Chart.Tooltip.positioners.custom = function(elements, eventPosition) {
var tooltip = this;
return {
x: 0,
y: 0
};
}
排序回调
排序回调允许对提示框内的提示项进行排序。至少要实现一个方法,并且该方法可以作为参数传入到Array.prototype.sort方法中。该方法还可以接收第三个参数,第三个参数表示传递给图表的数据对象。
过滤回调
过滤回调允许对提示框的提示项进行过滤。至少要实现一个方法,并且该方法可以作为参数传入到Array.prototype.filter方法中。该方法还可以接收第二个参数,第二个参数表示传递给图表的数据对象。
提示框回调
提示框的标签配置使用options.tooltips.callbacks属性进行设置。提示框具有如下的回调函数用来提供文本信息。对下表所有的函数来说,this均指代由Chart.Tooltip构造函数创建的提示框对象。
下表中所有函数被调用时具有相同的参数:第一个参数是提示框项,第二个参数是传递给图表的数据对象。下表所有函数必须返回一个字符串或字符串数组。如果返回的是字符串数组,则表示多行文本。
回调函数名称 | 参数 | 描述 |
---|---|---|
beforeTitle | Array[tooltipItem], data | 返回要渲染到标题之前的文本 |
title | Array[tooltipItem], data | 返回要渲染的标题内容 |
afterTitle | Array[tooltipItem], data | 返回要渲染到标题之后的文本 |
beforeBody | Array[tooltipItem], data | 返回要渲染到主体内容之前的文本 |
beforeLabel | tooltipItem, data | 返回要渲染到提示框的单个标签之前的文本,此函数会被提示框中的每标签项调用 |
label | tooltipItem, data | 返回要渲染的标签内容 |
labelColor | toolItem, chart | 返回要渲染的提示框项的颜色 |
labelTextColor | tooltipItem, chart | 返回提示框标签项的文本颜色 |
afterLabel | tooltipItem, data | 返回要渲染到标签项之后的文本 |
afterBody | Array[tooltipItem], data | 返回要渲染到提示框主体内容之后的文本 |
beforeFooter | Array[tooltipItem], data | 返回要渲染到提示框尾部内容之前的文本 |
footer | Array[tooltipItem], data | 返回要渲染的尾部内容 |
afterFooter | Array[tooltipItem], data | 返回要渲染到提示框尾部内容之后的文本 |
标签回调
标签回调可以改变给定数据点的显示文本。一个很常见的实例是数据值的四舍五入,下面实例对数据值保留两位小数进行四舍五入。
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
tooltips: {
callbacks: {
label: function(tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].label || '';
if(label) {
label += ': ',
}
label += Math.round(tooltipItem.yLabel * 100) / 100;
return label;
}
}
}
}
});
标签颜色回调
例如,对提示框中的每一项,返回一个红色的盒子:
var chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
callbacks: {
labelColor: function(tooltipItem, chart) {
return {
borderColor: 'rgb(255, 0, 0)',
backgroundColor: 'rgb(255, 0, 0)'
}
},
labelTextColor: function(tooltipItem, chart) {
return '#543453';
}
}
}
});
TooltipItem接口
{
xLabel: String,
yLabel: String,
datasetIndex: Number,
index: Number,
x: Number,
y: Number,
}
外部(自定义)提示框
自定义提示框允许你使用渲染过程的钩子,从而渲染自定义的提示框。此方法通常用来生成HTML格式的提示框,而不是在画布上绘制。你既可以在全局中激活自定义提示框,也可以在特定图表的配置对象中激活,如下所示:
var myPieChart = new Chart(ctx, {
type: 'pie',
data: data,
options: {
tooltips: {
// 禁用画布上的提示框
enabled: false,
custom: function(tooltipModel) {
// 提示框元素
let tooltipEl = document.getElementById('chartjs-tooltip');
// 在第一次渲染时创建元素
if(!tooltipEl) {
tooltipEl = document.createElement('div');
tooltipEl.id = 'chartjs-tooltip';
tooltipEl.innerHTML = '<table></table>';
document.body.appendChild(tooltipEl);
}
// 如果没有提示框则隐藏自定义的提示框
if(tooltipModel.opacity === 0) {
tooltipEl.style.opacity = 0;
return;
}
// 设置插入符号位置
tooltipEl.classList.remove('above', 'below', 'no-transform');
if(tooltipModel.yAlign) {
tooltipEl.classList.add(tooltipModel.yAlign);
} else {
tooltipEl.classList.add('no-transform');
}
function getBody(bodyItem) {
return bodyItem.lines;
}
// 设置文本
if(tooltipModel.body) {
let titleLines = tooltipModel.title || [];
let bodyLines = tooltipModel.body.map(getBody);
let innerHTML = '<thead>';
titleLines.forEach(function(title){
innerHTML += '<tr><th>' + title + '</th></tr>';
});
innerHTML += '</thead><tbody>';
bodyLines.forEach(function(body, i) {
let colors = tooltipModel.labelColors[i];
let style = 'background:' + colors.backgroundColor;
style += 'border-color:' + colors.borderColor;
style += 'border-width: 2px';
var span = '<span style="' + style + '"></span>';
innerHTML += '<tr><td>' + span + body + '</td></tr>';
});
innerHTML += '</tbody>';
let tableRoot = tooltipEl.querySelector('table');
tableRoot.innerHTML = innerHTML;
}
// `this` will be the overall tooltip
var position = this._chart.canvas.getBoundingClientRect();
// Display, position, and set styles for font
tooltipEl.style.opacity = 1;
tooltipEl.style.position = 'absolute';
tooltipEl.style.left = position.left + tooltipModel.caretX + 'px';
tooltipEl.style.top = position.top + tooltipModel.caretY + 'px';
tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
tooltipEl.style.fontSize = tooltipModel.bodyFontSize + 'px';
tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;
tooltipEl.style.padding = tooltipModel.yPadding + 'px ' + tooltipModel.xPadding + 'px';
}
}
}
});
TooltipModel接口
{
dataPoints: TooltipItem[],
xPadding: Number,
yPadding: Number,
xAlign: String,
yAlign: String,
x: Number,
y: Number,
width: Number,
height: Number,
caretX: Number,
caretY: Number,
// Body相关
body: Object[],
beforeBody: String[],
afterBody: String[],
bodyFontColor: Color,
_bodyFontFamily: String,
_bodyFontStyle: String,
_bodyAlign: String,
bodyFontSize: Number,
bodySpacing: Number,
// Title相关
title: String[],
titleFontColor: Color,
_titleFontFamily: String,
_titleFontStyle: String,
titleFontSize: Number,
_titleAlign: String,
titleSpacing: Number,
titleMarginBottom: Number,
// Footer相关
footer: String[],
footerFontColor: Color,
_footerFontFamily: String,
_footerFontStyle: String,
footerFontSize: Number,
_footerAlign: String,
footerSpacing: Number,
footerMarginTop: Number,
// Appearance
caretSize: Number,
cornerRadius: Number,
backgroundColor: Color,
// colors to render for each item in body[]. This is the color of the squares in the tooltip
labelColors: Color[],
// 0 opacity is a hidden tooltip
opacity: Number,
legendColorBackground: Color,
displayColors: Boolean,
}
3.7 元素
有时候我可能想要给所有的数据集定义相同的样式,比如,为柱状图中的每一个柱形条设置相同的边框颜色,但是对每个柱形条填充不同的颜色。有一些选项可以用来配置四种不同类型元素(弧线、直线、点、矩形)的样式。
全局配置
不同元素类型的样式配置可以通过为每一个图表单独指定,也可以使用全局指定。全局指定是使用Chart.defaults.global.elements属性完成的。例如,我们要设置所有柱形条的边框宽度为2px,你可以使用如下方式:
Chart.defaults.global.elements.rectangle.borderWidth = 2;
点配置
点元素用于表示线形图或气泡图中的点。
在全局配置中,使用Chart.defaults.global.elements.point属性进行设置。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
radius | Number | 3 | 点的半径 |
pointStyle | String | 'circle' | 点的类型 |
backgroundColor | Color | 'rgba(0, 0, 0, 0.1)' | 点的填充颜色 |
borderWidth | Number | 1 | 点的边框宽度 |
borderColor | Color | 'rgba(0, 0, 0, 0.1)' | 点的边框颜色 |
hitRadius | Number | 1 | 用于碰撞检测而额外添加到点半径上的尺寸 |
hoverRadius | Number | 4 | 当鼠标位于点之上时,点的半径 |
hoverBorderWidth | Number | 1 | 当鼠标位于点之上时,点的边框宽度 |
点的类型
支持如下类型的点:
- 'circle' 圆形
- 'cross' 十字
- 'crossRot'
- 'dash'虚线
- 'line'实线
- 'rect'矩形
- 'rectRounded'圆角矩形
- 'rectRot'
- 'star'星形
- 'triangle'三角形
除上面这些值之外,还可以是一个图片,如果是图片,则使用drawImage绘制到画布上。
线配置
线元素用来表示线形图中的线。
在全局配置中,使用Chart.defaults.global.elements.line属性进行配置。
属性名称 | 数据类型 | 默认值 | 描述 |
---|---|---|---|
tension | Number | 0.4 | 贝塞尔曲线张量(0表示不使用贝塞尔曲线) |