/** * @class Ext.chart.series.sprite.Pie3DPart * @extends Ext.draw.sprite.Path * * Pie3D series sprite. */Ext.define('Ext.chart.series.sprite.Pie3DPart', { extend: 'Ext.draw.sprite.Path', mixins: { markerHolder: 'Ext.chart.MarkerHolder' }, alias: 'sprite.pie3dPart', type: 'pie3dPart', inheritableStatics: { def: { processors: { /** * @cfg {Number} [centerX=0] The central point of the series on the x-axis. */ centerX: 'number', /** * @cfg {Number} [centerY=0] The central point of the series on the x-axis. */ centerY: 'number', /** * @cfg {Number} [startAngle=0] The starting angle of the polar series. */ startAngle: 'number', /** * @cfg {Number} [endAngle=Math.PI] The ending angle of the polar series. */ endAngle: 'number', /** * @cfg {Number} [startRho=0] The starting radius of the polar series. */ startRho: 'number', /** * @cfg {Number} [endRho=150] The ending radius of the polar series. */ endRho: 'number', /** * @cfg {Number} [margin=0] Margin from the center of the pie. Used for donut. */ margin: 'number', /** * @cfg {Number} [thickness=0] The thickness of the 3D pie part. */ thickness: 'number', /** * @cfg {Number} [distortion=0] The distortion of the 3D pie part. */ distortion: 'number', /** * @cfg {Object} [baseColor='white'] The color of the 3D pie part before adding the 3D effect. */ baseColor: 'color', /** * @cfg {Number} [baseRotation=0] The starting rotation of the polar series. */ baseRotation: 'number', /** * @cfg {String} [part='top'] The part of the 3D Pie represented by the sprite. */ part: 'enums(top,start,end,inner,outer)' }, aliases: { rho: 'endRho' }, triggers: { centerX: 'path,bbox', centerY: 'path,bbox', startAngle: 'path,partZIndex', endAngle: 'path,partZIndex', startRho: 'path', endRho: 'path,bbox', margin: 'path,bbox', thickness: 'path', baseRotation: 'path,partZIndex', baseColor: 'partZIndex,partColor', part: 'path,partZIndex' }, defaults: { centerX: 0, centerY: 0, startAngle: 0, endAngle: 0, startRho: 0, endRho: 150, margin: 0, distortion: 1, baseRotation: 0, baseColor: 'white', miterLimit: 1, part: 'top' }, updaters: { partColor: function (attr) { var color = Ext.draw.Color.fly(attr.baseColor), fillStyle; switch (attr.part) { case 'top': fillStyle = color.toString(); break; case 'outer': fillStyle = Ext.create('Ext.draw.gradient.Linear', { type: 'linear', stops: [ { offset: 0, color: color.createDarker(0.3).toString() }, { offset: 0.3, color: color.toString() }, { offset: 0.8, color: color.createLighter(0.2).toString() }, { offset: 1, color: color.createDarker(0.4).toString() } ] }); break; case 'start': fillStyle = color.createDarker(0.3).toString(); break; case 'end': fillStyle = color.createDarker(0.3).toString(); break; case 'inner': fillStyle = Ext.create('Ext.draw.gradient.Linear', { type: 'linear', stops: [ { offset: 0, color: color.createDarker(0.4).toString() }, { offset: 0.2, color: color.createLighter(0.2).toString() }, { offset: 0.7, color: color.toString() }, { offset: 1, color: color.createDarker(0.3).toString() } ] }); break; } attr.fillStyle = fillStyle; attr.canvasAttributes.fillStyle = fillStyle; }, partZIndex: function (attr) { var rotation = attr.baseRotation, midAngle = (attr.startAngle + attr.endAngle) * 0.5, depth = Math.sin(midAngle + rotation); switch (attr.part) { case 'top': attr.zIndex = 5; break; case 'outer': attr.zIndex = 4 + depth; break; case 'start': attr.zIndex = 1 + Math.sin(attr.startAngle + rotation); break; case 'end': attr.zIndex = 1 + Math.sin(attr.endAngle + rotation); break; case 'inner': attr.zIndex = 1 + depth; break; } attr.dirtyZIndex = true; } } } }, updatePlainBBox: function (plain) { var attr = this.attr, rho = attr.part === 'inner' ? attr.startRho : attr.endRho; plain.width = rho * 2; plain.height = rho * attr.distortion * 2 + attr.thickness; plain.x = attr.centerX - rho; plain.y = attr.centerY - rho * attr.distortion; }, updateTransformedBBox: function (transform) { return this.updatePlainBBox(transform); }, updatePath: function (path) { if (this.attr.endAngle < this.attr.startAngle) { return; } this[this.attr.part + 'Renderer'](path); }, topRenderer: function (path) { var attr = this.attr, margin = attr.margin, distortion = attr.distortion, centerX = attr.centerX, centerY = attr.centerY, baseRotation = attr.baseRotation, startAngle = attr.startAngle + baseRotation, endAngle = attr.endAngle + baseRotation, midAngle = (startAngle + endAngle) * 0.5, startRho = attr.startRho, endRho = attr.endRho, sinEnd = Math.sin(endAngle), cosEnd = Math.cos(endAngle); centerX += Math.cos(midAngle) * margin; centerY += Math.sin(midAngle) * margin * distortion; path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, startAngle, endAngle, false); path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion); path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, endAngle, startAngle, true); path.closePath(); }, startRenderer: function (path) { var attr = this.attr, margin = attr.margin, centerX = attr.centerX, centerY = attr.centerY, distortion = attr.distortion, baseRotation = attr.baseRotation, startAngle = attr.startAngle + baseRotation , endAngle = attr.endAngle + baseRotation, thickness = attr.thickness, startRho = attr.startRho, endRho = attr.endRho, sinStart = Math.sin(startAngle), cosStart = Math.cos(startAngle), midAngle; if (cosStart < 0) { midAngle = (startAngle + endAngle) * 0.5; centerX += Math.cos(midAngle) * margin; centerY += Math.sin(midAngle) * margin * distortion; path.moveTo(centerX + cosStart * startRho, centerY + sinStart * startRho * distortion); path.lineTo(centerX + cosStart * endRho, centerY + sinStart * endRho * distortion); path.lineTo(centerX + cosStart * endRho, centerY + sinStart * endRho * distortion + thickness); path.lineTo(centerX + cosStart * startRho, centerY + sinStart * startRho * distortion + thickness); path.closePath(); } }, endRenderer: function (path) { var attr = this.attr, margin = attr.margin, centerX = attr.centerX, centerY = attr.centerY, distortion = attr.distortion, baseRotation = attr.baseRotation, startAngle = attr.startAngle + baseRotation , endAngle = attr.endAngle + baseRotation, thickness = attr.thickness, startRho = attr.startRho, endRho = attr.endRho, sin = Math.sin(endAngle), cos = Math.cos(endAngle), midAngle; if (cos > 0) { midAngle = (startAngle + endAngle) * 0.5; centerX += Math.cos(midAngle) * margin; centerY += Math.sin(midAngle) * margin * distortion; path.moveTo(centerX + cos * startRho, centerY + sin * startRho * distortion); path.lineTo(centerX + cos * endRho, centerY + sin * endRho * distortion); path.lineTo(centerX + cos * endRho, centerY + sin * endRho * distortion + thickness); path.lineTo(centerX + cos * startRho, centerY + sin * startRho * distortion + thickness); path.closePath(); } }, innerRenderer: function (path) { var attr = this.attr, margin = attr.margin, centerX = attr.centerX, centerY = attr.centerY, distortion = attr.distortion, baseRotation = attr.baseRotation, startAngle = attr.startAngle + baseRotation , endAngle = attr.endAngle + baseRotation, midAngle = (startAngle + endAngle) * 0.5, thickness = attr.thickness, startRho = attr.startRho, isTranslucent = attr.globalAlpha < 1, sinEnd, cosEnd, tempStart, tempEnd; centerX += Math.cos(midAngle) * margin; centerY += Math.sin(midAngle) * margin * distortion; if (startAngle >= Math.PI * 2 || isTranslucent) { startAngle -= Math.PI * 2; endAngle -= Math.PI * 2; } if (endAngle > Math.PI && endAngle < Math.PI * 3 || isTranslucent) { tempStart = startAngle; tempEnd = Math.min(endAngle, Math.PI * 2); sinEnd = Math.sin(tempEnd); cosEnd = Math.cos(tempEnd); path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, tempStart, tempEnd, false); path.lineTo(centerX + cosEnd * startRho, centerY + sinEnd * startRho * distortion + thickness); path.ellipse(centerX, centerY + thickness, startRho, startRho * distortion, 0, tempEnd, tempStart, true); path.closePath(); } if (endAngle > Math.PI * 3) { tempStart = Math.PI; tempEnd = endAngle; sinEnd = Math.sin(tempEnd); cosEnd = Math.cos(tempEnd); path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, tempStart, tempEnd, false); path.lineTo(centerX + cosEnd * startRho, centerY + sinEnd * startRho * distortion + thickness); path.ellipse(centerX, centerY + thickness, startRho, startRho * distortion, 0, tempEnd, tempStart, true); path.closePath(); } }, outerRenderer: function (path) { var attr = this.attr, margin = attr.margin, centerX = attr.centerX, centerY = attr.centerY, distortion = attr.distortion, baseRotation = attr.baseRotation, startAngle = attr.startAngle + baseRotation , endAngle = attr.endAngle + baseRotation, midAngle = (startAngle + endAngle) * 0.5, thickness = attr.thickness, endRho = attr.endRho, isTranslucent = attr.globalAlpha < 1, sinEnd, cosEnd, tempStart, tempEnd; centerX += Math.cos(midAngle) * margin; centerY += Math.sin(midAngle) * margin * distortion; if (startAngle >= Math.PI * 2 || isTranslucent) { startAngle -= Math.PI * 4; endAngle -= Math.PI * 4; } if (startAngle < Math.PI || isTranslucent) { tempStart = startAngle; tempEnd = Math.min(endAngle, Math.PI); sinEnd = Math.sin(tempEnd); cosEnd = Math.cos(tempEnd); path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, tempStart, tempEnd, false); path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion + thickness); path.ellipse(centerX, centerY + thickness, endRho, endRho * distortion, 0, tempEnd, tempStart, true); path.closePath(); } if (endAngle > Math.PI * 2) { tempStart = Math.max(startAngle, Math.PI * 2); tempEnd = endAngle; sinEnd = Math.sin(tempEnd); cosEnd = Math.cos(tempEnd); path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, tempStart, tempEnd, false); path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion + thickness); path.ellipse(centerX, centerY + thickness, endRho, endRho * distortion, 0, tempEnd, tempStart, true); path.closePath(); } }});