| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 | 
/** 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 zrUtil = require("zrender/lib/core/util");var graphic = require("./graphic");var BoundingRect = require("zrender/lib/core/BoundingRect");var _text = require("zrender/lib/contain/text");var calculateTextPosition = _text.calculateTextPosition;/** 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.*/// Symbol factory/** * Triangle shape * @inner */var Triangle = graphic.extendShape({  type: 'triangle',  shape: {    cx: 0,    cy: 0,    width: 0,    height: 0  },  buildPath: function (path, shape) {    var cx = shape.cx;    var cy = shape.cy;    var width = shape.width / 2;    var height = shape.height / 2;    path.moveTo(cx, cy - height);    path.lineTo(cx + width, cy + height);    path.lineTo(cx - width, cy + height);    path.closePath();  }});/** * Diamond shape * @inner */var Diamond = graphic.extendShape({  type: 'diamond',  shape: {    cx: 0,    cy: 0,    width: 0,    height: 0  },  buildPath: function (path, shape) {    var cx = shape.cx;    var cy = shape.cy;    var width = shape.width / 2;    var height = shape.height / 2;    path.moveTo(cx, cy - height);    path.lineTo(cx + width, cy);    path.lineTo(cx, cy + height);    path.lineTo(cx - width, cy);    path.closePath();  }});/** * Pin shape * @inner */var Pin = graphic.extendShape({  type: 'pin',  shape: {    // x, y on the cusp    x: 0,    y: 0,    width: 0,    height: 0  },  buildPath: function (path, shape) {    var x = shape.x;    var y = shape.y;    var w = shape.width / 5 * 3; // Height must be larger than width    var h = Math.max(w, shape.height);    var r = w / 2; // Dist on y with tangent point and circle center    var dy = r * r / (h - r);    var cy = y - h + r + dy;    var angle = Math.asin(dy / r); // Dist on x with tangent point and circle center    var dx = Math.cos(angle) * r;    var tanX = Math.sin(angle);    var tanY = Math.cos(angle);    var cpLen = r * 0.6;    var cpLen2 = r * 0.7;    path.moveTo(x - dx, cy + dy);    path.arc(x, cy, r, Math.PI - angle, Math.PI * 2 + angle);    path.bezierCurveTo(x + dx - tanX * cpLen, cy + dy + tanY * cpLen, x, y - cpLen2, x, y);    path.bezierCurveTo(x, y - cpLen2, x - dx + tanX * cpLen, cy + dy + tanY * cpLen, x - dx, cy + dy);    path.closePath();  }});/** * Arrow shape * @inner */var Arrow = graphic.extendShape({  type: 'arrow',  shape: {    x: 0,    y: 0,    width: 0,    height: 0  },  buildPath: function (ctx, shape) {    var height = shape.height;    var width = shape.width;    var x = shape.x;    var y = shape.y;    var dx = width / 3 * 2;    ctx.moveTo(x, y);    ctx.lineTo(x + dx, y + height);    ctx.lineTo(x, y + height / 4 * 3);    ctx.lineTo(x - dx, y + height);    ctx.lineTo(x, y);    ctx.closePath();  }});/** * Map of path contructors * @type {Object.<string, module:zrender/graphic/Path>} */var symbolCtors = {  line: graphic.Line,  rect: graphic.Rect,  roundRect: graphic.Rect,  square: graphic.Rect,  circle: graphic.Circle,  diamond: Diamond,  pin: Pin,  arrow: Arrow,  triangle: Triangle};var symbolShapeMakers = {  line: function (x, y, w, h, shape) {    // FIXME    shape.x1 = x;    shape.y1 = y + h / 2;    shape.x2 = x + w;    shape.y2 = y + h / 2;  },  rect: function (x, y, w, h, shape) {    shape.x = x;    shape.y = y;    shape.width = w;    shape.height = h;  },  roundRect: function (x, y, w, h, shape) {    shape.x = x;    shape.y = y;    shape.width = w;    shape.height = h;    shape.r = Math.min(w, h) / 4;  },  square: function (x, y, w, h, shape) {    var size = Math.min(w, h);    shape.x = x;    shape.y = y;    shape.width = size;    shape.height = size;  },  circle: function (x, y, w, h, shape) {    // Put circle in the center of square    shape.cx = x + w / 2;    shape.cy = y + h / 2;    shape.r = Math.min(w, h) / 2;  },  diamond: function (x, y, w, h, shape) {    shape.cx = x + w / 2;    shape.cy = y + h / 2;    shape.width = w;    shape.height = h;  },  pin: function (x, y, w, h, shape) {    shape.x = x + w / 2;    shape.y = y + h / 2;    shape.width = w;    shape.height = h;  },  arrow: function (x, y, w, h, shape) {    shape.x = x + w / 2;    shape.y = y + h / 2;    shape.width = w;    shape.height = h;  },  triangle: function (x, y, w, h, shape) {    shape.cx = x + w / 2;    shape.cy = y + h / 2;    shape.width = w;    shape.height = h;  }};var symbolBuildProxies = {};zrUtil.each(symbolCtors, function (Ctor, name) {  symbolBuildProxies[name] = new Ctor();});var SymbolClz = graphic.extendShape({  type: 'symbol',  shape: {    symbolType: '',    x: 0,    y: 0,    width: 0,    height: 0  },  calculateTextPosition: function (out, style, rect) {    var res = calculateTextPosition(out, style, rect);    var shape = this.shape;    if (shape && shape.symbolType === 'pin' && style.textPosition === 'inside') {      res.y = rect.y + rect.height * 0.4;    }    return res;  },  buildPath: function (ctx, shape, inBundle) {    var symbolType = shape.symbolType;    if (symbolType !== 'none') {      var proxySymbol = symbolBuildProxies[symbolType];      if (!proxySymbol) {        // Default rect        symbolType = 'rect';        proxySymbol = symbolBuildProxies[symbolType];      }      symbolShapeMakers[symbolType](shape.x, shape.y, shape.width, shape.height, proxySymbol.shape);      proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);    }  }}); // Provide setColor helper method to avoid determine if set the fill or stroke outsidefunction symbolPathSetColor(color, innerColor) {  if (this.type !== 'image') {    var symbolStyle = this.style;    var symbolShape = this.shape;    if (symbolShape && symbolShape.symbolType === 'line') {      symbolStyle.stroke = color;    } else if (this.__isEmptyBrush) {      symbolStyle.stroke = color;      symbolStyle.fill = innerColor || '#fff';    } else {      // FIXME 判断图形默认是填充还是描边,使用 onlyStroke ?      symbolStyle.fill && (symbolStyle.fill = color);      symbolStyle.stroke && (symbolStyle.stroke = color);    }    this.dirty(false);  }}/** * Create a symbol element with given symbol configuration: shape, x, y, width, height, color * @param {string} symbolType * @param {number} x * @param {number} y * @param {number} w * @param {number} h * @param {string} color * @param {boolean} [keepAspect=false] whether to keep the ratio of w/h, *                            for path and image only. */function createSymbol(symbolType, x, y, w, h, color, keepAspect) {  // TODO Support image object, DynamicImage.  var isEmpty = symbolType.indexOf('empty') === 0;  if (isEmpty) {    symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);  }  var symbolPath;  if (symbolType.indexOf('image://') === 0) {    symbolPath = graphic.makeImage(symbolType.slice(8), new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');  } else if (symbolType.indexOf('path://') === 0) {    symbolPath = graphic.makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');  } else {    symbolPath = new SymbolClz({      shape: {        symbolType: symbolType,        x: x,        y: y,        width: w,        height: h      }    });  }  symbolPath.__isEmptyBrush = isEmpty;  symbolPath.setColor = symbolPathSetColor;  symbolPath.setColor(color);  return symbolPath;}exports.createSymbol = createSymbol;
 |