TreemapSeries.js 10.0 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 33
            clipWindow: 'origin',                      // 缩放时窗口大小。'origin' or 'fullscreen'
            squareRatio: 0.5 * (1 + Math.sqrt(5)), // golden ratio
            root: '',
P
pah100 已提交
34
            visualDimension: 'value',                    // 默认第一个维度。
P
pah100 已提交
35
            zoomToNodeRatio: 0.32 * 0.32,                 // zoom to node时 node占可视区域的面积比例。
P
pah100 已提交
36
            roam: true,
37 38 39
            animation: true,
            animationDurationUpdate: 1500,
            animationEasing: 'quadraticInOut',
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
                        color: '#fff',
P
pah100 已提交
74 75 76 77 78 79 80 81 82
                        fontFamily: 'Arial',
                        fontSize: 13,
                        fontStyle: 'normal',
                        fontWeight: 'normal'
                    }
                }
            },
            itemStyle: {
                normal: {
P
pah100 已提交
83 84 85
                    color: null,         // 各异 如不需,可设为'none'
                    colorA: null,        // 默认不设置 如不需,可设为'none'
                    colorS: null,        // 默认不设置 如不需,可设为'none'
P
pah100 已提交
86 87
                    borderWidth: 0,
                    gapWidth: 0,
P
pah100 已提交
88 89
                    borderColor: '#fff',
                    borderColorS: null   // 如果设置,则borderColor的设置无效,而是取当前节点计算出的颜色,再经由borderColorS处理。
P
pah100 已提交
90 91 92
                },
                emphasis: {}
            },
93 94 95 96
            color: 'none',    // 为数组,表示同一level的color 选取列表。默认空,在level[0].color中取系统color列表。
            colorA: null,   // 为数组,表示同一level的color alpha 选取范围。
            colorS: null,   // 为数组,表示同一level的color alpha 选取范围。
            colorMapping: 'byIndex', // 'byIndex' or 'byValue'
P
pah100 已提交
97
            visibleMin: 10,    // If area less than this threshold (unit: pixel^2), node will not be rendered.
98 99 100 101 102 103
                               // 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 已提交
104
            levels: []         // Each item: {
105
                               //     visibleMin, itemStyle, visualDimension, label
P
pah100 已提交
106 107 108 109 110 111 112
                               // }
        },

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

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

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

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

P
pah100 已提交
127 128
            levels = option.levels = setDefault(levels, ecModel);

P
pah100 已提交
129 130 131
            // 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 已提交
132
            return Tree.createTree(root, this, levels).data;
P
pah100 已提交
133 134 135 136 137 138 139 140 141
        },

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

P
pah100 已提交
144 145 146 147 148 149 150 151 152 153
        /**
         * @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 已提交
154
            var name = data.getName(dataIndex);
P
pah100 已提交
155 156 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

            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 已提交
188 189
        /**
         * @public
190 191 192 193 194 195
         * @param {Object} layoutInfo {
         *                                x: containerGroup x
         *                                y: containerGroup y
         *                                width: containerGroup width
         *                                height: containerGroup height
         *                            }
P
pah100 已提交
196
         */
197
        setLayoutInfo: function (layoutInfo) {
P
pah100 已提交
198 199
            /**
             * @readOnly
200
             * @type {Object}
P
pah100 已提交
201
             */
202 203
            this.layoutInfo = this.layoutInfo || {};
            zrUtil.extend(this.layoutInfo, layoutInfo);
P
pah100 已提交
204 205 206 207
        }
    });

    /**
P
pah100 已提交
208
     * @param {Object} dataNode
P
pah100 已提交
209
     */
210
    function completeTreeValue(dataNode, arrValueLength) {
P
pah100 已提交
211 212 213 214 215
        // 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 已提交
216
        zrUtil.each(dataNode.children, function (child) {
P
pah100 已提交
217

218
            completeTreeValue(child, arrValueLength);
P
pah100 已提交
219

P
pah100 已提交
220 221
            var childValue = child.value;
            zrUtil.isArray(childValue) && (childValue = childValue[0]);
P
treemap  
pah100 已提交
222

P
pah100 已提交
223
            sum += childValue;
P
pah100 已提交
224 225
        });

P
pah100 已提交
226 227
        var thisValue = dataNode.value;

228
        if (arrValueLength >= 0) {
P
pah100 已提交
229
            if (!zrUtil.isArray(thisValue)) {
230
                dataNode.value = new Array(arrValueLength);
P
pah100 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243 244
            }
            else {
                thisValue = thisValue[0];
            }
        }

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

245
        arrValueLength >= 0
P
pah100 已提交
246 247
            ? (dataNode.value[0] = thisValue)
            : (dataNode.value = thisValue);
P
pah100 已提交
248 249
    }

P
pah100 已提交
250 251 252 253 254 255 256 257 258 259 260 261 262 263
    /**
     * 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);
264
            var modelColor = model.get('color');
P
pah100 已提交
265
            if (model.get('itemStyle.normal.color')
266
                || (modelColor && modelColor !== 'none')
P
pah100 已提交
267 268 269 270 271 272 273
            ) {
                hasColorDefine = true;
            }
        });

        if (!hasColorDefine) {
            var level0 = levels[0] || (levels[0] = {});
274
            level0.color = globalColorList.slice();
P
pah100 已提交
275 276 277 278 279
        }

        return levels;
    }

P
pah100 已提交
280
});