ctx.fillStyle will be assigned with an ECharts-style gradient object

n9vozmp4  于 2022-11-03  发布在  Echarts
关注(0)|答案(3)|浏览(128)

Version

5.0.2

https://codepen.io/marcong95/pen/mdOqeLo?editors=0011

Steps to reproduce

Draw a line chart with a linear gradient as areaStyle, sometime, ctx.fillStyle will be assigned with an object which is illegal for CanvasRenderingContext2D. Then it will set to a legal one soon.

It's ok somehow when using ECharts in browser, but when I use it in uni-app with mpvue-echarts, which all the canvas operations will be proxied by uni-app. It throws an error, cuz fillStyle is in illegal value type.

What is expected?

ctx.fillStyle is only accepts one of the following:

A DOMString parsed as CSS value;
A CanvasGradient object (a linear or radial gradient);
A CanvasPattern object (a repeating image).

according to: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle

What is actually happening?

ctx.fillStyle was assigned with an ECharts-style gradient object like:

{
  "colorStops": [
    {
      "offset": 0,
      "color": "#3875f6"
    },
    {
      "offset": 1,
      "color": "#c0e4fc"
    }
  ],
  "x": 0,
  "y": 0,
  "x2": 0,
  "y2": 1,
  "type": "linear",
  "global": false
}

For whom may meet the same issue, which use ECharts in uni-app following https://ask.dcloud.net.cn/article/38568 :

Exception like the following may be thrown:

TypeError: Invalid attempt to spread non-iterable instance.
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.

You can do the following modification for temporary fix:

in Line 36 of wx-canvas.js, there is an Object.defineProperty invocation, replace it with

Object.defineProperty(ctx, style, {
        set: (value) => {
          if ((style !== 'fillStyle' && style !== 'strokeStyle') ||
            (value !== 'none' && value !== null)
          ) {
            if (style === 'fillStyle' && value.type && !value.data) {
              const { type, x, y, x2, y2, colorStops } = value;
              switch (type) {
                case 'linear':
                  value = {
                    type,
                    data: [x, y, x2, y2],
                    colorStop: colorStops
                  };
                  break;
                default:
                  console.error(
                    'fillStyle set with non-uni gradient object',
                    style, value);
              }
              return;
            }
            ctx[`set${style.charAt(0).toUpperCase()}${style.slice(1)}`](value);
          }
        }
      });

If you want to use other types of gradient like radial gradient, you may have to modify it accordingly yourself

wlsrxk51

wlsrxk511#

Hi! We've received your issue and please be patient to get responded. 🎉
The average response time is expected to be within one day for weekdays.

In the meanwhile, please make sure thatyou have posted enough image to demo your request. You may also check out the API and chart option to get the answer.

If you don't get helped for a long time (over a week) or have an urgent question to ask, you may also send an email to dev@echarts.apache.org . Please attach the issue link if it's a technical question.

If you are interested in the project, you may also subscribe our mailing list .

Have a nice day! 🍵

zy1mlcev

zy1mlcev2#

@marcong95 Hi, since you are using uni-app, you should debug with your code to check if ctx.fillStyle is set to be the CanvasLinearGradient instance rather than the gradient object. It should be like the following code but based on the version of ECharts you are using, it could be a little different.

j2qf4p5b

j2qf4p5b3#

@marcong95 Can you give more information about how we could reproduce this case? For example, can you debug to see when was fillStyle set to be the option object?

相关问题