如何在Chart.js的甜甜圈图中使用径向CanvasGradients?

dotnet木匠

我正在尝试创建两个径向渐变以与Charts.js甜甜圈图一起使用

渐变看起来应该像下面的图片,但为红色。
在此处输入图片说明

createRadialGradient使用香草javascript和DOM创建渐变()非常简单,如下面的代码片段所示:

'use strict'

const red = "hsla(1, 73.7%, 38.8%, 1)"
const redDark = "hsla(1, 60%, 30%, 1)"
const redDarker = "hsla(1, 20%, 20%, 1)"
const redLight = "hsla(1, 73.7%, 48%, 1)"

const canvasList = document.querySelectorAll('canvas.vanilla')

var {ctx, gradient} = createGradient1(canvasList[0].getContext('2d'))
ctx.fillStyle = gradient
drawRect(ctx)

var {ctx, gradient} = createGradient1(canvasList[1].getContext('2d'))
ctx.strokeStyle = gradient
ctx.lineWidth = 42
drawArc(ctx)

var {ctx, gradient} = createGradient2(canvasList[2].getContext('2d'))
ctx.fillStyle = gradient
drawRect(ctx)

var {ctx, gradient} = createGradient2(canvasList[3].getContext('2d'))
ctx.strokeStyle = gradient
ctx.lineWidth = 42
drawArc(ctx)

function createGradient1 (ctx) {
    // The inner circle is at x=110, y=90, with radius=30
    // The outer circle is at x=100, y=100, with radius=70
    // ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
    const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);

    // Add three color stops
    const innerColor = redDark
    const mainColor = red
    const outerColor = redLight
    gradient.addColorStop(0, innerColor);
    gradient.addColorStop(.04, innerColor);
    gradient.addColorStop(.05, mainColor);
    gradient.addColorStop(1, outerColor);

    return { ctx, gradient }
}
function createGradient2 (ctx) {
    // The inner circle is at x=110, y=90, with radius=30
    // The outer circle is at x=100, y=100, with radius=70
    // ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
    const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);

    // Add three color stops
    const innerColor = "hsla(1, 90%, 10%, 1)"
    const mainColor = "hsla(1, 73.7%, 20%, 1)"
    const outerColor = "transparent"
    gradient.addColorStop(0, innerColor);
    gradient.addColorStop(.04, innerColor);
    gradient.addColorStop(.05, mainColor);
    gradient.addColorStop(.7, mainColor);
    gradient.addColorStop(.73, outerColor);

    return { ctx, gradient }
}

function drawRect (ctx) {
    // ctx.fillRect(x, y, width, height)
    ctx.fillRect(20, 20, 160, 160);
}

function drawArc (ctx) {
    ctx.beginPath();
    // ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise])
    ctx.arc(100, 100, 50, 0, 2 * Math.PI);
    ctx.stroke()
}
.vanilla {
    display: inline-block;
}
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>
<canvas class="vanilla" width="180" height="180"></canvas>

但是,当我对Charts.js应用相同的2个渐变时,会得到灰色的甜甜圈。使用单个渐变不会更改结果。但是,使用两种Hsla颜色可以正常工作(red"white")。

/** @type {CanvasRenderingContext2D} */
const ctx = document.querySelector('.d-goal--canvas').getContext('2d')
const red = "hsla(1, 73.7%, 38.8%, 1)"
const { gradient1 } = createGradient1(ctx)
const { gradient2 } = createGradient2(ctx)
const donut = new Chart(ctx, {
    type: 'doughnut',
    data: {
        labels: [
            "Pledged",
            "Missing"
        ],
        datasets: [{
            label: "Donations",
            data: [420, 80],
            cubicInterpolationMode: "monotone",
            // borderColor: [red, "white"],
            // backgroundColor: [red, "white"],
            borderColor: [gradient1, gradient2],
            backgroundColor: [gradient1, gradient2],
        }]
    },
    options: {
        legend: {
            display: false
        }
    }
})

function createGradient1 (ctx) {
    // The inner circle is at x=110, y=90, with radius=30
    // The outer circle is at x=100, y=100, with radius=70
    // ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
    const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);

    // Add three color stops
    const innerColor = "hsla(1, 60%, 30%, 1)"
    const mainColor = red
    const outerColor = "hsla(1, 73.7%, 48%, 1)"
    gradient.addColorStop(0, innerColor);
    gradient.addColorStop(.04, innerColor);
    gradient.addColorStop(.05, mainColor);
    gradient.addColorStop(1, outerColor);

    return { ctx, gradient }
}
function createGradient2 (ctx) {
    // The inner circle is at x=110, y=90, with radius=30
    // The outer circle is at x=100, y=100, with radius=70
    // ctx.createRadialGradient(x0, y0, r0, x1, y1, r1)
    const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);

    // Add three color stops
    const innerColor = "hsla(1, 90%, 10%, 1)"
    const mainColor = "hsla(1, 73.7%, 20%, 1)"
    const outerColor = "transparent"
    gradient.addColorStop(0, innerColor);
    gradient.addColorStop(.04, innerColor);
    gradient.addColorStop(.05, mainColor);
    gradient.addColorStop(.7, mainColor);
    gradient.addColorStop(.73, outerColor);

    return { ctx, gradient }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas class="d-goal--canvas"></canvas>

