Echarts的自定義系列

自定義系列(custom series),是一種系列的類型。它把繪製圖形元素這一步留給開發者去作,從而開發者能在座標系中自由繪製出本身須要的圖表。利用好自定義系列,你會以爲Echarts無所不能了。html

簡介

自定義系列主要是靠renderItem函數來實現,以下:api

var option = {
    ...,
    series: [{
        type: 'custom',
        renderItem: function (params, api) {
            // ...
        },
        data: data
    }]
}

這個 renderItem 函數的職責,就是返回一個(或者一組)圖形元素定義,圖形元素定義 中包括圖形元素的類型、位置、尺寸、樣式等。echarts 會根據這些 圖形元素定義 來渲染出圖形元素。echarts

var option = {
    ...,
    series: [{
        type: 'custom',
        renderItem: function (params, api) {
            // 對於 data 中的每一個 dataItem,都會調用這個 renderItem 函數。
            // (可是注意,並不必定是按照 data 的順序調用)

            // 這裏進行一些處理,例如,座標轉換。
            // 這裏使用 api.value(0) 取出當前 dataItem 中第一個維度的數值。
            var categoryIndex = api.value(0);
            // 這裏使用 api.coord(...) 將數值在當前座標系中轉換成爲屏幕上的點的像素值。
            var startPoint = api.coord([api.value(1), categoryIndex]);
            var endPoint = api.coord([api.value(2), categoryIndex]);
            // 這裏使用 api.size(...) 得到 Y 軸上數值範圍爲 1 的一段所對應的像素長度。
            var height = api.size([0, 1])[1] * 0.6;

            // shape 屬性描述了這個矩形的像素位置和大小。
            // 其中特殊得用到了 echarts.graphic.clipRectByRect,意思是,
            // 若是矩形超出了當前座標系的包圍盒,則剪裁這個矩形。
            // 若是矩形徹底被剪掉,會返回 undefined.
var rectShape = echarts.graphic.clipRectByRect({
                // 矩形的位置和大小。
                x: startPoint[0],
                y: startPoint[1] - height / 2,
                width: endPoint[0] - startPoint[0],
                height: height
            }, {
                // 當前座標系的包圍盒。
                x: params.coordSys.x,
                y: params.coordSys.y,
                width: params.coordSys.width,
                height: params.coordSys.height
            });
             // 這裏返回爲這個 dataItem 構建的圖形元素定義。
            return rectShape && {
                // 表示這個圖形元素是矩形。還能夠是 'circle', 'sector', 'polygon' 等等。
                type: 'rect',
                shape: rectShape,
                // 用 api.style(...) 獲得默認的樣式設置。這個樣式設置包含了
                // option 中 itemStyle 的配置和視覺映射獲得的顏色。
                style: api.style()
            };
        },
        data: [
            [12, 44, 55, 60], // 這是第一個 dataItem
            [53, 31, 21, 56], // 這是第二個 dataItem
            [71, 33, 10, 20], // 這是第三個 dataItem
            ...
        ]
    }]
}

renderItem 函數提供了兩個參數:
params:包含了當前數據信息(如 seriesIndex、dataIndex 等等)和座標系的信息(如座標系包圍盒的位置和尺寸)。
api:是一些開發者可調用的方法集合(如 api.value()、api.coord())。ide

實例一:echarts.graphic.clipRectByRect

介紹完成後,咱們來看一個實例。
https://gallery.echartsjs.com...函數

clipboard.png

option = null;
var startTime = +new Date();
var categories = ['categoryA', 'categoryB', 'categoryC', 'categoryD'];

var step = 14399285;

