Chart.js 配置选项 #

配置结构概览 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Chart.js 配置层级                          │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              全局配置 (Chart.defaults)               │   │
│  │  所有图表共享的默认配置                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                            │                                 │
│                            ▼                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              图表类型配置 (Chart.defaults.type)      │   │
│  │  特定图表类型的默认配置                                │   │
│  └─────────────────────────────────────────────────────┘   │
│                            │                                 │
│                            ▼                                 │
│  ┌─────────────────────────────────────────────────────┐   │
│  │              实例配置 (options)                       │   │
│  │  单个图表实例的配置                                    │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                              │
└─────────────────────────────────────────────────────────────┘

全局配置 #

设置全局默认值 #

javascript
// 设置全局默认配置
Chart.defaults.font.family = 'Arial';
Chart.defaults.font.size = 12;
Chart.defaults.color = '#666';

// 设置全局响应式
Chart.defaults.responsive = true;
Chart.defaults.maintainAspectRatio = false;

全局字体配置 #

javascript
Chart.defaults.font = {
  family: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
  size: 12,
  style: 'normal',
  weight: 'normal',
  lineHeight: 1.2
};

全局颜色配置 #

javascript
// 默认颜色
Chart.defaults.borderColor = 'rgba(0, 0, 0, 0.1)';
Chart.defaults.color = '#666';

// 默认背景色(用于没有指定颜色的数据集)
Chart.defaults.backgroundColor = [
  'rgba(255, 99, 132, 0.5)',
  'rgba(54, 162, 235, 0.5)',
  'rgba(255, 206, 86, 0.5)',
  'rgba(75, 192, 192, 0.5)',
  'rgba(153, 102, 255, 0.5)',
  'rgba(255, 159, 64, 0.5)'
];

按图表类型设置默认值 #

javascript
// 设置柱状图默认值
Chart.defaults.datasets.bar.backgroundColor = 'rgba(54, 162, 235, 0.5)';
Chart.defaults.datasets.bar.borderColor = 'rgba(54, 162, 235, 1)';
Chart.defaults.datasets.bar.borderWidth = 1;

// 设置折线图默认值
Chart.defaults.datasets.line.tension = 0.4;
Chart.defaults.datasets.line.fill = false;

核心配置选项 #

响应式配置 #

javascript
const options = {
  // 是否响应式
  responsive: true,
  
  // 是否保持宽高比
  maintainAspectRatio: true,
  
  // 宽高比(宽度/高度)
  aspectRatio: 2,
  
  // 调整大小延迟(毫秒)
  resizeDelay: 0,
  
  // 是否使用 ResizeObserver
  resizeObserver: true,
  
  // 容器
  devicePixelRatio: window.devicePixelRatio || 1
};

交互配置 #

javascript
const options = {
  // 交互模式
  interaction: {
    // 模式:'point', 'nearest', 'index', 'dataset', 'x', 'y'
    mode: 'index',
    
    // 是否必须相交
    intersect: false,
    
    // 包含距离
    includeInvisible: false,
    
    // 坐标轴:'x', 'y', 'xy'
    axis: 'x'
  },
  
  // 事件配置
  events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
  
  // 点击事件
  onClick: (event, elements, chart) => {},
  
  // 悬停事件
  onHover: (event, elements, chart) => {},
  
  // 离开事件
  onLeave: (event, elements, chart) => {}
};

布局配置 #

javascript
const options = {
  layout: {
    // 内边距
    padding: {
      top: 10,
      right: 20,
      bottom: 10,
      left: 20
    },
    
    // 或者统一设置
    padding: 20
  }
};

插件配置 #

标题插件 #

