Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Guidance on adding line shadows in v4 #11583

Open
1 of 3 tasks
JG-QuarkNet opened this issue Nov 14, 2023 · 1 comment
Open
1 of 3 tasks

Guidance on adding line shadows in v4 #11583

JG-QuarkNet opened this issue Nov 14, 2023 · 1 comment

Comments

@JG-QuarkNet
Copy link

Documentation Is:

  • Missing or needed?
  • Confusing
  • Not sure?

Please Explain in Detail...

I'm trying to upgrade a graphing app from Flot.js 0.8.3 to use Chart.js 4.4.0. The biggest sticking point is that Flot easily created drop shadows underneath the line of a chart, whereas this is proving to be nearly impossible in Chart.js.

This question has been asked many times over the years, but I can't find any clear, implementable answer for how to do it in Chart.js v4. There is zero documentation on this matter. Probably the best StackOverflow result on the topic is from 2015, which would probably be v1 or v2. In any event, it captures what seems like the three main strategies that people have developed for this:

  1. Make a Plugin
  2. Extend something
  3. Override something

On 1), I've attempted to make a Plugin using the following code:

/* The Chart.js context */
const ctx = document.getElementById('mychart');

/* The Plugin */
const lineShadowPlugin = {
    beforeDraw : function(chartInstance) {
        let _stroke = chartInstance.ctx.stroke;
        chartInstance.ctx.stroke = function () {

            chartInstance.ctx.save();

            chartInstance.ctx.shadowColor = 'gray';
            chartInstance.ctx.shadowBlur = 2;
            chartInstance.ctx.shadowOffsetX = 0.5;
            chartInstance.ctx.shadowOffsetY = 2.5;

            _stroke.apply(this, arguments)
            chartInstance.ctx.restore();
        };

        let _fill = chartInstance.ctx.fill;
        ctx.fill = function () {

            chartInstance.ctx.save();

            chartInstance.ctx.shadowColor = 'gray';
            chartInstance.ctx.shadowBlur = 10;
            chartInstance.ctx.shadowOffsetX = 2;
            chartInstance.ctx.shadowOffsetY = 2;

            _fill.apply(this, arguments)
            chartInstance.ctx.restore();
        };
    }
};

/* The Chart
let chartjs_plot = new Chart(ctx, {
    type: 'scatter',
    data: { ... },
    plugins: [lineShadowPlugin],
    options: { ... }
});

This does work to create a shadow under the line, but it also creates shadows under all of the other chart elements, which I don't want.

On 2), I've tried the code for overriding the Chart.js draw() function from this StackOverflow answer for Chart.js v2, but it results in a this.chart.chart is undefined error, which I suppose is the result of a namespace change between Chart.js v2 and v4.

I've found this issue on the topic, which was moved to a discussion. That discussion centers on overriding the draw function, but it doesn't include enough information for me to get a working chart out of it.

On 3), I've tried the code for extending Chart.types.Line from this StackOverflow answer, but it results in a Chart.types is undefined error, which I also suppose is the result of a namespace change between whatever Chart.js version it was written for and v4.

I've also found this approach for extending LineController with a custom class:

class Custom extends Chart.LineController {
    draw() {
        /* Call the line controller method to draw points */
        super.draw(arguments);

        /* custom drawing */
        const ctx = this.chart.ctx;
        let _stroke = ctx.stroke;

        ctx.stroke = function () {
            ctx.save();
            ctx.shadowColor = 'black';
            ctx.shadowBlur = 10;
            ctx.shadowOffsetX = 0;
            ctx.shadowOffsetY = 4;
            _stroke.apply(this, arguments);
            ctx.restore();
        }
    }
};

Custom.id = 'shadowline'; // chart type name
Custom.defaults = Chart.LineController.defaults;

When I implement this, there is again a drop shadow under everything, and also my data is messed up.

I also found this Chart.js feature request for exactly what I and countless others are struggling with, but which was dismissed by @LeeLenaleee as "externally implementable by plugin hooks" with no further guidance. If it's open for discussion, I strongly support making line shadows a core feature of Chart.js, given that it's an in-demand feature that's preposterously difficult for the average user to accomplish using Plugins.

This is essentially a crosspost of this StackOverflow question, which has been sitting for a month with one comment and no conclusive results.

So, how can I accomplish this? Again, the three requirements are

  1. Create a drop shadow under the line of a line or scatter plot,
  2. Not create a shadow under any other element of the chart, and
  3. Work with Chart.js v4 (specifically 4.4.0)

Thank you to everyone at Chart.js for your work on the library, and thanks in advance to anyone who can help me.

Your Proposal for Changes

Either add shadows as a core feature (feature request, preferable but already rejected) or please explain how to do this somewhere.

Example

No response

@siderakis
Copy link

+1 for documenting how a shadow effect can be added using a plugin. For a newbie to this library it might be easier to just find another library to use rather than jumping into the plugin framework/library internals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants