Echarts custom graphics, method reference

In a front-end large-screen project, there is a module that uses a custom pseudo 3D column chart composed of three faces. Record it here for reference when you customize it later. It involves some methods in zrender, and I went to zrender to read some examples and documents.

1. The final effect of custom graphics is as follows:

The graph consists of three faces, and three shapes need to be defined. Use cubeleft, cubetop, cuberight to define the left side, top side and right side respectively.

2. Register custom graphics

 echarts official documentation: Documentation - Apache ECharts

We need to define such a class, and then register this class through echarts, and then use it through the class name.

3.extendShape

            // 绘制左侧面
            const CubeLeft = echarts.graphic.extendShape({
                    shape: {
                        x: 0,
                        y: 0
                    },
                    buildPath: function(ctx, shape) {
                        const xAxisPoint = shape.xAxisPoint
                        const c0 = [shape.x, shape.y]
                        const c1 = [shape.x - 13, shape.y - 13]
                        const c2 = [xAxisPoint[0] - 13, xAxisPoint[1] - 13]
                        const c3 = [xAxisPoint[0], xAxisPoint[1]]
                        ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath()
                    }
             })
            // 绘制右侧面
            const CubeRight = echarts.graphic.extendShape({
                    shape: {
                        x: 0,
                        y: 0
                    },
                    buildPath: function(ctx, shape) {
                        const xAxisPoint = shape.xAxisPoint
                        const c1 = [shape.x, shape.y]
                        const c2 = [xAxisPoint[0], xAxisPoint[1]]
                        const c3 = [xAxisPoint[0] + 18, xAxisPoint[1] - 9]
                        const c4 = [shape.x + 18, shape.y - 9]
                        ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
                    }
                })
            // 绘制顶面
            const CubeTop = echarts.graphic.extendShape({
                    shape: {
                        x: 0,
                        y: 0
                    },
                    buildPath: function(ctx, shape) {
                        const c1 = [shape.x, shape.y]
                        const c2 = [shape.x + 18, shape.y - 9]
                        const c3 = [shape.x + 5, shape.y - 22]
                        const c4 = [shape.x - 13, shape.y - 13]
                        ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
                    }
             })

 This code is mainly to see how to use the buildpath. In the official documentation of zrender, it does not directly tell what the two parameters of this method are used for. It only gives an example. From this example, you can know how these two parameters are used. use.

Example URLs: https://github.com/ecomfe/zrender/blob/master/test/pin.html icon-default.png?t=LA92https://github.com/ecomfe/zrender/blob/master/test/pin.html

 

The first parameter is path, and the second parameter is shape. path can be understood as a drawing brush in a canvas, which can set the path and close the path.

The second parameter in echarts is passed by the custom custom, so we can get a very familiar attribute xAxisPoint through this object.

Of the two faces drawn, only the left and right sides need to have a fill height, and the top does not, so the top shape does not use the xAxisPoint attribute.

This is also very understandable, because the filling in our custom pseudo cylinder must have a height. The amount of padding is based on our data, making it look like it's actually being filled from the bottom by something.

Take the simpler top as an example:

buildPath: function(ctx, shape) {
    const c1 = [shape.x, shape.y]
    const c2 = [shape.x + 18, shape.y - 9]
    const c3 = [shape.x + 5, shape.y - 22]
    const c4 = [shape.x - 13, shape.y - 13]
    ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0],c4[1]).closePath()
}

The drawn quadrilateral is actually four vertices. We only need to use moveTo to control the path, and close it at the last point. The offset is a fixed value, and you can set different values ​​according to the situation to distort the quadrilateral.

where c1 is the bottom vertex, c2 is the right vertex, c3 is the top vertex, and c4 is the right vertex. The other two sides are also similar.

4. Use echarts to register these three graphics

                // 注册三个面图形
            echarts.graphic.registerShape('CubeLeft', CubeLeft)
            echarts.graphic.registerShape('CubeRight', CubeRight)
            echarts.graphic.registerShape('CubeTop', CubeTop)

5. Use custom shapes

Other data are the same as normal use of echarts, the difference lies in the configuration of series.

In the series array, a total of two objects are placed. The first object is as follows:

{
                type: 'custom',
                renderItem: function(params, api) {
                    const location = api.coord([api.value(0), api.value(1)])
                    return {
                        type: 'group',
                        children: [{
                            type: 'CubeLeft',
                            shape: {
                                api,
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: 'rgba(47,102,192,.27)',
                                stroke: 'black'
                            },
                            z2: 999
                        }, {
                            type: 'CubeRight',
                            shape: {
                                api,
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: 'rgba(59,128,226,.27)',
                                stroke: 'black'
                            },
                            z2: 999
                        }, {
                            type: 'CubeTop',
                            shape: {
                                api,
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: 'rgba(72,156,221,.27)',
                                stroke: 'black'
                            },
                            z2: 999
                        }]
                    }
                },
                data: MAX
}

The most important thing is the logic in renderItem. This method returns an object, which is a group we customized. The objects that renderItem can return are described in the documentation: Documentation - Apache ECharts

The three faces we defined need to be considered as a whole, so renderItem returns an object of type group, and the other three shapes are stored in the array as children.

The shape parameter will be used in the buildpath.

Its fill color and border line color are set in style. Then use z2 to define the display level of this echarts as the top level. If you don't use it, the padding below will cover it up.

Here, only the first custom shape is defined, which is the outermost pseudo 3d cylinder. The second custom shape is the shape to fill.

{
                type: 'custom',
                renderItem: (params, api) => {
                    const location = api.coord([api.value(0), api.value(1)])
                    var color = new echarts.graphic.LinearGradient(
                        0, 0, 0, 1, [{
                                offset: 1,
                                color: "#FEFD53"
                            },
                            {
                                offset: 0,
                                color: "#f7c824"
                            }
                        ]
                    );
                    return {
                        type: 'group',
                        children: [{
                            type: 'CubeLeft',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: color,
                                stroke: 'red'
                            }
                        }, {
                            type: 'CubeRight',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: color,
                                stroke: 'red'
                            }
                        }, {
                            type: 'CubeTop',
                            shape: {
                                api,
                                xValue: api.value(0),
                                yValue: api.value(1),
                                x: location[0],
                                y: location[1],
                                xAxisPoint: api.coord([api.value(0), 0])
                            },
                            style: {
                                fill: color,
                                stroke: 'red'
                            }
                        }]
                    }
                },
                data: VALUE
}

 The internally filled graphics are filled with a linear gradient color. Use red for border lines. The difference from the first one is the style in style and the data used by data. The data here uses the specific value of value. The data used by the graphics of the shell is the max value. In this way, there will be a red border graphic filled with gradient color, filled into a black border cylinder.

In this way, a visual 3D cylinder-shaped chart is customized.

Guess you like

Origin blog.csdn.net/GhostPaints/article/details/122057968