| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377 | 
/** 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 PointerPath = require("./PointerPath");var graphic = require("../../util/graphic");var ChartView = require("../../view/Chart");var _number = require("../../util/number");var parsePercent = _number.parsePercent;var round = _number.round;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 parsePosition(seriesModel, api) {  var center = seriesModel.get('center');  var width = api.getWidth();  var height = api.getHeight();  var size = Math.min(width, height);  var cx = parsePercent(center[0], api.getWidth());  var cy = parsePercent(center[1], api.getHeight());  var r = parsePercent(seriesModel.get('radius'), size / 2);  return {    cx: cx,    cy: cy,    r: r  };}function formatLabel(label, labelFormatter) {  if (labelFormatter) {    if (typeof labelFormatter === 'string') {      label = labelFormatter.replace('{value}', label != null ? label : '');    } else if (typeof labelFormatter === 'function') {      label = labelFormatter(label);    }  }  return label;}var PI2 = Math.PI * 2;var GaugeView = ChartView.extend({  type: 'gauge',  render: function (seriesModel, ecModel, api) {    this.group.removeAll();    var colorList = seriesModel.get('axisLine.lineStyle.color');    var posInfo = parsePosition(seriesModel, api);    this._renderMain(seriesModel, ecModel, api, colorList, posInfo);  },  dispose: function () {},  _renderMain: function (seriesModel, ecModel, api, colorList, posInfo) {    var group = this.group;    var axisLineModel = seriesModel.getModel('axisLine');    var lineStyleModel = axisLineModel.getModel('lineStyle');    var clockwise = seriesModel.get('clockwise');    var startAngle = -seriesModel.get('startAngle') / 180 * Math.PI;    var endAngle = -seriesModel.get('endAngle') / 180 * Math.PI;    var angleRangeSpan = (endAngle - startAngle) % PI2;    var prevEndAngle = startAngle;    var axisLineWidth = lineStyleModel.get('width');    var showAxis = axisLineModel.get('show');    for (var i = 0; showAxis && i < colorList.length; i++) {      // Clamp      var percent = Math.min(Math.max(colorList[i][0], 0), 1);      var endAngle = startAngle + angleRangeSpan * percent;      var sector = new graphic.Sector({        shape: {          startAngle: prevEndAngle,          endAngle: endAngle,          cx: posInfo.cx,          cy: posInfo.cy,          clockwise: clockwise,          r0: posInfo.r - axisLineWidth,          r: posInfo.r        },        silent: true      });      sector.setStyle({        fill: colorList[i][1]      });      sector.setStyle(lineStyleModel.getLineStyle( // Because we use sector to simulate arc      // so the properties for stroking are useless      ['color', 'borderWidth', 'borderColor']));      group.add(sector);      prevEndAngle = endAngle;    }    var getColor = function (percent) {      // Less than 0      if (percent <= 0) {        return colorList[0][1];      }      for (var i = 0; i < colorList.length; i++) {        if (colorList[i][0] >= percent && (i === 0 ? 0 : colorList[i - 1][0]) < percent) {          return colorList[i][1];        }      } // More than 1      return colorList[i - 1][1];    };    if (!clockwise) {      var tmp = startAngle;      startAngle = endAngle;      endAngle = tmp;    }    this._renderTicks(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise);    this._renderPointer(seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise);    this._renderTitle(seriesModel, ecModel, api, getColor, posInfo);    this._renderDetail(seriesModel, ecModel, api, getColor, posInfo);  },  _renderTicks: function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise) {    var group = this.group;    var cx = posInfo.cx;    var cy = posInfo.cy;    var r = posInfo.r;    var minVal = +seriesModel.get('min');    var maxVal = +seriesModel.get('max');    var splitLineModel = seriesModel.getModel('splitLine');    var tickModel = seriesModel.getModel('axisTick');    var labelModel = seriesModel.getModel('axisLabel');    var splitNumber = seriesModel.get('splitNumber');    var subSplitNumber = tickModel.get('splitNumber');    var splitLineLen = parsePercent(splitLineModel.get('length'), r);    var tickLen = parsePercent(tickModel.get('length'), r);    var angle = startAngle;    var step = (endAngle - startAngle) / splitNumber;    var subStep = step / subSplitNumber;    var splitLineStyle = splitLineModel.getModel('lineStyle').getLineStyle();    var tickLineStyle = tickModel.getModel('lineStyle').getLineStyle();    for (var i = 0; i <= splitNumber; i++) {      var unitX = Math.cos(angle);      var unitY = Math.sin(angle); // Split line      if (splitLineModel.get('show')) {        var splitLine = new graphic.Line({          shape: {            x1: unitX * r + cx,            y1: unitY * r + cy,            x2: unitX * (r - splitLineLen) + cx,            y2: unitY * (r - splitLineLen) + cy          },          style: splitLineStyle,          silent: true        });        if (splitLineStyle.stroke === 'auto') {          splitLine.setStyle({            stroke: getColor(i / splitNumber)          });        }        group.add(splitLine);      } // Label      if (labelModel.get('show')) {        var label = formatLabel(round(i / splitNumber * (maxVal - minVal) + minVal), labelModel.get('formatter'));        var distance = labelModel.get('distance');        var autoColor = getColor(i / splitNumber);        group.add(new graphic.Text({          style: graphic.setTextStyle({}, labelModel, {            text: label,            x: unitX * (r - splitLineLen - distance) + cx,            y: unitY * (r - splitLineLen - distance) + cy,            textVerticalAlign: unitY < -0.4 ? 'top' : unitY > 0.4 ? 'bottom' : 'middle',            textAlign: unitX < -0.4 ? 'left' : unitX > 0.4 ? 'right' : 'center'          }, {            autoColor: autoColor          }),          silent: true        }));      } // Axis tick      if (tickModel.get('show') && i !== splitNumber) {        for (var j = 0; j <= subSplitNumber; j++) {          var unitX = Math.cos(angle);          var unitY = Math.sin(angle);          var tickLine = new graphic.Line({            shape: {              x1: unitX * r + cx,              y1: unitY * r + cy,              x2: unitX * (r - tickLen) + cx,              y2: unitY * (r - tickLen) + cy            },            silent: true,            style: tickLineStyle          });          if (tickLineStyle.stroke === 'auto') {            tickLine.setStyle({              stroke: getColor((i + j / subSplitNumber) / splitNumber)            });          }          group.add(tickLine);          angle += subStep;        }        angle -= subStep;      } else {        angle += step;      }    }  },  _renderPointer: function (seriesModel, ecModel, api, getColor, posInfo, startAngle, endAngle, clockwise) {    var group = this.group;    var oldData = this._data;    if (!seriesModel.get('pointer.show')) {      // Remove old element      oldData && oldData.eachItemGraphicEl(function (el) {        group.remove(el);      });      return;    }    var valueExtent = [+seriesModel.get('min'), +seriesModel.get('max')];    var angleExtent = [startAngle, endAngle];    var data = seriesModel.getData();    var valueDim = data.mapDimension('value');    data.diff(oldData).add(function (idx) {      var pointer = new PointerPath({        shape: {          angle: startAngle        }      });      graphic.initProps(pointer, {        shape: {          angle: linearMap(data.get(valueDim, idx), valueExtent, angleExtent, true)        }      }, seriesModel);      group.add(pointer);      data.setItemGraphicEl(idx, pointer);    }).update(function (newIdx, oldIdx) {      var pointer = oldData.getItemGraphicEl(oldIdx);      graphic.updateProps(pointer, {        shape: {          angle: linearMap(data.get(valueDim, newIdx), valueExtent, angleExtent, true)        }      }, seriesModel);      group.add(pointer);      data.setItemGraphicEl(newIdx, pointer);    }).remove(function (idx) {      var pointer = oldData.getItemGraphicEl(idx);      group.remove(pointer);    }).execute();    data.eachItemGraphicEl(function (pointer, idx) {      var itemModel = data.getItemModel(idx);      var pointerModel = itemModel.getModel('pointer');      pointer.setShape({        x: posInfo.cx,        y: posInfo.cy,        width: parsePercent(pointerModel.get('width'), posInfo.r),        r: parsePercent(pointerModel.get('length'), posInfo.r)      });      pointer.useStyle(itemModel.getModel('itemStyle').getItemStyle());      if (pointer.style.fill === 'auto') {        pointer.setStyle('fill', getColor(linearMap(data.get(valueDim, idx), valueExtent, [0, 1], true)));      }      graphic.setHoverStyle(pointer, itemModel.getModel('emphasis.itemStyle').getItemStyle());    });    this._data = data;  },  _renderTitle: function (seriesModel, ecModel, api, getColor, posInfo) {    var data = seriesModel.getData();    var valueDim = data.mapDimension('value');    var titleModel = seriesModel.getModel('title');    if (titleModel.get('show')) {      var offsetCenter = titleModel.get('offsetCenter');      var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);      var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);      var minVal = +seriesModel.get('min');      var maxVal = +seriesModel.get('max');      var value = seriesModel.getData().get(valueDim, 0);      var autoColor = getColor(linearMap(value, [minVal, maxVal], [0, 1], true));      this.group.add(new graphic.Text({        silent: true,        style: graphic.setTextStyle({}, titleModel, {          x: x,          y: y,          // FIXME First data name ?          text: data.getName(0),          textAlign: 'center',          textVerticalAlign: 'middle'        }, {          autoColor: autoColor,          forceRich: true        })      }));    }  },  _renderDetail: function (seriesModel, ecModel, api, getColor, posInfo) {    var detailModel = seriesModel.getModel('detail');    var minVal = +seriesModel.get('min');    var maxVal = +seriesModel.get('max');    if (detailModel.get('show')) {      var offsetCenter = detailModel.get('offsetCenter');      var x = posInfo.cx + parsePercent(offsetCenter[0], posInfo.r);      var y = posInfo.cy + parsePercent(offsetCenter[1], posInfo.r);      var width = parsePercent(detailModel.get('width'), posInfo.r);      var height = parsePercent(detailModel.get('height'), posInfo.r);      var data = seriesModel.getData();      var value = data.get(data.mapDimension('value'), 0);      var autoColor = getColor(linearMap(value, [minVal, maxVal], [0, 1], true));      this.group.add(new graphic.Text({        silent: true,        style: graphic.setTextStyle({}, detailModel, {          x: x,          y: y,          text: formatLabel( // FIXME First data name ?          value, detailModel.get('formatter')),          textWidth: isNaN(width) ? null : width,          textHeight: isNaN(height) ? null : height,          textAlign: 'center',          textVerticalAlign: 'middle'        }, {          autoColor: autoColor,          forceRich: true        })      }));    }  }});var _default = GaugeView;module.exports = _default;
 |