TreemapSeries.js 11.3 KB
Newer Older
P
pah100 已提交
1 2 3 4 5
define(function(require) {

    var SeriesModel = require('../../model/Series');
    var Tree = require('../../data/Tree');
    var zrUtil = require('zrender/core/util');
P
pah100 已提交
6
    var Model = require('../../model/Model');
P
pah100 已提交
7 8 9 10
    var formatUtil = require('../../util/format');
    var encodeHTML = formatUtil.encodeHTML;
    var addCommas = formatUtil.addCommas;

P
pah100 已提交
11 12 13 14 15 16 17 18 19 20 21

    return SeriesModel.extend({

        type: 'series.treemap',

        dependencies: ['grid', 'polar'],

        defaultOption: {
            calculable: false,
            clickable: true,
            // center: ['50%', '50%'],             // not supported in ec3.
P
pah100 已提交
22
            // size: ['80%', '80%'],               // deprecated, compatible with ec2.
P
pah100 已提交
23 24 25 26 27 28
            x: 'center',
            y: 'middle',
            x2: null,
            y2: null,
            width: '80%',
            height: '80%',
P
tweak  
pah100 已提交
29 30
            sort: true,                         // Can be null or false or true
                                                // (order by desc default, asc not supported yet (strange effect))
P
pah100 已提交
31 32
            clipWindow: 'origin',                      // 缩放时窗口大小。'origin' or 'fullscreen'
            squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio
P
pah100 已提交
33
            root: null,                             // default: tree root. This feature doesnt work unless node have id.
P
pah100 已提交
34
            visualDimension: 'value',                    // 默认第一个维度。
P
pah100 已提交
35
            zoomToNodeRatio: 0.32 * 0.32,                 // zoom to node时 node占可视区域的面积比例。
P
pah100 已提交
36
            roam: true,
37 38
            animation: true,
            animationDurationUpdate: 1500,
L
Tweak  
lang 已提交
39
            animationEasing: 'quinticInOut',
P
pah100 已提交
40 41
            breadcrumb: {
                show: true,
P
pah100 已提交
42
                height: 22,
P
pah100 已提交
43
                x: 'center',
P
pah100 已提交
44 45
                y: 'bottom',
                emptyItemWidth: 25,                    // 空节点宽度
P
pah100 已提交
46 47
                itemStyle: {
                    normal: {
P
pah100 已提交
48 49 50 51 52 53 54 55 56 57
                        color: 'rgba(0,0,0,0.7)', //'#5793f3',
                        borderColor: 'rgba(255,255,255,0.7)',
                        borderWidth: 1,
                        shadowColor: 'rgba(150,150,150,1)',
                        shadowBlur: 3,
                        shadowOffsetX: 0,
                        shadowOffsetY: 0,
                        textStyle: {
                            color: '#fff',
                            fontFamily: 'Arial',
P
pah100 已提交
58
                            fontSize: 12,
P
pah100 已提交
59 60
                            fontWeight: 'normal'
                        }
P
pah100 已提交
61 62 63 64 65 66 67 68
                    },
                    emphasis: {
                        textStyle: {}
                    }
                }
            },
            label: {
                normal: {
69
                    show: true,
P
pah100 已提交
70
                    position: ['50%', '50%'],      // 可以是 5 '5%' 'insideTopLeft', ...
P
pah100 已提交
71
                    textStyle: {
P
pah100 已提交
72
                        align: 'center',
P
pah100 已提交
73
                        baseline: 'middle',
P
pah100 已提交
74
                        color: '#fff',
P
pah100 已提交
75 76 77
                        fontFamily: 'Arial',
                        fontSize: 13,
                        fontStyle: 'normal',
P
pah100 已提交
78
                        fontWeight: 'normal',
P
tweak  
pah100 已提交
79
                        ellipsis: true
P
pah100 已提交
80 81 82 83 84
                    }
                }
            },
            itemStyle: {
                normal: {
P
pah100 已提交
85 86 87
                    color: null,         // 各异 如不需,可设为'none'
                    colorA: null,        // 默认不设置 如不需,可设为'none'
                    colorS: null,        // 默认不设置 如不需,可设为'none'
P
pah100 已提交
88 89
                    borderWidth: 0,
                    gapWidth: 0,
P
pah100 已提交
90 91
                    borderColor: '#fff',
                    borderColorS: null   // 如果设置,则borderColor的设置无效,而是取当前节点计算出的颜色,再经由borderColorS处理。
P
pah100 已提交
92 93 94
                },
                emphasis: {}
            },
95 96 97
            color: 'none',    // 为数组,表示同一level的color 选取列表。默认空,在level[0].color中取系统color列表。
            colorA: null,   // 为数组,表示同一level的color alpha 选取范围。
            colorS: null,   // 为数组,表示同一level的color alpha 选取范围。
P
pah100 已提交
98
            colorMapping: 'byIndex', // 'byIndex' or 'byValue' or 'byId'
P
pah100 已提交
99
            visibleMin: 10,    // If area less than this threshold (unit: pixel^2), node will not be rendered.
100 101 102 103 104 105
                               // Only works when sort is 'asc' or 'desc'.
            childrenVisibleMin: null, // If area of a node less than this threshold (unit: pixel^2),
                                      // grandchildren will not show.
                                      // Why grandchildren? If not grandchildren but children,
                                      // some siblings show children and some not,
                                      // the appearance may be mess and not consistent,
P
pah100 已提交
106
            levels: []         // Each item: {
107
                               //     visibleMin, itemStyle, visualDimension, label
P
pah100 已提交
108 109 110 111 112 113 114
                               // }
        },

        /**
         * @override
         */
        getInitialData: function (option, ecModel) {
P
treemap  
pah100 已提交
115
            var data = option.data || [];
P
pah100 已提交
116
            var rootName = option.name;
117
            rootName == null && (rootName = option.name);
P
pah100 已提交
118

P
pah100 已提交
119
            // Create a virtual root.
P
pah100 已提交
120
            var root = {name: rootName, children: option.data};
121
            var value0 = (data[0] || {}).value;
P
pah100 已提交
122

123
            completeTreeValue(root, zrUtil.isArray(value0) ? value0.length : -1);
P
pah100 已提交
124

P
treemap  
pah100 已提交
125 126
            // FIXME
            // sereis.mergeOption 的 getInitData是否放在merge后,从而能直接获取merege后的结果而非手动判断。
127
            var levels = option.levels || [];
P
treemap  
pah100 已提交
128

P
pah100 已提交
129 130
            levels = option.levels = setDefault(levels, ecModel);

P
pah100 已提交
131 132 133
            // Make sure always a new tree is created when setOption,
            // in TreemapView, we check whether oldTree === newTree
            // to choose mappings approach among old shapes and new shapes.
L
lang 已提交
134
            return Tree.createTree(root, this, levels).data;
P
pah100 已提交
135 136 137 138 139 140 141 142
        },

        /**
         * @public
         */
        getViewRoot: function () {
            var optionRoot = this.option.root;
            var treeRoot = this.getData().tree.root;
P
pah100 已提交
143
            return optionRoot && treeRoot.getNodeById(optionRoot) || treeRoot;
P
pah100 已提交
144 145
        },

P
pah100 已提交
146 147 148 149 150 151 152 153 154 155
        /**
         * @override
         * @param {number} dataIndex
         * @param {boolean} [mutipleSeries=false]
         */
        formatTooltip: function (dataIndex) {
            var data = this.getData();
            var value = data.getRawValue(dataIndex);
            var formattedValue = zrUtil.isArray(value)
                ? addCommas(value[0]) : addCommas(value);
L
lang 已提交
156
            var name = data.getName(dataIndex);
P
pah100 已提交
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

            return encodeHTML(name) + ': ' + formattedValue;
        },

        /**
         * Add tree path to tooltip param
         *
         * @override
         * @param {number} dataIndex
         * @return {Object}
         */
        getFormatParams: function (dataIndex) {
            var params = SeriesModel.prototype.getFormatParams.apply(this, arguments);

            var data = this.getData();
            var node = data.tree.getNodeByDataIndex(dataIndex);
            var treePathInfo = params.treePathInfo = [];

            while (node) {
                var nodeDataIndex = node.dataIndex;
                treePathInfo.push({
                    name: node.name,
                    dataIndex: nodeDataIndex,
                    value: data.getRawValue(nodeDataIndex)
                });
                node = node.parentNode;
            }

            treePathInfo.reverse();

            return params;
        },

P
pah100 已提交
190 191
        /**
         * @public
192 193 194 195 196 197
         * @param {Object} layoutInfo {
         *                                x: containerGroup x
         *                                y: containerGroup y
         *                                width: containerGroup width
         *                                height: containerGroup height
         *                            }
P
pah100 已提交
198
         */
199
        setLayoutInfo: function (layoutInfo) {
P
pah100 已提交
200 201
            /**
             * @readOnly
202
             * @type {Object}
P
pah100 已提交
203
             */
204 205
            this.layoutInfo = this.layoutInfo || {};
            zrUtil.extend(this.layoutInfo, layoutInfo);
P
pah100 已提交
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241
        },

        /**
         * @param  {string} id
         * @return {number} index
         */
        mapIdToIndex: function (id) {
            // A feature is implemented:
            // index is monotone increasing with the sequence of
            // input id at the first time.
            // This feature can make sure that each data item and its
            // mapped color have the same index between data list and
            // color list at the beginning, which is useful for user
            // to adjust data-color mapping.

            /**
             * @private
             * @type {Object}
             */
            var idIndexMap = this._idIndexMap;

            if (!idIndexMap) {
                idIndexMap = this._idIndexMap = {};
                /**
                 * @private
                 * @type {number}
                 */
                this._idIndexMapCount = 0;
            }

            var index = idIndexMap[id];
            if (index == null) {
                idIndexMap[id] = index = this._idIndexMapCount++;
            }

            return index;
P
pah100 已提交
242 243 244 245
        }
    });

    /**
P
pah100 已提交
246
     * @param {Object} dataNode
P
pah100 已提交
247
     */
248
    function completeTreeValue(dataNode, arrValueLength) {
P
pah100 已提交
249 250 251 252 253
        // Postorder travel tree.
        // If value of none-leaf node is not set,
        // calculate it by suming up the value of all children.
        var sum = 0;

P
pah100 已提交
254
        zrUtil.each(dataNode.children, function (child) {
P
pah100 已提交
255

256
            completeTreeValue(child, arrValueLength);
P
pah100 已提交
257

P
pah100 已提交
258 259
            var childValue = child.value;
            zrUtil.isArray(childValue) && (childValue = childValue[0]);
P
treemap  
pah100 已提交
260

P
pah100 已提交
261
            sum += childValue;
P
pah100 已提交
262 263
        });

P
pah100 已提交
264 265
        var thisValue = dataNode.value;

266
        if (arrValueLength >= 0) {
P
pah100 已提交
267
            if (!zrUtil.isArray(thisValue)) {
268
                dataNode.value = new Array(arrValueLength);
P
pah100 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282
            }
            else {
                thisValue = thisValue[0];
            }
        }

        if (thisValue == null || isNaN(thisValue)) {
            thisValue = sum;
        }
        // Value should not less than 0.
        if (thisValue < 0) {
            thisValue = 0;
        }

283
        arrValueLength >= 0
P
pah100 已提交
284 285
            ? (dataNode.value[0] = thisValue)
            : (dataNode.value = thisValue);
P
pah100 已提交
286 287
    }

P
pah100 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301
    /**
     * set default to level configuration
     */
    function setDefault(levels, ecModel) {
        var globalColorList = ecModel.get('color');

        if (!globalColorList) {
            return;
        }

        levels = levels || [];
        var hasColorDefine;
        zrUtil.each(levels, function (levelDefine) {
            var model = new Model(levelDefine);
302
            var modelColor = model.get('color');
P
pah100 已提交
303
            if (model.get('itemStyle.normal.color')
304
                || (modelColor && modelColor !== 'none')
P
pah100 已提交
305 306 307 308 309 310 311
            ) {
                hasColorDefine = true;
            }
        });

        if (!hasColorDefine) {
            var level0 = levels[0] || (levels[0] = {});
312
            level0.color = globalColorList.slice();
P
pah100 已提交
313 314 315 316 317
        }

        return levels;
    }

P
pah100 已提交
318
});