static/js/dncp/util/shape/Symbol.js
/**
* zrender
*
* @author Kener (@Kener-林峰, kener.linfeng@gmail.com)
*
* shape类:大规模散点图图形
* 可配图形属性:
{
// 基础属性
shape : 'symbol', // 必须,shape类标识,需要显式指定
id : {string}, // 必须,图形唯一标识,可通过'zrender/tool/guid'方法生成
zlevel : {number}, // 默认为0,z层level,决定绘画在哪层canvas中
invisible : {boolean}, // 默认为false,是否可见
// 样式属性,默认状态样式样式属性
style : {
pointList : {Array}, // 必须,二维数组,二维内容如下
x : {number}, // 必须,横坐标
y : {number}, // 必须,纵坐标数组
size : {number}, // 必须,半宽
type : {string=}, // 默认为'circle',图形类型
},
// 样式属性,高亮样式属性,当不存在highlightStyle时使用基于默认样式扩展显示
highlightStyle : {
// 同style
}
// 交互属性,详见shape.Base
// 事件属性,详见shape.Base
}
*/
define(function (require) {
var Base = require('zrender/shape/Base');
var PolygonShape = require('zrender/shape/Polygon');
var polygonInstance = new PolygonShape({});
var zrUtil = require('zrender/tool/util');
function Symbol(options) {
Base.call(this, options);
}
Symbol.prototype = {
type : 'symbol',
/**
* 创建矩形路径
* @param {Context2D} ctx Canvas 2D上下文
* @param {Object} style 样式
*/
buildPath : function (ctx, style) {
var pointList = style.pointList;
var len = pointList.length;
if (len === 0) {
return;
}
var subSize = 10000;
var subSetLength = Math.ceil(len / subSize);
var sub;
var subLen;
var isArray = pointList[0] instanceof Array;
var size = style.size ? style.size : 2;
var curSize = size;
var halfSize = size / 2;
var PI2 = Math.PI * 2;
var percent;
var x;
var y;
for (var j = 0; j < subSetLength; j++) {
ctx.beginPath();
sub = j * subSize;
subLen = sub + subSize;
subLen = subLen > len ? len : subLen;
for (var i = sub; i < subLen; i++) {
if (style.random) {
percent = style['randomMap' + (i % 20)] / 100;
curSize = size * percent * percent;
halfSize = curSize / 2;
}
if (isArray) {
x = pointList[i][0];
y = pointList[i][1];
}
else {
x = pointList[i].x;
y = pointList[i].y;
}
if (curSize < 3) {
// 小于3像素视觉误差
ctx.rect(x - halfSize, y - halfSize, curSize, curSize);
}
else {
// 大于3像素才考虑图形
switch (style.iconType) {
case 'circle' :
ctx.moveTo(x, y);
ctx.arc(x, y, halfSize, 0, PI2, true);
break;
case 'diamond' :
ctx.moveTo(x, y - halfSize);
ctx.lineTo(x + halfSize / 3, y - halfSize / 3);
ctx.lineTo(x + halfSize, y);
ctx.lineTo(x + halfSize / 3, y + halfSize / 3);
ctx.lineTo(x, y + halfSize);
ctx.lineTo(x - halfSize / 3, y + halfSize / 3);
ctx.lineTo(x - halfSize, y);
ctx.lineTo(x - halfSize / 3, y - halfSize / 3);
ctx.lineTo(x, y - halfSize);
break;
default :
ctx.rect(x - halfSize, y - halfSize, curSize, curSize);
}
}
}
ctx.closePath();
if (j < (subSetLength - 1)) {
switch (style.brushType) {
case 'both':
ctx.fill();
style.lineWidth > 0 && ctx.stroke(); // js hint -_-"
break;
case 'stroke':
style.lineWidth > 0 && ctx.stroke();
break;
default:
ctx.fill();
}
}
}
},
/* 像素模式
buildPath : function (ctx, style) {
var pointList = style.pointList;
var rect = this.getRect(style);
var ratio = window.devicePixelRatio || 1;
// console.log(rect)
// var ti = new Date();
// bbox取整
rect = {
x : Math.floor(rect.x),
y : Math.floor(rect.y),
width : Math.floor(rect.width),
height : Math.floor(rect.height)
};
var pixels = ctx.getImageData(
rect.x * ratio, rect.y * ratio,
rect.width * ratio, rect.height * ratio
);
var data = pixels.data;
var idx;
var zrColor = require('zrender/tool/color');
var color = zrColor.toArray(style.color);
var r = color[0];
var g = color[1];
var b = color[2];
var width = rect.width;
for (var i = 1, l = pointList.length; i < l; i++) {
idx = ((Math.floor(pointList[i][0]) - rect.x) * ratio
+ (Math.floor(pointList[i][1])- rect.y) * width * ratio * ratio
) * 4;
data[idx] = r;
data[idx + 1] = g;
data[idx + 2] = b;
data[idx + 3] = 255;
}
ctx.putImageData(pixels, rect.x * ratio, rect.y * ratio);
// console.log(new Date() - ti);
return;
},
*/
/**
* 返回矩形区域,用于局部刷新和文字定位
* @param {Object} style
*/
getRect : function (style) {
return style.__rect || polygonInstance.getRect(style);
},
isCover : require('./normalIsCover')
};
zrUtil.inherits(Symbol, Base);
return Symbol;
});