javascript
const options = {
  plugins: {
    title: {
      // 是否显示
      display: true,
      
      // 标题文本(可以是字符串或数组)
      text: ['第一行标题', '第二行副标题'],
      
      // 位置:'top', 'bottom', 'left', 'right'
      position: 'top',
      
      // 对齐:'start', 'center', 'end'
      align: 'center',
      
      // 字体配置
      font: {
        family: 'Arial',
        size: 16,
        weight: 'bold',
        style: 'normal',
        lineHeight: 1.2
      },
      
      // 文字颜色
      color: '#333',
      
      // 内边距
      padding: {
        top: 10,
        bottom: 20
      },
      
      // 是否绘制边框
      drawBorder: false,
      
      // 边框宽度
      borderWidth: 1,
      
      // 边框颜色
      borderColor: '#ccc',
      
      // 边框圆角
      borderRadius: 4
    }
  }
};

图例插件 #

javascript
const options = {
  plugins: {
    legend: {
      // 是否显示
      display: true,
      
      // 位置
      position: 'top',
      
      // 对齐
      align: 'center',
      
      // 最大宽度
      maxWidth: 200,
      
      // 最大高度
      maxHeight: 100,
      
      // 是否可点击切换
      onClick: (e, legendItem, legend) => {
        const index = legendItem.datasetIndex;
        const ci = legend.chart;
        const meta = ci.getDatasetMeta(index);
        meta.hidden = meta.hidden === null ? !ci.data.datasets[index].hidden : null;
        ci.update();
      },
      
      // 悬停事件
      onHover: (e, legendItem, legend) => {},
      onLeave: (e, legendItem, legend) => {},
      
      // 是否反转
      reverse: false,
      
      // 标签配置
      labels: {
        // 字体
        font: {
          size: 12
        },
        
        // 颜色
        color: '#666',
        
        // 盒子宽度
        boxWidth: 40,
        
        // 盒子高度
        boxHeight: 12,
        
        // 使用点样式
        usePointStyle: false,
        
        // 点样式
        pointStyle: 'circle',
        
        // 内边距
        padding: 20,
        
        // 生成标签函数
        generateLabels: (chart) => {
          return chart.data.datasets.map((dataset, i) => ({
            text: dataset.label,
            fillStyle: dataset.backgroundColor,
            hidden: !chart.isDatasetVisible(i),
            lineCap: dataset.borderCapStyle,
            lineDash: dataset.borderDash,
            lineDashOffset: dataset.borderDashOffset,
            lineJoin: dataset.borderJoinStyle,
            lineWidth: dataset.borderWidth,
            strokeStyle: dataset.borderColor,
            pointStyle: dataset.pointStyle,
            rotation: 0,
            datasetIndex: i
          }));
        },
        
        // 过滤标签
        filter: (legendItem, chartData) => {
          return legendItem.text !== undefined;
        },
        
        // 排序
        sort: (a, b, chartData) => {}
      },
      
      // 标题
      title: {
        display: false,
        text: '图例标题',
        color: '#333',
        font: {
          size: 14,
          weight: 'bold'
        },
        padding: 10
      }
    }
  }
};

提示框插件 #

