VCanvas_vml = createClass(VCanvas_base, { init: function (width, height, target) { var groupel; VCanvas_vml._super.init.call(this, width, height, target); if (target[0]) { target = target[0]; } $.data(target, '_jqs_vcanvas', this); this.canvas = document.createElement('span'); $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'}); this._insert(this.canvas, target); this._calculatePixelDims(width, height, this.canvas); this.canvas.width = this.pixelWidth; this.canvas.height = this.pixelHeight; groupel = ''; this.canvas.insertAdjacentHTML('beforeEnd', groupel); this.group = $(this.canvas).children()[0]; this.rendered = false; this.prerender = ''; }, _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) { var vpath = [], initial, stroke, fill, closed, vel, plen, i; for (i = 0, plen = path.length; i < plen; i++) { vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]); } initial = vpath.splice(0, 1); lineWidth = lineWidth === undefined ? 1 : lineWidth; stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : ''; vel = '' + ' '; return vel; }, _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) { var stroke, fill, vel; x -= radius; y -= radius; stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="' + lineWidth + 'px" strokeColor="' + lineColor + '" '; fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; vel = ''; return vel; }, _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) { var vpath, startx, starty, endx, endy, stroke, fill, vel; if (startAngle === endAngle) { return ''; // VML seems to have problem when start angle equals end angle. } if ((endAngle - startAngle) === (2 * Math.PI)) { startAngle = 0.0; // VML seems to have a problem when drawing a full circle that doesn't start 0 endAngle = (2 * Math.PI); } startx = x + Math.round(Math.cos(startAngle) * radius); starty = y + Math.round(Math.sin(startAngle) * radius); endx = x + Math.round(Math.cos(endAngle) * radius); endy = y + Math.round(Math.sin(endAngle) * radius); if (startx === endx && starty === endy) { if ((endAngle - startAngle) < Math.PI) { // Prevent very small slices from being mistaken as a whole pie return ''; } // essentially going to be the entire circle, so ignore startAngle startx = endx = x + radius; starty = endy = y; } if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) { return ''; } vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy]; stroke = lineColor === undefined ? ' stroked="false" ' : ' strokeWeight="1px" strokeColor="' + lineColor + '" '; fill = fillColor === undefined ? ' filled="false"' : ' fillColor="' + fillColor + '" filled="true" '; vel = '' + ' '; return vel; }, _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) { return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor); }, reset: function () { this.group.innerHTML = ''; }, appendShape: function (shape) { var vel = this['_draw' + shape.type].apply(this, shape.args); if (this.rendered) { this.group.insertAdjacentHTML('beforeEnd', vel); } else { this.prerender += vel; } this.lastShapeId = shape.id; return shape.id; }, replaceWithShape: function (shapeid, shape) { var existing = $('#jqsshape' + shapeid), vel = this['_draw' + shape.type].apply(this, shape.args); existing[0].outerHTML = vel; }, replaceWithShapes: function (shapeids, shapes) { // replace the first shapeid with all the new shapes then toast the remaining old shapes var existing = $('#jqsshape' + shapeids[0]), replace = '', slen = shapes.length, i; for (i = 0; i < slen; i++) { replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args); } existing[0].outerHTML = replace; for (i = 1; i < shapeids.length; i++) { $('#jqsshape' + shapeids[i]).remove(); } }, insertAfterShape: function (shapeid, shape) { var existing = $('#jqsshape' + shapeid), vel = this['_draw' + shape.type].apply(this, shape.args); existing[0].insertAdjacentHTML('afterEnd', vel); }, removeShapeId: function (shapeid) { var existing = $('#jqsshape' + shapeid); this.group.removeChild(existing[0]); }, getShapeAt: function (el, x, y) { var shapeid = el.id.substr(8); return shapeid; }, render: function () { if (!this.rendered) { // batch the intial render into a single repaint this.group.innerHTML = this.prerender; this.rendered = true; } } });