chartjs-advanced
This skill should be used when the user asks "Chart.js gradients", "Chart.js linear gradient", "Chart.js radial gradient", "custom Chart.js chart type", "extend Chart.js", "derived chart type", "custom Chart.js scale", "Chart.js programmatic events", "Chart.js setActiveElements", "Chart.js custom controller", or needs help with advanced Chart.js v4.5.1 techniques.
安装与使用
请根据来源仓库和你的 AI 工具说明安装此技能。先阅读技能文件和依赖要求,再添加到工作流。
查看来源 ↗使用指南技能说明
Chart.js Advanced Techniques (v4.5.1)
Guide to advanced Chart.js customization including gradients, custom chart types, and programmatic control.
Gradients
Create visual depth with linear and radial gradients.
Linear Gradients
const ctx = document.getElementById('myChart').getContext('2d');
// Create gradient
const gradient = ctx.createLinearGradient(0, 0, 0, 400);
gradient.addColorStop(0, 'rgba(75, 192, 192, 1)');
gradient.addColorStop(0.5, 'rgba(75, 192, 192, 0.5)');
gradient.addColorStop(1, 'rgba(75, 192, 192, 0.1)');
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
datasets: [{
label: 'Sales',
data: [12, 19, 3, 5, 2],
backgroundColor: gradient,
borderColor: 'rgb(75, 192, 192)',
fill: true
}]
}
});
Dynamic Gradients (Responsive)
function createGradient(ctx, chartArea) {
const gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, 'rgba(54, 162, 235, 0)');
gradient.addColorStop(1, 'rgba(54, 162, 235, 1)');
return gradient;
}
const chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar'],
datasets: [{
label: 'Revenue',
data: [10, 20, 30],
backgroundColor: function(context) {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) {
return null; // Chart not initialized yet
}
return createGradient(ctx, chartArea);
}
}]
}
});
Radial Gradients
function createRadialGradient(ctx, chartArea) {
const width = chartArea.right - chartArea.left;
const height = chartArea.bottom - chartArea.top;
const centerX = (chartArea.left + chartArea.right) / 2;
const centerY = (chartArea.top + chartArea.bottom) / 2;
const r = Math.min(width, height) / 2;
const gradient = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, r);
gradient.addColorStop(0, 'rgba(255, 99, 132, 1)');
gradient.addColorStop(0.5, 'rgba(255, 99, 132, 0.5)');
gradient.addColorStop(1, 'rgba(255, 99, 132, 0)');
return gradient;
}
// Use with pie/doughnut charts
datasets: [{
data: [300, 50, 100],
backgroundColor: function(context) {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) return null;
return createRadialGradient(ctx, chartArea);
}
}]
Multi-Dataset Gradients
const gradients = [
{ start: 'rgba(255, 99, 132, 1)', end: 'rgba(255, 99, 132, 0.1)' },
{ start: 'rgba(54, 162, 235, 1)', end: 'rgba(54, 162, 235, 0.1)' },
{ start: 'rgba(255, 206, 86, 1)', end: 'rgba(255, 206, 86, 0.1)' }
];
datasets: gradients.map((colors, i) => ({
label: `Dataset ${i + 1}`,
data: data[i],
backgroundColor: function(context) {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) return null;
const gradient = ctx.createLinearGradient(0, chartArea.bottom, 0, chartArea.top);
gradient.addColorStop(0, colors.end);
gradient.addColorStop(1, colors.start);
return gradient;
}
}))
Custom Chart Types
Extend existing chart types or create new ones.
Extending Bar Controller
import {Chart, BarController} from 'chart.js';
class CustomBarController extends BarController {
// Override draw method
draw() {
super.draw();
// Add custom drawing
const meta = this.getMeta();
const ctx = this.chart.ctx;
meta.data.forEach(bar => {
const {x, y, base, width} = bar.getProps(['x', 'y', 'base', 'width']);
// Draw custom element
ctx.save();
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillRect(x - width/2, y - 5, width, 5);
ctx.restore();
});
}
// Override update method
update(mode) {
const meta = this.getMeta();
// Custom update logic
this.updateElements(meta.data, 0, meta.data.length, mode);
}
}
CustomBarController.id = 'customBar';
CustomBarController.defaults = {
...BarController.defaults,
// Add custom default options
customOption: true
};
Chart.register(CustomBarController);
// Use custom chart type
const chart = new Chart(ctx, {
type: 'customBar',
data: data
});
Creating Derived Bubble Chart
import {Chart, BubbleController} from 'chart.js';
class DerivedBubble extends BubbleController {
draw() {
// Call parent draw
super.draw();
// Add custom decoration
const meta = this.getMeta();
const firstPoint = meta.data[0];
const {x, y} = firstPoint.getProps(['x', 'y']);
const {radius} = firstPoint.options;
const ctx = this.chart.ctx;
ctx.save();
ctx.strokeStyle = this.options.boxStrokeStyle;
ctx.lineWidth = 2;
ctx.strokeRect(x - radius, y - radius, 2 * radius, 2 * radius);
ctx.restore();
}
}
DerivedBubble.id = 'derivedBubble';
DerivedBubble.defaults = {
boxStrokeStyle: 'red'
};
Chart.register(DerivedBubble);
Custom Scales
Create custom axis types.
Logarithmic Base-2 Scale
import {Chart, Scale} from 'chart.js';
class Log2Axis extends Scale {
constructor(cfg) {
super(cfg);
this.start = undefined;
this.end = undefined;
}
parse(raw, index) {
const value = +raw;
return isFinite(value) ? value : null;
}
determineDataLimits() {
const {min, max} = this.getMinMax(true);
this.min = min;
this.max = max;
}
buildTicks() {
const ticks = [];
let power = Math.floor(Math.log2(this.min));
let value = Math.pow(2, power);
while (value < this.max) {
ticks.push({value});
power++;
value = Math.pow(2, power);
}
return ticks;
}
getPixelForValue(value) {
if (value === undefined || value === 0) {
value = this.min;
}
const decimal = (Math.log2(value) - Math.log2(this.min)) / (Math.log2(this.max) - Math.log2(this.min));
return this.getPixelForDecimal(decimal);
}
getValueForPixel(pixel) {
const decimal = this.getDecimalForPixel(pixel);
return Math.pow(2, Math.log2(this.min) + decimal * (Math.log2(this.max) - Math.log2(this.min)));
}
}
Log2Axis.id = 'log2';
Log2Axis.defaults = {};
Chart.register(Log2Axis);
// Use custom scale
const chart = new Chart(ctx, {
type: 'line',
data: data,
options: {
scales: {
y: {
type: 'log2'
}
}
}
});
Programmatic Interactions
Control chart interactions via API.
Trigger Hover Programmatically
function triggerHover(chart, datasetIndex, index) {
if (chart.getActiveElements().length > 0) {
// Clear active elements
chart.setActiveElements([]);
} else {
// Set active elements
chart.setActiveElements([
{datasetIndex: 0, index: 0},
{datasetIndex: 1, index: 0}
]);
}
chart.update();
}
// Usage
triggerHover(chart, 0, 2); // Highlight first dataset, third point
Trigger Tooltip Programmatically
function triggerTooltip(chart, datasetIndex, index) {
const tooltip = chart.tooltip;
if (tooltip.getActiveElements().length > 0) {
// Hide tooltip
tooltip.setActiveElements([], {x: 0, y: 0});
} else {
// Show tooltip
const chartArea = chart.chartArea;
tooltip.setActiveElements([
{datasetIndex, index}
], {
x: (chartArea.left + chartArea.right) / 2,
y: (chartArea.top + chartArea.bottom) / 2
});
}
chart.update();
}
// Usage
triggerTooltip(chart, 0, 3); // Show tooltip for first dataset, fourth point
Simulate Click Event
function simulateClick(chart, x, y) {
const event = {
type: 'click',
x: x,
y: y,
native: {
clientX: x,
clientY: y
}
};
chart.handleEvent(event);
}
// Click center of chart
const chartArea = chart.chartArea;
const centerX = (chartArea.left + chartArea.right) / 2;
const centerY = (chartArea.top + chartArea.bottom) / 2;
simulateClick(chart, centerX, centerY);
Dynamic Updates
Advanced data update patterns.
Smooth Data Streaming
function addDataPoint(chart, label, data) {
chart.data.labels.push(label);
chart.data.datasets.forEach((dataset, i) => {
dataset.data.push(data[i]);
});
// Keep last 20 points
if (chart.data.labels.length > 20) {
chart.data.labels.shift();
chart.data.datasets.forEach(dataset => {
dataset.data.shift();
});
}
chart.update('active'); // Use active transition for smooth updates
}
// Stream data every second
setInterval(() => {
addDataPoint(chart, new Date().toLocaleTimeString(), [
Math.random() * 100,
Math.random() * 100
]);
}, 1000);
Update Without Animation
// No animation
chart.data.datasets[0].data = [10, 20, 30, 40];
chart.update('none');
// Or disable for single update
chart.update({duration: 0});
Performance Optimization
Data Decimation
options: {
plugins: {
decimation: {
enabled: true,
algorithm: 'lttb', // Largest Triangle Three Buckets
samples: 500 // Target number of samples
}
}
}
Disable Animations for Large Datasets
const dataPoints = data.datasets[0].data.length;
options: {
animation: dataPoints > 1000 ? false : {
duration: 1000,
easing: 'easeOutQuart'
}
}
Additional Resources
Examples
-
examples/gradient-backgrounds.html- Gradient pattern library (vertical, horizontal, radial, diagonal) -
examples/custom-chart-type.html- Complete custom controller example (DerivedBubble)
References
-
references/controller-api.md- Chart controller API and TypeScript declarations -
references/scale-api.md- Scale API for custom axis types -
references/performance-optimization.md- Comprehensive performance tuning guide
使用示例
查看来源仓库中的使用示例与配置说明。
查看来源 ↗来源历史
- 收录时间
- 2026-01-20
- 索引更新时间
- 2026-01-26
- Branch
- main
收录与同步日期属于本站记录。源码修改历史请查看来源仓库。
GitHub ↗chat Comments (0)
Sign in to join the discussion and leave a comment.
No comments yet. Be the first to share your thoughts!