我究竟做错了什么?

我阅读了Jelena Jovanovic的渐变教程,该教程createLinearGradient应用于折线图的线性渐变(),我看不出自己在做什么。据我所知,也许我的渐变区域是错误的,但不应导致显示灰色图表。

Charts.js文档中有一个有关颜色的部分,其中描述了如何使用颜色CanvasGradient但仅用于createLinearGradient,这使我认为这可能是Charts.js中的错误...

朦胧

问题是渐变填充样式实际应用于甜甜圈的方式。您(也是我最初的假设)是,chart.js将负责将渐变放置和缩放到适当的大小,以填充甜甜圈。好吧,事实并非如此。相反,它使用渐变在画布上的大小和位置。

为了更好地理解,让我们看一下其中一个渐变的代码:

const red = "hsla(1, 73.7%, 38.8%, 1)"
const gradient = ctx.createRadialGradient(100,100,31, 100,100,70);
const innerColor = "hsla(1, 60%, 30%, 1)"
const mainColor = red
const outerColor = "hsla(1, 73.7%, 48%, 1)"
gradient.addColorStop(0, innerColor);
gradient.addColorStop(.04, innerColor);
gradient.addColorStop(.05, mainColor);
gradient.addColorStop(1, outerColor);

这将在x = 100和y = 100处生成一个直径为140像素的渐变,例如:

现在,如果我们进一步挖掘并假设您绘制到的实际画布的大小为797 x 419像素,我们可以看到问题所在:

渐变完全超出了甜甜圈的形状!

To fix it, the gradient would need to be in the center of the doughnut and have the appropriate size to fill it entirely. A little something like this:

Well this is easier said then done because initially we don't know the exact size of the canvas as chart.js automatically stretches it to fill the browser window.

So what we can do to workaround goes a little something like this:

  • create the doughnut using chart.js but don't give it a fill yet
  • wait until chart.js fires a resize event to get the actual size of the canvas
  • calculate the dimensions of the gradients according the size of the canvas and draw it at the center
  • finally populate the backgroundColor of the doughnut with the gradients

这是一个示例(请以“整页”运行,因为我们在stackoverflow的微型预览框中没有获得正确的窗口大小):

const canvas = document.querySelector('.d-goal--canvas');
const ctx = canvas.getContext('2d')
const red = "hsla(1, 73.7%, 38.8%, 1)"
let gradient1;
let gradient2;

function createGradient1(ctx) {
  const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);

  const innerColor = "hsla(1, 60%, 30%, 1)"
  const mainColor = red
  const outerColor = "hsla(1, 73.7%, 48%, 1)"
  gradient.addColorStop(0, innerColor);
  gradient.addColorStop(.12, innerColor);
  gradient.addColorStop(.121, mainColor);
  gradient.addColorStop(1, outerColor);

  return gradient;
}

function createGradient2(ctx) {
  const gradient = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, canvas.height / 4, canvas.width / 2, canvas.height / 2, canvas.height / 2);

  const innerColor = "hsla(1, 90%, 10%, 1)"
  const mainColor = "hsla(1, 73.7%, 20%, 1)"
  const outerColor = "transparent"
  gradient.addColorStop(0, innerColor);
  gradient.addColorStop(.12, innerColor);
  gradient.addColorStop(.121, mainColor);
  gradient.addColorStop(.99, mainColor);
  gradient.addColorStop(1, outerColor);

  return gradient;
}

function resized() {
  gradient1 = createGradient1(ctx);
  gradient2 = createGradient2(ctx);
  config.data.datasets[0].backgroundColor = [gradient1, gradient2];
  donut.update();
}
var config = {
  type: 'doughnut',
  data: {
    labels: [
      "Pledged",
      "Missing"
    ],
    datasets: [{
      label: "Donations",
      data: [420, 80],
      cubicInterpolationMode: "monotone"
    }]
  },
  options: {
    onResize: resized,
    legend: {
      display: false
    }
  }
};
const donut = new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas class="d-goal--canvas"></canvas>

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Chart.js的甜甜圈图中使用径向CanvasGradients?

来自分类Dev