var data = [{
    name: 'JS Heap',
    value: [0, 1563000480298, (1563000480298 + step)],
    itemStyle: {
        normal: {
            color: '#7b9ce1'
        }
    }
}, {
    name: 'Documents',
    value: [1, 1563000484450, (1563000484450 + step - 3000000)],
    itemStyle: {
        normal: {
            color: '#bd6d6c'
        }
    }
}, {
    name: 'Nodes',
    value: [2, 1563000493753, (1563000493753 + step - 5000000)],
    itemStyle: {
        normal: {
            color: '#75d874'
        }
    }
}, {
    name: 'Listeners',
    value: [3, 1563000503740, (1563000503740 + step)],
    itemStyle: {
        normal: {
            color: '#e0bc78'
        }
    }
}, {
    name: 'GPU Memory',
    value: [2, 1563000506369, (1563000506369 + step - 8000000)],
    itemStyle: {
        normal: {
            color: '#e0bc78'
        }
    }
}, {
    name: 'GPU',
    value: [3, 1563000513841, (1563000513841 + step - 12000000)],
    itemStyle: {
        normal: {
            color: '#72b362'
        }
    }
}]

function renderItem(params, api) {
    var categoryIndex = api.value(0);
    var start = api.coord([api.value(1), categoryIndex]);
    var end = api.coord([api.value(2), categoryIndex]);
    var height = api.size([0, 1])[1] * 0.6;

    var rectShape = echarts.graphic.clipRectByRect({
        x: start[0],
        y: start[1] - height / 2,
        width: end[0] - start[0],
        height: height
    }, {
        x: params.coordSys.x,
        y: params.coordSys.y,
        width: params.coordSys.width,
        height: params.coordSys.height
    });

    return rectShape && {
        type: 'rect',
        shape: rectShape,
        style: api.style()
    };
}


option = {
    tooltip: {
        formatter: function (params) {
            return params.marker + params.name + ': ' + params.value[1] + ' ms';
        }
    },
    title: {
        text: 'Profile',
        left: 'center'
    },
    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:300
    },
    xAxis: [{
        min: startTime,
        scale: true,
        axisLabel: {
            formatter: function (val) {
                return Math.max(0, val - startTime) + ' ms';
            }
        }
    }],
    yAxis: [{
        data: categories
    }],
    series: [{
        type: 'custom',
        renderItem: renderItem,
        itemStyle: {
            normal: {
                opacity: 0.8
            }
        },
        encode: {
            x: [1, 2],
            y: 0
        },
        data: data
    }]
};

這裏最重要的一個函數就是renderItem, 其中裏面的echarts.graphic.clipRectByRect更是其中的關鍵。spa

實例二:echarts.graphic.clipPointsByRect

echarts.graphic.clipRectByRect輸入兩個矩形,返回第二個矩形截取第一個矩形的結果。
除了echarts.graphic.clipRectByRect,還有一個echarts.graphic.clipPointsByRect, echarts.graphic.clipPointsByRect表示輸入一組點,和一個矩形,返回被矩形截取過的點, 好比[[23, 44], [12, 15], …]code

那咱們再把上面的例子改善,繪製成多邊形的形狀。
https://gallery.echartsjs.com...orm

先看看效果圖: htm

clipboard.png

與上圖不同的就是右側的形狀,代碼的不一樣之處也就是renderItem對象

function renderItem(params, api) {
    var categoryIndex = api.value(0);
    var start = api.coord([api.value(1), categoryIndex]);
    var end = api.coord([api.value(2), categoryIndex]);
    var height = api.size([0, 1])[1] * 0.6;
    var width = end[0] - start[0];
    var x = start[0];
    var y = start[1] - height / 2;

    var shape = echarts.graphic.clipPointsByRect([
            [x, y],
            [x + width - 10, y],
            [x + width, y - height / 2],
            [x + width - 10, y - height],
            [x, y - height]
        ], {
        x: params.coordSys.x,
        y: params.coordSys.y,
        width: params.coordSys.width,
        height: params.coordSys.height
    });

    return shape && {
        type: 'polygon',
        shape: {
            points: shape
        },
        style: api.style()
    }
}

這裏的繪製就是採用5個座標的points繪製而成的,即上面的shape對象,因此echarts.graphic.clipPointsByRect真的是什麼東西都能繪製出來。

相關文章
相關標籤/搜索