Javascript – ChartJS 尝试更改负数的边框颜色和填充颜色

huangapple go评论63阅读模式
英文:

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)',
        },
      },
    ],
  };

这是当前的结果:

Javascript – ChartJS 尝试更改负数的边框颜色和填充颜色

最后,这是我希望它看起来的预览。这只是一个模拟,所以不太准确。
Javascript – ChartJS 尝试更改负数的边框颜色和填充颜色

你有任何想法如何能够重现这个效果吗?在文档中似乎没有提到这个问题。

英文:

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:

Javascript – ChartJS 尝试更改负数的边框颜色和填充颜色

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.
Javascript – ChartJS 尝试更改负数的边框颜色和填充颜色

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: [
      &#39;01/22&#39;,
      &#39;02/22&#39;,
      &#39;03/22&#39;,
      &#39;04/22&#39;,
      &#39;05/22&#39;,
      &#39;06/22&#39;,
      &#39;07/22&#39;,
      &#39;08/22&#39;,
    ],
    datasets: [
      {
        label: &#39;Profit&#39;,
        data: [2.4, 2.6, 2.23, 1.2, -2.2, -3.6, -1, 0.2],
        borderColor: &#39;#0B9564&#39;,
        pointBackgroundColor: &#39;transparent&#39;,
        pointBorderColor: &#39;transparent&#39;,
        borderJoinStyle: &#39;bevel&#39;,
        fill: {
            value: -25,
            above: &#39;rgba(11, 149, 100, 0.08)&#39;
        },
        segment: {
            borderColor: ctx =&gt; segmentColor(ctx, &#39;#0B9564&#39;, &#39;red&#39;)
        }
      },
    ],
  };
  
function segmentColor(ctx, color1, color2){
    if(ctx.p0.parsed.y &lt; 0 &amp;&amp; ctx.p1.parsed.y &lt; 0 ) {
        return color2;
    } else if (ctx.p0.parsed.y &lt; 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 &lt; 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: &#39;line&#39;,
    data: lineChartData,
    options: {
        maintainAspectRatio: false,
        plugins: {
            legend: {
                position: &#39;right&#39;,
                labels: {
                    usePointStyle: true,
                },
            }
        },
    }
};

var myChart = new Chart(
    document.getElementById(&#39;chart&#39;),
    config
);

<!-- language: lang-html -->

&lt;script src=&quot;//cdn.jsdelivr.net/npm/chart.js&quot;&gt;&lt;/script&gt;  

&lt;div class=&quot;chart&quot; style=&quot;height:184px; width:350px;&quot;&gt;
    &lt;canvas  id=&quot;chart&quot; &gt;&lt;/canvas&gt;
&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年2月9日 03:10:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/75390633.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定