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

Gradient not applied #114

Closed
stockiNail opened this issue Feb 11, 2019 · 12 comments
Closed

Gradient not applied #114

stockiNail opened this issue Feb 11, 2019 · 12 comments

Comments

@stockiNail
Copy link
Contributor

I'm trying to apply a gradient as background color to labels but it doesn't work.

Here is code, based on data labels sample:

<script id="script-init">
var ctx = document.getElementById('chart-0').getContext("2d");
var gradientStroke = ctx.createLinearGradient(500, 0, 100, 0);
gradientStroke.addColorStop(0, "#80b6f4");
gradientStroke.addColorStop(1, "#f49080");

	var DATA_COUNT = 8;
	var labels = [];
	Samples.srand(8);

	for (var i = 0; i < DATA_COUNT; ++i) {
		labels.push('' + i);
	}

	Chart.helpers.merge(Chart.defaults.global, {
		aspectRatio: 4/3,
		tooltips: false,
		layout: {
			padding: {
				top: 42,
				right: 16,
				bottom: 32,
				left: 8
			}
		},
		elements: {
			line: {
				fill: false
			}
		},
		plugins: {
			legend: false,
			title: false
		}
	});
</script>

<script id="script-construct">
var chart = new Chart('chart-0', {
	type: 'line',
	data: {
		labels: labels,
		datasets: [{
			backgroundColor: gradientStroke,
			borderColor: gradientStroke,
			data: Samples.numbers({
				count: DATA_COUNT,
				min: 0,
				max: 100
			})
		}]
	},
	options: {
		plugins: {
			datalabels: {
					backgroundColor: function(context) {
						return gradientStroke;
					},
					borderRadius: 4,
					color: 'white',
					font: {
						weight: 'bold'
					},
					formatter: Math.round
				}
			},
			scales: {
				yAxes: [{
					stacked: true
				}]
			}
		}
	});
</script>

Here is the result:

canvas

There is a similar issue in Chart.js, fixed in the master .

@stockiNail
Copy link
Contributor Author

@simonbrunel I see you marked this issue as Enhancement. But reading the published documentation:

Style Options

Style options are usually inputs for fillStyle or strokeStyle.

The following values are supported:

Therefore my expectation was that capability was already ready and then this is a bug and not an enhancement. Am I wrong?

@simonbrunel
Copy link
Member

@stockiNail I flagged this ticket but forgot to reply, sorry. This is already implemented but the gradient is applied locally to each label, not globally and I guess that's why you don't see it. Both use cases are valid so that's why I don't consider your request as a bug but as an enhancement.

@stockiNail
Copy link
Contributor Author

Perfect
I am gonna test it as you said
Thanks a lot

@stockiNail
Copy link
Contributor Author

@stockiNail I flagged this ticket but forgot to reply, sorry. This is already implemented but the gradient is applied locally to each label, not globally and I guess that's why you don't see it. Both use cases are valid so that's why I don't consider your request as a bug but as an enhancement.

I did some tests.

Setting globally and it does not work (as written above):

Chart.defaults.global.plugins.datalabels.backgroundColor = gradientStroke;

Chart.helpers.merge(Chart.defaults.global.plugins.datalabels, {
	backgroundColor: gradientStroke
});

Then we have already seen that setting the gradient at chart options level (both directly or by callback) it does not work.

Then, thinking about the reply (where locally is mentioned), I did a test setting a dataset as following:

datasets: [{
	backgroundColor: gradientStroke,
	borderColor: gradientStroke,
	data: Samples.numbers({
	count: DATA_COUNT,
	min: 0,
	max: 100
	}),
	datalabels: {
	      backgroundColor: gradientStroke
	}
}]

But it does not work, also using the callback.
I don't understand what does it mean the gradient is applied locally to each label, not globally because, by my tests and using your sample, it does not work at all levels of options configuration.

Is there any sample to have a look?

@simonbrunel
Copy link
Member

I agree that my previous comment is confusing. What I mean by "local" is that the gradient coordinates are relative the the label coordinates (example), not relative to the canvas coordinates (global).

So currently, it's not possible to implement your use case (thus the "enhancement").

@stockiNail
Copy link
Contributor Author

Ah ok, now I've understood. THANK YOU

About my use case, nop, I can wait. I'll release my project in next days, adding this condition for using gradients.

@simonbrunel
Copy link
Member

In the meantime, here is a "non ideal" workaround if you use (or want to use) a color lib such as chroma, etc., you could interpolate the background color using scriptable options (jsfiddle).

@stockiNail
Copy link
Contributor Author

Thank you for feedback and examples! VERY HELPFUL!!! And the workaround is not so bad... I'm gonna to implement it!

Let me share the context. I'm developing a GWT wrapper for CHART.JS (named Charba and you recognize parts of documentation) where I've included Datalabels as component.

My use case is not a specific need (in fact I used your public sample) but I'd like to provide the right guidelines for developers who are using Datalabels in Charba in their projects and use gradients! ;)

And eithers your samples are very helpful to me!!

Chroma sounds interesting... I'll have a look !! Thanks again

@stockiNail
Copy link
Contributor Author

I'm gonna add your samples in the showcase to show how to use gradients with the plugin!
Thank you

@stockiNail
Copy link
Contributor Author

@simonbrunel just FYI. I used your first sample and it works by Charba.

This is not an issue but an enhancement, fully agree

dlgradients

@simonbrunel
Copy link
Member

Thanks @stockiNail for the extra details about the context, it looks really great.

@stockiNail
Copy link
Contributor Author

FYI I have added the way to get the color from a gradient as you did by Chroma. THKS! Really appreciated! In this way I've got also another workaround.

gradient3

I've update the sample in jsfiddle as following:

 backgroundColor: function(ctx) {
       var count = ctx.dataset.data.length;
       var ratio = count > 1 ? ctx.dataIndex / (count-1) : 0;
       return chroma.mix(c1, c0, ratio);
 },

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