javascript
const options = {
  plugins: {
    tooltip: {
      // 是否启用
      enabled: true,
      
      // 模式
      mode: 'index',
      
      // 是否相交
      intersect: false,
      
      // 外部提示框(自定义 HTML 提示框)
      external: null,
      
      // 背景色
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      
      // 标题颜色
      titleColor: '#fff',
      
      // 正文颜色
      bodyColor: '#fff',
      
      // 字体
      titleFont: {
        size: 14,
        weight: 'bold'
      },
      bodyFont: {
        size: 12
      },
      footerFont: {
        size: 12
      },
      
      // 对齐
      textAlign: 'left',
      
      // 内边距
      padding: 10,
      
      // 圆角
      cornerRadius: 4,
      
      // 是否显示颜色框
      displayColors: true,
      
      // 颜色框宽度
      boxWidth: 12,
      boxHeight: 12,
      boxPadding: 3,
      
      // 使用点样式
      usePointStyle: false,
      
      // 边框
      borderColor: 'rgba(0, 0, 0, 0)',
      borderWidth: 0,
      
      // 位置:'average', 'nearest'
      position: 'average',
      
      // 是否跟随鼠标
      xAlign: 'center',
      yAlign: 'center',
      
      // 回调函数
      callbacks: {
        // 标题
        title: (tooltipItems) => {
          return tooltipItems[0].label;
        },
        
        // 标签
        label: (context) => {
          let label = context.dataset.label || '';
          if (label) {
            label += ': ';
          }
          if (context.parsed.y !== null) {
            label += context.parsed.y;
          }
          return label;
        },
        
        // 标签颜色
        labelColor: (context) => {
          return {
            borderColor: context.dataset.borderColor,
            backgroundColor: context.dataset.backgroundColor,
            borderWidth: 2,
            borderDash: [],
            borderRadius: 0
          };
        },
        
        // 标签文本样式
        labelTextColor: (context) => {
          return '#fff';
        },
        
        // 标题间距
        labelPointStyle: (context) => {
          return {
            pointStyle: 'circle',
            rotation: 0
          };
        },
        
        // 页脚
        footer: (tooltipItems) => {
          return '总计: ' + tooltipItems.reduce((sum, item) => sum + item.parsed.y, 0);
        },
        
        // 之前标题
        beforeTitle: (tooltipItems) => '',
        
        // 之后标题
        afterTitle: (tooltipItems) => '',
        
        // 之前正文
        beforeBody: (tooltipItems) => '',
        
        // 之后正文
        afterBody: (tooltipItems) => '',
        
        // 之前标签
        beforeLabel: (context) => '',
        
        // 之后标签
        afterLabel: (context) => '',
        
        // 之前页脚
        beforeFooter: (tooltipItems) => '',
        
        // 之后页脚
        afterFooter: (tooltipItems) => ''
      }
    }
  }
};

坐标轴配置 #

线性坐标轴 #

javascript
const options = {
  scales: {
    y: {
      // 类型
      type: 'linear',
      
      // 是否显示
      display: true,
      
      // 位置:'left', 'right', 'top', 'bottom'
      position: 'left',
      
      // 是否反向
      reverse: false,
      
      // 是否从零开始
      beginAtZero: true,
      
      // 范围
      min: 0,
      max: 100,
      
      // 标题
      title: {
        display: true,
        text: 'Y轴标题',
        color: '#333',
        font: {
          size: 14,
          weight: 'bold'
        },
        padding: { top: 0, left: 0, right: 0, bottom: 0 }
      },
      
      // 刻度
      ticks: {
        // 是否显示
        display: true,
        
        // 颜色
        color: '#666',
        
        // 字体
        font: {
          size: 12
        },
        
        // 格式化
        callback: (value, index, ticks) => {
          return value + '%';
        },
        
        // 步长
        stepSize: 10,
        
        // 最大刻度数
        maxTicksLimit: 10,
        
        // 精度
        precision: 0,
        
        // 是否显示标签背景
        showLabelBackdrop: true,
        backdropColor: 'rgba(255, 255, 255, 0.75)',
        backdropPadding: 2,
        
        // 主要刻度
        major: {
          enabled: true
        }
      },
      
      // 网格线
      grid: {
        display: true,
        color: '#eee',
        lineWidth: 1,
        drawBorder: true,
        drawOnChartArea: true,
        drawTicks: true,
        tickLength: 10,
        borderDash: [],
        borderDashOffset: 0,
        circular: false
      },
      
      // 边框
      border: {
        display: true,
        color: '#ccc',
        width: 1,
        dash: [],
        dashOffset: 0
      },
      
      // 堆叠
      stacked: false,
      
      // 权重
      weight: 1
    }
  }
};

分类坐标轴 #

