/** * 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; });