kurkle / chartjs-plugin-gradient

Easy gradients for Chart.js
MIT License
33 stars 6 forks source link

Background Fill Wont Work In Vue.js 3 #37

Closed mhnayeb closed 1 year ago

mhnayeb commented 1 year ago

Hey there I was looking around and founded your great plugin! but it only work on border and it wont fill under the line chart as expected! Here is my sample and these are my dependencies I use:

PS: I'd be happy to help you fix the bug!

  "dependencies": {
    "vue": "^3.2.37",
    "vue-chartjs": "^4.1.1",
    "chartjs-plugin-gradient": "^0.5.1"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^3.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.1.0",
    "vue-tsc": "^0.40.4"
  }
import { defineComponent, h, PropType } from 'vue'
import gradient from 'chartjs-plugin-gradient';
import { Line } from 'vue-chartjs'
import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  LineElement,
  LinearScale,
  PointElement,
  CategoryScale,
  Plugin
} from 'chart.js'

ChartJS.register(
  gradient,
  Title,
  Tooltip,
  Legend,
  LineElement,
  LinearScale,
  PointElement,
  CategoryScale,
)

export default defineComponent({
  name: 'LineChart',
  components: {
    Line
  },
  props: {
    chartId: {
      type: String,
      default: 'line-chart'
    },
    width: {
      type: Number,
      default: 500
    },
    height: {
      type: Number,
      default: 400
    },
    cssClasses: {
      default: '',
      type: String
    },
    styles: {
      type: Object as PropType<Partial<CSSStyleDeclaration>>,
      default: () => {
        accentColor: 'yellow'
        backgroundColor: 'yellow'
      }
    },
    plugins: {
      type: Array as PropType<Plugin<'line'>[]>,
      default: () => []
    }
  },
  setup(props) {
    const chartData = {
      labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
      datasets: [
        {
          gradient: {
            backgroundColor: {
              axis: 'y',
              colors: {
                0: 'red',
                50: 'yellow',
                100: 'green'
              }
            },
            borderColor: {
              axis: 'x',
              colors: {
                0: '#ffcb00',
                1: 'black',
                2: '#ffcb00',
                3: 'black'
              }
            }
          },
          tension: .4,
          data: [40, 39, 30, 40, 39, 50, 40]
        }
      ]
    }

    const chartOptions = {
      responsive: true,
      maintainAspectRatio: false,
      plugins: {
        legend: {
          display: false
        },
        interaction: {
          mode: 'index',
        },
        layout: {
          padding: {
            left: 0,
            right: 0,
            top: 0,
            bottom: 0,
          },
        }
      },
      elements: {
        point: {
          radius: 0
        }
      },
    }

    return () =>
      h(Line, {
        chartData,
        chartOptions,
        chartId: props.chartId,
        width: props.width,
        height: props.height,
        cssClasses: props.cssClasses,
        styles: props.styles,
        plugins: props.plugins
      })
  }
})
mhnayeb commented 1 year ago

image

stockiNail commented 1 year ago

@mhnayeb I think the fill option in line dataset is missing and default is false. Try adding fill: true to dataset configuration

mhnayeb commented 1 year ago

Thanks for your fast response. I added the fill: true option inside datasets object and it wont work. I just followed the official documents on chartjs website and this repo but nothing worked!

new config:

datasets: [{
          fill: true,
          backgroundColor: '#f87979',
          data: [40, 39, 10, 40, 39, 80, 40],
          gradient: {
            backgroundColor: {
              axis: 'y',
              colors: {
                0: 'red',
                50: 'red',
                100: 'red'
              }
            },
            borderColor: {
              axis: 'x',
              colors: {
                0: 'purple',
                1: 'red',
                2: 'purple',
                3: 'red'
              }
            }
          }
}]
stockiNail commented 1 year ago

Can you provide a reproducible sample? I have created a codepen and is working: https://codepen.io/stockinail/pen/ZEoKqVa

mhnayeb commented 1 year ago

It easier for me to recreate it in codesandbox I replicated that exact problem there! here is the link: https://codesandbox.io/s/chartjs-background-gradient-ujmkv0?file=/src/components/lineChart.ts

it works great outside of vue.js environment or in your example! it only break inside of vue.js environment

stockiNail commented 1 year ago

Found it.

The fill of the area is based on filler plugin is not included and register in your sample (I didn't recognize it reading your code).

import {
  Chart as ChartJS,
  Title,
  Tooltip,
  Legend,
  LineElement,
  LinearScale,
  PointElement,
  CategoryScale,
  Plugin,
  Filler // <--MUST be added
} from "chart.js";

ChartJS.register(
  Title,
  Tooltip,
  Legend,
  LineElement,
  LinearScale,
  PointElement,
  CategoryScale,
  gradient,
  Filler  // <--MUST be added
);
kurkle commented 1 year ago

I filed an issue to the Chart.js repo about this: https://github.com/chartjs/Chart.js/issues/10700