javascript
const options = {
  scales: {
    x: {
      type: 'category',
      
      // 标签
      labels: ['一月', '二月', '三月', '四月', '五月'],
      
      // 最小/最大索引
      min: 0,
      max: 4,
      
      // 标题
      title: {
        display: true,
        text: '月份'
      },
      
      // 刻度
      ticks: {
        color: '#666',
        font: { size: 12 }
      },
      
      // 网格线
      grid: {
        display: false
      }
    }
  }
};

时间坐标轴 #

javascript
// 需要安装适配器
// npm install chart.js date-fns

import 'chartjs-adapter-date-fns';

const options = {
  scales: {
    x: {
      type: 'time',
      
      // 时间单位:'millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'
      time: {
        unit: 'day',
        displayFormats: {
          millisecond: 'HH:mm:ss.SSS',
          second: 'HH:mm:ss',
          minute: 'HH:mm',
          hour: 'HH:mm',
          day: 'MMM d',
          week: 'MMM d',
          month: 'MMM yyyy',
          quarter: 'MMM yyyy',
          year: 'yyyy'
        },
        tooltipFormat: 'yyyy-MM-dd HH:mm'
      },
      
      // 最小/最大时间
      min: '2024-01-01',
      max: '2024-12-31'
    }
  }
};

对数坐标轴 #

javascript
const options = {
  scales: {
    y: {
      type: 'logarithmic',
      
      // 对数坐标轴配置
      ticks: {
        callback: (value, index, ticks) => {
          if (value === 10 || value === 100 || value === 1000 || value === 10000) {
            return value.toLocaleString();
          }
        }
      }
    }
  }
};

动画配置 #

基本动画 #

javascript
const options = {
  animation: {
    // 是否启用动画
    // true: 启用默认动画
    // false: 禁用动画
    // 'active': 只在初始渲染时启用
    // 'resize': 只在调整大小时启用
    // 'none': 禁用所有动画
    // 'default': 默认动画
    
    // 动画持续时间(毫秒)
    duration: 1000,
    
    // 缓动函数
    easing: 'easeInOutQuart',
    
    // 延迟
    delay: (context) => {
      return context.dataIndex * 100;
    },
    
    // 循环
    loop: false
  }
};

缓动函数 #

javascript
const easingFunctions = [
  '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'
];

const options = {
  animation: {
    easing: 'easeOutBounce'
  }
};

属性动画 #

javascript
const options = {
  animation: {
    // 数字属性动画
    numbers: {
      properties: ['x', 'y', 'borderWidth', 'radius', 'tension'],
      duration: 1000,
      easing: 'easeInOutQuart'
    },
    
    // 颜色属性动画
    colors: {
      properties: ['color', 'borderColor', 'backgroundColor'],
      duration: 1000,
      easing: 'easeInOutQuart'
    },
    
    // 显示/隐藏动画
    show: {
      colors: {
        from: 'transparent'
      },
      visible: {
        type: 'show',
        duration: 500
      }
    },
    
    hide: {
      colors: {
        to: 'transparent'
      },
      visible: {
        type: 'hide',
        duration: 500
      }
    }
  }
};

动画回调 #

javascript
const options = {
  animation: {
    onComplete: (animation) => {
      console.log('动画完成');
    },
    
    onProgress: (animation) => {
      console.log('动画进度:', animation.currentStep / animation.numSteps);
    }
  }
};

禁用动画 #

javascript
// 完全禁用
const options = {
  animation: false
};

// 或者
const options = {
  animation: {
    duration: 0
  }
};

// 只在初始渲染时禁用
const options = {
  animation: {
    duration: {
      x: 0,
      y: 1000
    }
  }
};

过渡配置 #

