| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 | 
/** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements.  See the NOTICE file* distributed with this work for additional information* regarding copyright ownership.  The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License.  You may obtain a copy of the License at**   http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied.  See the License for the* specific language governing permissions and limitations* under the License.*/var _config = require("../../config");var __DEV__ = _config.__DEV__;var layout = require("../../util/layout");var _number = require("../../util/number");var parsePercent = _number.parsePercent;var linearMap = _number.linearMap;/** Licensed to the Apache Software Foundation (ASF) under one* or more contributor license agreements.  See the NOTICE file* distributed with this work for additional information* regarding copyright ownership.  The ASF licenses this file* to you under the Apache License, Version 2.0 (the* "License"); you may not use this file except in compliance* with the License.  You may obtain a copy of the License at**   http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing,* software distributed under the License is distributed on an* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY* KIND, either express or implied.  See the License for the* specific language governing permissions and limitations* under the License.*/function getViewRect(seriesModel, api) {  return layout.getLayoutRect(seriesModel.getBoxLayoutParams(), {    width: api.getWidth(),    height: api.getHeight()  });}function getSortedIndices(data, sort) {  var valueDim = data.mapDimension('value');  var valueArr = data.mapArray(valueDim, function (val) {    return val;  });  var indices = [];  var isAscending = sort === 'ascending';  for (var i = 0, len = data.count(); i < len; i++) {    indices[i] = i;  } // Add custom sortable function & none sortable opetion by "options.sort"  if (typeof sort === 'function') {    indices.sort(sort);  } else if (sort !== 'none') {    indices.sort(function (a, b) {      return isAscending ? valueArr[a] - valueArr[b] : valueArr[b] - valueArr[a];    });  }  return indices;}function labelLayout(data) {  data.each(function (idx) {    var itemModel = data.getItemModel(idx);    var labelModel = itemModel.getModel('label');    var labelPosition = labelModel.get('position');    var orient = itemModel.get('orient');    var labelLineModel = itemModel.getModel('labelLine');    var layout = data.getItemLayout(idx);    var points = layout.points;    var isLabelInside = labelPosition === 'inner' || labelPosition === 'inside' || labelPosition === 'center' || labelPosition === 'insideLeft' || labelPosition === 'insideRight';    var textAlign;    var textX;    var textY;    var linePoints;    if (isLabelInside) {      if (labelPosition === 'insideLeft') {        textX = (points[0][0] + points[3][0]) / 2 + 5;        textY = (points[0][1] + points[3][1]) / 2;        textAlign = 'left';      } else if (labelPosition === 'insideRight') {        textX = (points[1][0] + points[2][0]) / 2 - 5;        textY = (points[1][1] + points[2][1]) / 2;        textAlign = 'right';      } else {        textX = (points[0][0] + points[1][0] + points[2][0] + points[3][0]) / 4;        textY = (points[0][1] + points[1][1] + points[2][1] + points[3][1]) / 4;        textAlign = 'center';      }      linePoints = [[textX, textY], [textX, textY]];    } else {      var x1;      var y1;      var x2;      var y2;      var labelLineLen = labelLineModel.get('length');      if (labelPosition === 'left') {        // Left side        x1 = (points[3][0] + points[0][0]) / 2;        y1 = (points[3][1] + points[0][1]) / 2;        x2 = x1 - labelLineLen;        textX = x2 - 5;        textAlign = 'right';      } else if (labelPosition === 'right') {        // Right side        x1 = (points[1][0] + points[2][0]) / 2;        y1 = (points[1][1] + points[2][1]) / 2;        x2 = x1 + labelLineLen;        textX = x2 + 5;        textAlign = 'left';      } else if (labelPosition === 'top') {        // Top side        x1 = (points[3][0] + points[0][0]) / 2;        y1 = (points[3][1] + points[0][1]) / 2;        y2 = y1 - labelLineLen;        textY = y2 - 5;        textAlign = 'center';      } else if (labelPosition === 'bottom') {        // Bottom side        x1 = (points[1][0] + points[2][0]) / 2;        y1 = (points[1][1] + points[2][1]) / 2;        y2 = y1 + labelLineLen;        textY = y2 + 5;        textAlign = 'center';      } else if (labelPosition === 'rightTop') {        // RightTop side        x1 = orient === 'horizontal' ? points[3][0] : points[1][0];        y1 = orient === 'horizontal' ? points[3][1] : points[1][1];        if (orient === 'horizontal') {          y2 = y1 - labelLineLen;          textY = y2 - 5;          textAlign = 'center';        } else {          x2 = x1 + labelLineLen;          textX = x2 + 5;          textAlign = 'top';        }      } else if (labelPosition === 'rightBottom') {        // RightBottom side        x1 = points[2][0];        y1 = points[2][1];        if (orient === 'horizontal') {          y2 = y1 + labelLineLen;          textY = y2 + 5;          textAlign = 'center';        } else {          x2 = x1 + labelLineLen;          textX = x2 + 5;          textAlign = 'bottom';        }      } else if (labelPosition === 'leftTop') {        // LeftTop side        x1 = points[0][0];        y1 = orient === 'horizontal' ? points[0][1] : points[1][1];        if (orient === 'horizontal') {          y2 = y1 - labelLineLen;          textY = y2 - 5;          textAlign = 'center';        } else {          x2 = x1 - labelLineLen;          textX = x2 - 5;          textAlign = 'right';        }      } else if (labelPosition === 'leftBottom') {        // LeftBottom side        x1 = orient === 'horizontal' ? points[1][0] : points[3][0];        y1 = orient === 'horizontal' ? points[1][1] : points[2][1];        if (orient === 'horizontal') {          y2 = y1 + labelLineLen;          textY = y2 + 5;          textAlign = 'center';        } else {          x2 = x1 - labelLineLen;          textX = x2 - 5;          textAlign = 'right';        }      } else {        // Right side or Bottom side        x1 = (points[1][0] + points[2][0]) / 2;        y1 = (points[1][1] + points[2][1]) / 2;        if (orient === 'horizontal') {          y2 = y1 + labelLineLen;          textY = y2 + 5;          textAlign = 'center';        } else {          x2 = x1 + labelLineLen;          textX = x2 + 5;          textAlign = 'left';        }      }      if (orient === 'horizontal') {        x2 = x1;        textX = x2;      } else {        y2 = y1;        textY = y2;      }      linePoints = [[x1, y1], [x2, y2]];    }    layout.label = {      linePoints: linePoints,      x: textX,      y: textY,      verticalAlign: 'middle',      textAlign: textAlign,      inside: isLabelInside    };  });}function _default(ecModel, api, payload) {  ecModel.eachSeriesByType('funnel', function (seriesModel) {    var data = seriesModel.getData();    var valueDim = data.mapDimension('value');    var sort = seriesModel.get('sort');    var viewRect = getViewRect(seriesModel, api);    var indices = getSortedIndices(data, sort);    var orient = seriesModel.get('orient');    var viewWidth = viewRect.width;    var viewHeight = viewRect.height;    var x = viewRect.x;    var y = viewRect.y;    var sizeExtent = orient === 'horizontal' ? [parsePercent(seriesModel.get('minSize'), viewHeight), parsePercent(seriesModel.get('maxSize'), viewHeight)] : [parsePercent(seriesModel.get('minSize'), viewWidth), parsePercent(seriesModel.get('maxSize'), viewWidth)];    var dataExtent = data.getDataExtent(valueDim);    var min = seriesModel.get('min');    var max = seriesModel.get('max');    if (min == null) {      min = Math.min(dataExtent[0], 0);    }    if (max == null) {      max = dataExtent[1];    }    var funnelAlign = seriesModel.get('funnelAlign');    var gap = seriesModel.get('gap');    var viewSize = orient === 'horizontal' ? viewWidth : viewHeight;    var itemSize = (viewSize - gap * (data.count() - 1)) / data.count();    var getLinePoints = function (idx, offset) {      // End point index is data.count() and we assign it 0      if (orient === 'horizontal') {        var val = data.get(valueDim, idx) || 0;        var itemHeight = linearMap(val, [min, max], sizeExtent, true);        var y0;        switch (funnelAlign) {          case 'top':            y0 = y;            break;          case 'center':            y0 = y + (viewHeight - itemHeight) / 2;            break;          case 'bottom':            y0 = y + (viewHeight - itemHeight);            break;        }        return [[offset, y0], [offset, y0 + itemHeight]];      }      var val = data.get(valueDim, idx) || 0;      var itemWidth = linearMap(val, [min, max], sizeExtent, true);      var x0;      switch (funnelAlign) {        case 'left':          x0 = x;          break;        case 'center':          x0 = x + (viewWidth - itemWidth) / 2;          break;        case 'right':          x0 = x + viewWidth - itemWidth;          break;      }      return [[x0, offset], [x0 + itemWidth, offset]];    };    if (sort === 'ascending') {      // From bottom to top      itemSize = -itemSize;      gap = -gap;      if (orient === 'horizontal') {        x += viewWidth;      } else {        y += viewHeight;      }      indices = indices.reverse();    }    for (var i = 0; i < indices.length; i++) {      var idx = indices[i];      var nextIdx = indices[i + 1];      var itemModel = data.getItemModel(idx);      if (orient === 'horizontal') {        var width = itemModel.get('itemStyle.width');        if (width == null) {          width = itemSize;        } else {          width = parsePercent(width, viewWidth);          if (sort === 'ascending') {            width = -width;          }        }        var start = getLinePoints(idx, x);        var end = getLinePoints(nextIdx, x + width);        x += width + gap;        data.setItemLayout(idx, {          points: start.concat(end.slice().reverse())        });      } else {        var height = itemModel.get('itemStyle.height');        if (height == null) {          height = itemSize;        } else {          height = parsePercent(height, viewHeight);          if (sort === 'ascending') {            height = -height;          }        }        var start = orient === 'horizontal' ? getLinePoints(idx, x) : getLinePoints(idx, y);        var end = orient === 'horizontal' ? getLinePoints(nextIdx, x + width) : getLinePoints(nextIdx, y + height);        y += height + gap;        data.setItemLayout(idx, {          points: start.concat(end.slice().reverse())        });      }    }    labelLayout(data);  });}module.exports = _default;
 |