首页 > 其他 > 详细

解决echarts使用renderItem自定义图表时的残影问题

时间:2021-05-26 21:57:48      阅读:51      评论:0      收藏:0      [点我收藏+]

公司有一个需求是绘制人员的排班任务甘特图,因为有大量自定义元素和复杂交互,在初版时采用dom+Virtual List的办法来做,显示和交互的效果都不错,但是一旦数据量大的时候,就算是Virtual List在滚动时都会很卡,于是就有了通过echarts使用canvas来绘制甘特图的想法,主要是通过echarts的renderItem自定义图表来展示,于是开始踩坑。

option

yAxis: {
  type: ‘value‘
}.
xAxis: {
  type: ‘time‘
}
series: [
    {
        id: ‘flightData‘,
        type: ‘custom‘,
        renderItem: this.renderGanttItem,
        dimensions: [null, { type: ‘time‘ }, { type: ‘time‘ }, { type: ‘ordinal‘ }],
        encode: {
            x: [1, 2],
            y: 0,
        },
        data: echarts.util.map(_missions, (item, index) => {
            let startTime = new Date(this.root.options.startTime)
            let endTime = new Date(this.root.options.endTime)
            return [index, startTime, endTime].concat(item);
        }),
    },
    {
        type: ‘custom‘,
        renderItem: this.renderAxisLabelItem,
        dimensions: [null, { type: ‘ordinal‘ }],
        encode: {
            x: -1, // Then this series will not controlled by x.
            y: 0
        },
        data: echarts.util.map(_staffList, function (item, index) {
            return [index].concat(item);
        }),
    }
],
dataZoom:[
    {
        id: ‘slider_x‘,
        type: ‘slider‘,
        xAxisIndex: 0,
        filterMode: ‘none‘,
        height: 20,
        bottom: 0,
        start: this.zoom.x_left,
        end: this.zoom.x_right,
        handleIcon: dragIcon,
        handleSize: ‘80%‘,
        showDetail: false,
        backgroundColor:‘#E4E7ED9E‘,
        throttle: 100
    },
    {
        id: ‘slider_y‘,
        type: ‘slider‘,
        filterMode: ‘weakFilter‘,
        fillerColor:‘#d2d9e4‘,
        yAxisIndex: 0,
        zoomLock: true,
        width: 20,
        right: 0,
        start: this.zoom.y_top,
        end: this.zoom.y_bottom,
        handleSize: 0,
        showDetail: false,
        backgroundColor:‘#E4E7ED9E‘,
        throttle: 100
    },
    {
        type: ‘inside‘,
        id: ‘insideX‘,
        xAxisIndex: 0,
        throttle: 100,
        zoomOnMouseWheel: false,
        moveOnMouseMove: true
    },
    {
        type: ‘inside‘,
        id: ‘insideY‘,
        yAxisIndex: 0,
        throttle: 100,
        zoomOnMouseWheel: false,
        moveOnMouseMove: true,
        moveOnMouseWheel: true
    }
]

 

这时候碰到问题:renderGanttItem返回的元素group数量是变化的,因为时间轴的移动,显示的元素在不停变化,元素数量当然在变化,echarts对于减少和新增的元素,在界面上会出现残影、动画跳动的问题。参考了文档严格定义了唯一的series-custom.renderItem.return_rect.id也不能解决。

解决办法一

通过设置series-custom.renderItem.return_rect.ignore,节点是否完全被忽略(既不渲染,也不响应事件)。当视口离开元素时,把元素的ignore设置为true,当元素一定出现添加和减少时,先 调用this.myChart.clear(),保证不会在renderItem中有元素增减。

这个办法有用,但是碰到每行元素很多的时候,就算时设置了ignore,也可以看到卡顿,没有canvas对比dom的流畅,只能修改dataZoom-slider.throttle增加节流来减少卡顿。

解决办法二

通过查看源码,看到这样一段注释:

// Usage:
// (1) By default, `elOption.$mergeChildren` is `‘byIndex‘`, which indicates that
//     the existing children will not be removed, and enables the feature that
//     update some of the props of some of the children simply by construct
//     the returned children of `renderItem` like:
//     `var children = group.children = []; children[3] = {opacity: 0.5};`
// (2) If `elOption.$mergeChildren` is `‘byName‘`, add/update/remove children
//     by child.name. But that might be lower performance.
// (3) If `elOption.$mergeChildren` is `false`, the existing children will be
//     replaced totally.
// (4) If `!elOption.children`, following the "merge" principle, nothing will happen.
//
// For implementation simpleness, do not provide a direct way to remove sinlge
// child (otherwise the total indicies of the children array have to be modified).
// User can remove a single child by set its `ignore` as `true` or replace
// it by another element, where its `$merge` can be set as `true` if necessary.

 

在renderItem返回的group元素中设置$mergeChildren=‘byName‘,并且给每一类元素设置一个name,这样每次都会根据name来更新元素

renderGanttItem = (params, api) => {
   ...

    return {
      type: ‘group‘,
      name: ‘gantt-group‘,
      id: categoryIndex,
      info: {data:item},
      children: allChildren,
      $mergeChildren: ‘byName‘
    };

}

这样设置了以后,大量元素滚动也非常顺滑,解决问题

解决echarts使用renderItem自定义图表时的残影问题

原文:https://www.cnblogs.com/mesopotamiaa/p/14813917.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!