如何在Chart.JS的半个甜甜圈图中添加一些文本?

来自分类Dev

使用chart.js在甜甜圈图中心进行事件处理程序

来自分类Dev

如何在Angular Chart中的甜甜圈图中添加标题?

来自分类Dev

如何在Ext js饼图中的甜甜圈孔中显示总计

来自分类Dev

d3.js:如何在甜甜圈图中的标签下方添加值

来自分类Dev

如何在图表js甜甜圈图中添加FAHRENHEIT符号

来自分类Dev

我想知道如何在d3.js甜甜圈图中创建etc组

来自分类Dev

如何在角度图表的甜甜圈图中添加标题?

来自分类Dev

如何在甜甜圈图中的扇区之间进行缩进?

来自分类Dev

如何使用Chart.js在甜甜圈图的中心添加文本?

来自分类Dev

通过chart.js在多系列甜甜圈图中添加标签

来自分类Dev

如何在Chart.js中的甜甜圈图上显示标签

来自分类Dev

如何在Chart.js甜甜圈图上显示第二组标签?

来自分类Dev

如何在ggplot2中使用facet_grid制作甜甜圈图?

来自分类Dev

如何在Xamarin.android中使用oxyplot创建甜甜圈图?

来自分类Dev

如何在Xamarin.android中使用oxyplot创建甜甜圈图?

来自分类Dev

如何使用简单的html,javascript或jquery在Google提供的甜甜圈图中放入文本

来自分类Dev

如何使用响应式设计将Highchart甜甜圈图中心的HTML范围对齐?

来自分类Dev

使用Chart.js-为甜甜圈图创建图例

来自分类Dev

Chart.js使用文本工具提示问题扩展了甜甜圈

来自分类Dev

带有圆角的Chart.js甜甜圈

来自分类Dev

Chart.js甜甜圈图无法正常工作

来自分类Dev

Chart.js设置甜甜圈背景色?

来自分类Dev

Chart.js甜甜圈文本颜色

来自分类Dev

Chart.js v2:甜甜圈内甜甜圈之间的空间

来自分类Dev

如何使用easypiechart.js创建甜甜圈饼图?

来自分类Dev

如何使用c3.js自定义甜甜圈厚度?

来自分类Dev

HTML / JS画布甜甜圈图如何使用ovlerap创建圆笔画?

Related 相关文章

  1. 1

    如何在Chart.js的甜甜圈图中使用径向CanvasGradients?

  2. 2

    如何在Chart.JS的半个甜甜圈图中添加一些文本?

  3. 3

    使用chart.js在甜甜圈图中心进行事件处理程序

  4. 4

    如何在Angular Chart中的甜甜圈图中添加标题?

  5. 5

    如何在Ext js饼图中的甜甜圈孔中显示总计

  6. 6

    d3.js:如何在甜甜圈图中的标签下方添加值

  7. 7

    如何在图表js甜甜圈图中添加FAHRENHEIT符号

  8. 8

    我想知道如何在d3.js甜甜圈图中创建etc组

  9. 9

    如何在角度图表的甜甜圈图中添加标题?

  10. 10

    如何在甜甜圈图中的扇区之间进行缩进?

  11. 11

    如何使用Chart.js在甜甜圈图的中心添加文本?

  12. 12

    通过chart.js在多系列甜甜圈图中添加标签

  13. 13

    如何在Chart.js中的甜甜圈图上显示标签

  14. 14

    如何在Chart.js甜甜圈图上显示第二组标签?

  15. 15

    如何在ggplot2中使用facet_grid制作甜甜圈图?

  16. 16

    如何在Xamarin.android中使用oxyplot创建甜甜圈图?

  17. 17

    如何在Xamarin.android中使用oxyplot创建甜甜圈图?

  18. 18

    如何使用简单的html,javascript或jquery在Google提供的甜甜圈图中放入文本

  19. 19

    如何使用响应式设计将Highchart甜甜圈图中心的HTML范围对齐?

  20. 20

    使用Chart.js-为甜甜圈图创建图例

  21. 21

    Chart.js使用文本工具提示问题扩展了甜甜圈

  22. 22

    带有圆角的Chart.js甜甜圈

  23. 23

    Chart.js甜甜圈图无法正常工作

  24. 24

    Chart.js设置甜甜圈背景色?

  25. 25

    Chart.js甜甜圈文本颜色

  26. 26

    Chart.js v2:甜甜圈内甜甜圈之间的空间

  27. 27

    如何使用easypiechart.js创建甜甜圈饼图?

  28. 28

    如何使用c3.js自定义甜甜圈厚度?

  29. 29

    HTML / JS画布甜甜圈图如何使用ovlerap创建圆笔画?

热门标签

归档