英文:
Javascript - ChartJS Trying to change the borderColor and the fill color for negative numbers
问题
我目前正在使用ChartJs创建一个LineChart,用来表示某人的利润。这些利润可以是正数或负数。
我希望在零以上的线条是绿色的,而在零以下的线条是红色的。当数值为负数时,背景也必须是红色的。
我已经在Stackoverflow上看到了关于ChartJS先前版本的解决方案,但我认为在这个新版本中可能有更加优雅的解决方案。
我正在使用chartJs
的版本4.2.0
。
到目前为止,根据文档,我已经完成了以下工作:
const lineChartData = {
labels: [
'01/22',
'02/22',
'03/22',
'04/22',
'05/22',
'06/22',
'07/22',
'08/22',
],
datasets: [
{
label: 'Profit',
data: [2.4, 2.6, 2.23, 1.2, -2.2, -3.6, -1, 0.2],
borderColor: '#0B9564',
pointBackgroundColor: 'transparent',
pointBorderColor: 'transparent',
borderJoinStyle: 'bevel',
fill: {
target: 'origin',
above: 'rgba(11, 149, 100, 0.08)',
below: 'rgba(218, 96, 96, 0.08)',
},
},
],
};
这是当前的结果:
最后,这是我希望它看起来的预览。这只是一个模拟,所以不太准确。
你有任何想法如何能够重现这个效果吗?在文档中似乎没有提到这个问题。
英文:
I am currently creating a LineChart with ChartJs that represents someone's profits. These can be positive or negative.
I want the lines above zero to be green and the lines below to be red. Also, the background must be red when the values are negative.
I have already seen solutions with previous versions of ChartJS on Stackoverflow, however I think with this new version there may be a more elegant version to solve this problem.
I am using version 4.2.0
of chartJs
.
Here is what I have done so far following the documentation :
const lineChartData = {
labels: [
'01/22',
'02/22',
'03/22',
'04/22',
'05/22',
'06/22',
'07/22',
'08/22',
],
datasets: [
{
label: 'Profit',
data: [2.4, 2.6, 2.23, 1.2, -2.2, -3.6, -1, 0.2],
borderColor: '#0B9564',
pointBackgroundColor: 'transparent',
pointBorderColor: 'transparent',
borderJoinStyle: 'bevel',
fill: {
target: 'origin',
above: 'rgba(11, 149, 100, 0.08)',
below: 'rgba(218, 96, 96, 0.08)',
},
},
],
};
And here is the actual result:
Finally, here is a preview of what I would like it to look like. This is a mock-up, so it's not quite accurate.
Do you have any idea how I could reproduce this? It doesn't seem to me that in the documentation this problem is mentioned.
答案1
得分: 1
以下是您要翻译的内容:
"Out of the Box you won't be able to do this, the best would be something like in the example below (using the segmentation styling, and a linear color gradient).
If you really need this exact look, you could check if someone has created a plugin, or create your own plugin (or inline plugin), that would override the normal rendering. (link to plugin documentation).
Here a demo, how I would do this:
(based on the configuration, you posted)
const lineChartData = {
labels: [
'01/22',
'02/22',
'03/22',
'04/22',
'05/22',
'06/22',
'07/22',
'08/22',
],
datasets: [
{
label: 'Profit',
data: [2.4, 2.6, 2.23, 1.2, -2.2, -3.6, -1, 0.2],
borderColor: '#0B9564',
pointBackgroundColor: 'transparent',
pointBorderColor: 'transparent',
borderJoinStyle: 'bevel',
fill: {
value: -25,
above: 'rgba(11, 149, 100, 0.08)'
},
segment: {
borderColor: ctx => segmentColor(ctx, '#0B9564', 'red')
}
},
],
};
function segmentColor(ctx, color1, color2){
if(ctx.p0.parsed.y < 0 && ctx.p1.parsed.y < 0 ) {
return color2;
} else if (ctx.p0.parsed.y < 0){
var gradient = myChart.ctx.createLinearGradient(ctx.p0.x, ctx.p0.y, ctx.p1.x, ctx.p1.y);
gradient addColorStop(.5, color2);
gradient.addColorStop(1, color1);
return gradient
} else if (ctx.p1.parsed.y < 0){
var gradient = myChart.ctx.createLinearGradient(ctx.p1.x, ctx.p1.y, ctx.p0.x, ctx.p0.y);
gradient.addColorStop(.5, color2);
gradient.addColorStop(1, color1);
return gradient
}
return color1
}
const config = {
type: 'line',
data: lineChartData,
options: {
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
},
}
},
}
};
var myChart = new Chart(
document.getElementById('chart'),
config
);
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart" style="height:184px; width:350px;">
<canvas id="chart"></canvas>
</div>
英文:
Out of the Box you won't be able to do this, the best would be something like in the example below (using the segementation styling, and a linear color gradient).
If you really need this exact look, you could check if someone has created a plugin, or create your own plugin (or inline plugin), that would override the normal rendering. (link to plugin documentation).
Here a demo, how I would do this:
(based on the configuration, you posted)
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
const lineChartData = {
labels: [
'01/22',
'02/22',
'03/22',
'04/22',
'05/22',
'06/22',
'07/22',
'08/22',
],
datasets: [
{
label: 'Profit',
data: [2.4, 2.6, 2.23, 1.2, -2.2, -3.6, -1, 0.2],
borderColor: '#0B9564',
pointBackgroundColor: 'transparent',
pointBorderColor: 'transparent',
borderJoinStyle: 'bevel',
fill: {
value: -25,
above: 'rgba(11, 149, 100, 0.08)'
},
segment: {
borderColor: ctx => segmentColor(ctx, '#0B9564', 'red')
}
},
],
};
function segmentColor(ctx, color1, color2){
if(ctx.p0.parsed.y < 0 && ctx.p1.parsed.y < 0 ) {
return color2;
} else if (ctx.p0.parsed.y < 0){
var gradient = myChart.ctx.createLinearGradient(ctx.p0.x, ctx.p0.y, ctx.p1.x, ctx.p1.y);
gradient.addColorStop(.5, color2);
gradient.addColorStop(1, color1);
return gradient
} else if (ctx.p1.parsed.y < 0){
var gradient = myChart.ctx.createLinearGradient(ctx.p1.x, ctx.p1.y, ctx.p0.x, ctx.p0.y);
gradient.addColorStop(.5, color2);
gradient.addColorStop(1, color1);
return gradient
}
return color1
}
const config = {
type: 'line',
data: lineChartData,
options: {
maintainAspectRatio: false,
plugins: {
legend: {
position: 'right',
labels: {
usePointStyle: true,
},
}
},
}
};
var myChart = new Chart(
document.getElementById('chart'),
config
);
<!-- language: lang-html -->
<script src="//cdn.jsdelivr.net/npm/chart.js"></script>
<div class="chart" style="height:184px; width:350px;">
<canvas id="chart" ></canvas>
</div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论