美文网首页
ECharts 自定义系列 profile 坐标转置

ECharts 自定义系列 profile 坐标转置

作者: Abbott思宇 | 来源:发表于2017-11-18 11:45 被阅读0次

    [TOC]

    参考资料

    ECharts 自定义系列 profile - ECharts

    背景

    希望将 ECharts 自定义系列官方提供的 profile 图表,横纵坐标进行转换。

    实现效果

    image.png

    关键点

    series-custom.encode

    encode 的作用是映射

    简单的说,就是从一个二维数组中,选择需要映射那几列数据到图表中。本例中,encode 从 data.value 中映射数据。

    option = {
        series: [{
            encode: {
                x: 0,
                y: [1, 2]
            },
            data: data
    };
    

    数据映射,有两层意思。

    • 选择使用哪些数据
    • 被选中的数据映射到画布上(类似于地图的比例尺)

    为什么说被选中的数据映射到画布上

    画布的尺寸是有限的,也是是随界面布局的变化,时时相对发生变化。

    图形(柱状图,折线图,饼图等等)在画布上的比例(相对尺寸)是一定的,那么一个具体的数值,在展现在图形上时,就需要按照一定的比例进行映射。

    以本例为例,

    画布大概只有 400*600 px

    x 轴,只有3个数据 (0,1,2)
    y 轴,上的数据很多,是基于时间戳用随机数计算出来的(例如:1510975537362),科学计数法基本上都在 10e12 这个范围。

    显然,不可能直接把数值 转化为像素,因此就需要知道 x 和 y 轴的 最大值 和
    最小值 然后把每一个具体的值映射为屏幕中的像素值。

    上面 encode 中,x 只选择 data.value 中的第一列,也就是范围 0-2;y 轴选择 data.value 中的第二、三列(即开始时间和结束时间范围)

    在数值到画布坐标映射时,调用 api.coord([x, y]) 这个方法实现。本例中详见 series-custom.renderItem 的说明

    data 的结构

    本例中,data 是由 echarts.util.each(categories, function (category, index) 生成的。data 的完整结构如下:

    data.push({
        name: typeItem.name,
        value: [
            index,
            baseTime,
            baseTime += duration,
            duration
        ],
        itemStyle: {
            normal: {
                color: typeItem.color
            }
        }
    

    series-custom.xAxis (series-custom.yAxis)

    xAxis 和 yAxis 的作用是绘制坐标轴。

    在转置的时候,坐标轴需要配套转置。

    series-custom.renderItem

    renderItem 是数据映射过程中的关键,其作用好比 excel 中的数据透视表。不同的是,renderItem 需要把图形是什么样子的,定义清楚。

    api.coord([x, y])

    在本例中,我们需要对坐标轴进行转置,因此,在一开始的时候,修改了 series-custom.encode 中的映射行为。坐标轴对应的数据发生了修改,因此,在映射具体图形坐标的时候,需要配套修改。

    var start = api.coord([categoryIndex, api.value(1)]);
    var end = api.coord([categoryIndex, api.value(2)]);
    

    api.size([x, y])

    这个方法用来获取一组坐标在画布中的坐标轴上对应的长度。这就好比获取地图比例尺的长度。返回值为一个数组,第一个元素对应x轴,第二个元素对应y轴

    本例中,我们想知道转置以后,x轴一个单位的长度。

    var width = api.size([1, 1])[0] * 0.6;
    

    源码

    var data = [];
    var dataCount = 10;
    var startTime = +new Date();
    var categories = ['categoryA', 'categoryB', 'categoryC'];
    var types = [
        {name: 'JS Heap', color: '#7b9ce1'},
        {name: 'Documents', color: '#bd6d6c'},
        {name: 'Nodes', color: '#75d874'},
        {name: 'Listeners', color: '#e0bc78'},
        {name: 'GPU Memory', color: '#dc77dc'},
        {name: 'GPU', color: '#72b362'}
    ];
    
    // Generate mock data
    echarts.util.each(categories, function (category, index) {
        var baseTime = startTime;
        for (var i = 0; i < dataCount; i++) {
            var typeItem = types[Math.round(Math.random() * (types.length - 1))];
            var duration = Math.round(Math.random() * 10000);
            data.push({
                name: typeItem.name,
                value: [
                    index,
                    baseTime,
                    baseTime += duration,
                    duration
                ],
                itemStyle: {
                    normal: {
                        color: typeItem.color
                    }
                }
            });
            baseTime += Math.round(Math.random() * 6000);
        }
    });
    
    function renderItem(params, api) {
        var categoryIndex = api.value(0);
        var start = api.coord([categoryIndex, api.value(1)]);
        var end = api.coord([categoryIndex, api.value(2)]);
        
        var width = api.size([1, 1])[0] * 0.6;
        var height = end[1] - start[1];
        var x = start[0] - width / 2;
        var y = start[1];
    
        return {
            type: 'rect',
            shape: {
                x: x,
                y: y,
                width: width,
                height: height
            },
            style: api.style()
        };
    }
    
    
    option = {
        tooltip: {
            formatter: function (params) {
                return params.marker + params.name + ': ' + params.value[3] + ' ms';
            }
        },
        title: {
            text: 'Profile',
            left: 'center'
        },
        legend: {
            data: ['bar', 'error']
        },
        dataZoom: [{
            type: 'slider',
            filterMode: 'weakFilter',
            showDataShadow: false,
            top: 400,
            height: 10,
            borderColor: 'transparent',
            backgroundColor: '#e2e2e2',
            handleIcon: 'M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line
            handleSize: 20,
            handleStyle: {
                shadowBlur: 6,
                shadowOffsetX: 1,
                shadowOffsetY: 2,
                shadowColor: '#aaa'
            },
            labelFormatter: ''
        }, {
            type: 'inside',
            filterMode: 'weakFilter'
        }],
        grid: {
            height:500
        },
        yAxis: {
            min: startTime,
            scale: true,
            axisLabel: {
                formatter: function (val) {
                    return Math.max(0, val - startTime) + ' ms';
                }
            }
        },
        xAxis: {
            data: categories
        },
        series: [{
            type: 'custom',
            renderItem: renderItem,
            itemStyle: {
                normal: {
                    opacity: 0.8
                }
            },
            encode: {
                x: 0,
                y: [1, 2]
            },
            data: data
        }]
    };
    

    相关文章

      网友评论

          本文标题:ECharts 自定义系列 profile 坐标转置

          本文链接:https://www.haomeiwen.com/subject/lulevxtx.html