javascript
const options = {
  transitions: {
    // 活动状态过渡
    active: {
      animation: {
        duration: 400
      }
    },
    
    // 显示过渡
    show: {
      animation: {
        duration: 500
      }
    },
    
    // 隐藏过渡
    hide: {
      animation: {
        duration: 500
      }
    },
    
    // 调整大小过渡
    resize: {
      animation: {
        duration: 0
      }
    },
    
    // 重置过渡
    reset: {
      animation: {
        duration: 0
      }
    },
    
    // 默认过渡
    default: {
      animation: {
        duration: 1000
      }
    }
  }
};

元素配置 #

全局元素配置 #

javascript
// 点元素
Chart.defaults.elements.point = {
  radius: 3,
  hoverRadius: 5,
  pointStyle: 'circle',
  backgroundColor: 'rgba(0, 0, 0, 0.1)',
  borderColor: 'rgba(0, 0, 0, 0.1)',
  borderWidth: 1,
  hitRadius: 1,
  hoverBorderWidth: 1
};

// 线元素
Chart.defaults.elements.line = {
  tension: 0.4,
  borderWidth: 3,
  borderColor: 'rgba(0, 0, 0, 0.1)',
  borderCapStyle: 'butt',
  borderDash: [],
  borderDashOffset: 0,
  borderJoinStyle: 'miter',
  fill: true,
  backgroundColor: 'rgba(0, 0, 0, 0.1)',
  stepped: false
};

// 柱形元素
Chart.defaults.elements.bar = {
  backgroundColor: 'rgba(0, 0, 0, 0.1)',
  borderColor: 'rgba(0, 0, 0, 0.1)',
  borderWidth: 0,
  borderRadius: 0,
  borderSkipped: 'start'
};

// 弧形元素
Chart.defaults.elements.arc = {
  backgroundColor: 'rgba(0, 0, 0, 0.1)',
  borderColor: '#fff',
  borderWidth: 2,
  borderRadius: 0,
  offset: 0
};

实例元素配置 #

javascript
const options = {
  elements: {
    point: {
      radius: 5,
      hoverRadius: 8,
      pointStyle: 'star'
    },
    line: {
      tension: 0.4,
      borderWidth: 2
    },
    bar: {
      borderRadius: 4
    },
    arc: {
      borderWidth: 1
    }
  }
};

配置合并策略 #

配置优先级 #

text
实例配置 > 图表类型默认配置 > 全局默认配置

深度合并 #

javascript
// 全局配置
Chart.defaults.plugins.title.display = true;
Chart.defaults.plugins.title.color = '#333';

// 实例配置
const options = {
  plugins: {
    title: {
      text: '自定义标题',
      color: '#ff0000'  // 覆盖全局颜色
    }
  }
};

// 最终配置
// {
//   display: true,      // 来自全局
//   text: '自定义标题', // 来自实例
//   color: '#ff0000'    // 来自实例(覆盖)
// }

配置最佳实践 #

1. 使用配置对象 #

javascript
// 好的做法:分离配置
const chartConfig = {
  type: 'bar',
  data: chartData,
  options: chartOptions
};

const myChart = new Chart(ctx, chartConfig);

2. 复用配置 #

javascript
// 基础配置
const baseOptions = {
  responsive: true,
  maintainAspectRatio: false,
  plugins: {
    legend: {
      position: 'top'
    }
  }
};

// 扩展配置
const barOptions = {
  ...baseOptions,
  plugins: {
    ...baseOptions.plugins,
    title: {
      display: true,
      text: '柱状图'
    }
  }
};

3. 动态配置 #

javascript
function createChart(type, data, customOptions = {}) {
  const defaultOptions = {
    responsive: true,
    plugins: {
      legend: {
        display: true
      }
    }
  };
  
  return new Chart(ctx, {
    type,
    data,
    options: {
      ...defaultOptions,
      ...customOptions,
      plugins: {
        ...defaultOptions.plugins,
        ...customOptions.plugins
      }
    }
  });
}

下一步 #

现在你已经掌握了 Chart.js 的配置选项,接下来学习 图表类型,了解各种图表的特点和用法!

最后更新:2026-03-28