Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    sjnims

    chartjs-advanced

    sjnims/chartjs-advanced
    Design
    5 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    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",...

    SKILL.md

    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
    Recommended Servers
    Excel
    Excel
    Svelte
    Svelte
    Google Sheets
    Google Sheets
    Repository
    sjnims/chartjs-expert
    Files