HeatmapView.js 10.4 KB
Newer Older
L
lang 已提交
1 2 3
define(function (require) {

    var graphic = require('../../util/graphic');
L
lang 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
    var HeatmapLayer = require('./HeatmapLayer');
    var zrUtil = require('zrender/core/util');

    function getIsInPiecewiseRange(dataExtent, pieceList, selected) {
        var dataSpan = dataExtent[1] - dataExtent[0];
        pieceList = zrUtil.map(pieceList, function (piece) {
            return {
                interval: [
                    (piece.interval[0] - dataExtent[0]) / dataSpan,
                    (piece.interval[1] - dataExtent[0]) / dataSpan
                ]
            };
        });
        var len = pieceList.length;
        var lastIndex = 0;
        return function (val) {
            // Try to find in the location of the last found
            for (var i = lastIndex; i < len; i++) {
                var interval = pieceList[i].interval;
                if (interval[0] <= val && val <= interval[1]) {
                    lastIndex = i;
                    break;
                }
            }
            if (i === len) { // Not found, back interation
                for (var i = lastIndex - 1; i >= 0; i--) {
                    var interval = pieceList[i].interval;
                    if (interval[0] <= val && val <= interval[1]) {
                        lastIndex = i;
                        break;
                    }
                }
            }
            return i >= 0 && i < len && selected[i];
        };
    }

    function getIsInContinuousRange(dataExtent, range) {
        var dataSpan = dataExtent[1] - dataExtent[0];
        range = [
            (range[0] - dataExtent[0]) / dataSpan,
            (range[1] - dataExtent[0]) / dataSpan
        ];
        return function (val) {
            return val >= range[0] && val <= range[1];
        };
    }
L
lang 已提交
51

52 53 54 55 56 57
    function isGeoCoordSys(coordSys) {
        var dimensions = coordSys.dimensions;
        // Not use coorSys.type === 'geo' because coordSys maybe extended
        return dimensions[0] === 'lng' && dimensions[1] === 'lat';
    }

L
lang 已提交
58 59 60 61 62
    return require('../../echarts').extendChartView({

        type: 'heatmap',

        render: function (seriesModel, ecModel, api) {
63 64 65
            var visualMapOfThisSeries;
            ecModel.eachComponent('visualMap', function (visualMap) {
                visualMap.eachTargetSeries(function (targetSeries) {
L
lang 已提交
66
                    if (targetSeries === seriesModel) {
67
                        visualMapOfThisSeries = visualMap;
L
lang 已提交
68 69 70 71
                    }
                });
            });

72 73 74 75
            if (__DEV__) {
                if (!visualMapOfThisSeries) {
                    throw new Error('Heatmap must use with visualMap');
                }
L
lang 已提交
76 77 78
            }

            this.group.removeAll();
L
lang 已提交
79
            var coordSys = seriesModel.coordinateSystem;
80 81
            if (coordSys.type === 'cartesian2d' || coordSys.type === 'calendar') {
                this._renderOnCartesianAndCalendar(coordSys, seriesModel, api);
L
lang 已提交
82
            }
83
            else if (isGeoCoordSys(coordSys)) {
L
lang 已提交
84
                this._renderOnGeo(
85
                    coordSys, seriesModel, visualMapOfThisSeries, api
L
lang 已提交
86
                );
L
lang 已提交
87 88 89
            }
        },

1
100pah 已提交
90 91
        dispose: function () {},

92
        _renderOnCartesianAndCalendar: function (coordSys, seriesModel, api) {
D
dengxiaohong01 已提交
93

94 95 96
            if (coordSys.type === 'cartesian2d') {
                var xAxis = coordSys.getAxis('x');
                var yAxis = coordSys.getAxis('y');
D
dengxiaohong01 已提交
97

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
                if (__DEV__) {
                    if (!(xAxis.type === 'category' && yAxis.type === 'category')) {
                        throw new Error('Heatmap on cartesian must have two category axes');
                    }
                    if (!(xAxis.onBand && yAxis.onBand)) {
                        throw new Error('Heatmap on cartesian must have two axes with boundaryGap true');
                    }
                }

                var width = xAxis.getBandWidth();
                var height = yAxis.getBandWidth();

            }

            var group = this.group;
D
dengxiaohong01 已提交
113 114 115 116 117 118 119 120 121 122
            var data = seriesModel.getData();

            var itemStyleQuery = 'itemStyle.normal';
            var hoverItemStyleQuery = 'itemStyle.emphasis';
            var labelQuery = 'label.normal';
            var hoverLabelQuery = 'label.emphasis';
            var style = seriesModel.getModel(itemStyleQuery).getItemStyle(['color']);
            var hoverStl = seriesModel.getModel(hoverItemStyleQuery).getItemStyle();
            var labelModel = seriesModel.getModel('label.normal');
            var hoverLabelModel = seriesModel.getModel('label.emphasis');
P
tweak  
pah100 已提交
123
            var coordSysType = coordSys.type;
D
dengxiaohong01 已提交
124

P
tweak  
pah100 已提交
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
            var dataDims = coordSysType === 'cartesian2d'
                ? [
                    seriesModel.coordDimToDataDim('x')[0],
                    seriesModel.coordDimToDataDim('y')[0],
                    seriesModel.coordDimToDataDim('value')[0]
                ]
                : [
                    seriesModel.coordDimToDataDim('time')[0],
                    seriesModel.coordDimToDataDim('value')[0]
                ];

            data.each(function (idx) {
                var rect;

                if (coordSysType === 'cartesian2d') {
                    // Ignore empty data
                    if (isNaN(data.get(dataDims[2], idx))) {
                        return;
143 144
                    }

P
tweak  
pah100 已提交
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
                    var point = coordSys.dataToPoint([
                        data.get(dataDims[0], idx),
                        data.get(dataDims[1], idx)
                    ]);

                    rect = new graphic.Rect({
                        shape: {
                            x: point[0] - width / 2,
                            y: point[1] - height / 2,
                            width: width,
                            height: height
                        },
                        style: {
                            fill: data.getItemVisual(idx, 'color'),
                            opacity: data.getItemVisual(idx, 'opacity')
160
                        }
P
tweak  
pah100 已提交
161 162 163 164 165 166
                    });
                }
                else {
                    // Ignore empty data
                    if (isNaN(data.get(dataDims[1], idx))) {
                        return;
167
                    }
168

P
tweak  
pah100 已提交
169 170 171 172 173 174 175 176 177
                    rect = new graphic.Rect({
                        z2: 1,
                        shape: coordSys.dataToRect([data.get(dataDims[0], idx)]).contentShape,
                        style: {
                            fill: data.getItemVisual(idx, 'color'),
                            opacity: data.getItemVisual(idx, 'opacity')
                        }
                    });
                }
L
lang 已提交
178

P
tweak  
pah100 已提交
179
                var itemModel = data.getItemModel(idx);
180

P
tweak  
pah100 已提交
181 182 183 184 185 186 187
                // Optimization for large datset
                if (data.hasItemOption) {
                    style = itemModel.getModel(itemStyleQuery).getItemStyle(['color']);
                    hoverStl = itemModel.getModel(hoverItemStyleQuery).getItemStyle();
                    labelModel = itemModel.getModel(labelQuery);
                    hoverLabelModel = itemModel.getModel(hoverLabelQuery);
                }
L
lang 已提交
188

P
tweak  
pah100 已提交
189 190 191 192 193
                var rawValue = seriesModel.getRawValue(idx);
                var defaultText = '-';
                if (rawValue && rawValue[2] != null) {
                    defaultText = rawValue[2];
                }
S
sushuang 已提交
194 195 196 197 198 199 200 201 202 203

                graphic.setText(style, labelModel);
                style.text = labelModel.getShallow('show')
                    ? seriesModel.getFormattedLabel(idx, 'normal') || defaultText
                    : null;

                graphic.setText(hoverStl, hoverLabelModel, false);
                hoverStl.text = hoverLabelModel.getShallow('show')
                    ? seriesModel.getFormattedLabel(idx, 'emphasis')
                    : null;
L
lang 已提交
204

P
tweak  
pah100 已提交
205
                rect.setStyle(style);
L
lang 已提交
206

P
tweak  
pah100 已提交
207
                graphic.setHoverStyle(rect, data.hasItemOption ? hoverStl : zrUtil.extend({}, hoverStl));
L
lang 已提交
208

P
tweak  
pah100 已提交
209 210 211
                group.add(rect);
                data.setItemGraphicEl(idx, rect);
            });
L
lang 已提交
212 213
        },

214 215 216
        _renderOnGeo: function (geo, seriesModel, visualMapModel, api) {
            var inRangeVisuals = visualMapModel.targetVisuals.inRange;
            var outOfRangeVisuals = visualMapModel.targetVisuals.outOfRange;
L
lang 已提交
217 218 219 220 221
            // if (!visualMapping) {
            //     throw new Error('Data range must have color visuals');
            // }

            var data = seriesModel.getData();
222
            var hmLayer = this._hmLayer || (this._hmLayer || new HeatmapLayer());
L
lang 已提交
223
            hmLayer.blurSize = seriesModel.get('blurSize');
224
            hmLayer.pointSize = seriesModel.get('pointSize');
L
lang 已提交
225 226
            hmLayer.minOpacity = seriesModel.get('minOpacity');
            hmLayer.maxOpacity = seriesModel.get('maxOpacity');
L
lang 已提交
227 228

            var rect = geo.getViewRect().clone();
L
lang 已提交
229
            var roamTransform = geo.getRoamTransform().transform;
L
lang 已提交
230
            rect.applyTransform(roamTransform);
L
lang 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247

            // Clamp on viewport
            var x = Math.max(rect.x, 0);
            var y = Math.max(rect.y, 0);
            var x2 = Math.min(rect.width + rect.x, api.getWidth());
            var y2 = Math.min(rect.height + rect.y, api.getHeight());
            var width = x2 - x;
            var height = y2 - y;

            var points = data.mapArray(['lng', 'lat', 'value'], function (lng, lat, value) {
                var pt = geo.dataToPoint([lng, lat]);
                pt[0] -= x;
                pt[1] -= y;
                pt.push(value);
                return pt;
            });

248 249 250
            var dataExtent = visualMapModel.getExtent();
            var isInRange = visualMapModel.type === 'visualMap.continuous'
                ? getIsInContinuousRange(dataExtent, visualMapModel.option.range)
L
lang 已提交
251
                : getIsInPiecewiseRange(
252
                    dataExtent, visualMapModel.getPieceList(), visualMapModel.option.selected
L
lang 已提交
253
                );
L
lang 已提交
254

L
lang 已提交
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
            hmLayer.update(
                points, width, height,
                inRangeVisuals.color.getNormalizer(),
                {
                    inRange: inRangeVisuals.color.getColorMapper(),
                    outOfRange: outOfRangeVisuals.color.getColorMapper()
                },
                isInRange
            );
            var img = new graphic.Image({
                style: {
                    width: width,
                    height: height,
                    x: x,
                    y: y,
                    image: hmLayer.canvas
                },
                silent: true
            });
            this.group.add(img);
L
lang 已提交
275 276
        }
    });
D
dengxiaohong01 已提交
277
});