UNPKG

transcend-charts

Version:

Transcend is a charting and graph library for NUVI

781 lines (693 loc) 28.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _Numbers = require('../helpers/Numbers'); var _Numbers2 = _interopRequireDefault(_Numbers); var _Charts = require('../helpers/Charts'); var _Charts2 = _interopRequireDefault(_Charts); var _Color = require('./Color'); var _Color2 = _interopRequireDefault(_Color); var _ChartDictionary = require('./ChartDictionary'); var _ChartDictionary2 = _interopRequireDefault(_ChartDictionary); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var PieChart = function PieChart(htmlContainer, graphData, graphOptions) { var self = this; var htmlCanvas = null; var needsRender = false; var data = null; var plotVars = { graphArea: { top: 0, right: 0, bottom: 0, left: 0, width: 0, height: 0 } }; // this var is updated regularly in the render function to ensure it always contains correct data about the size and state of the graph var DEBUG = false; var fullScreenChangeListener; var webkitFullScreenChangeListener; var mozFullScreenChangeListener; var msFullScreenChangeListener; var resizeListener; var isDestroyed = false; var resizeTimer = null; var options = graphOptions; // background and padding if (!options.backgroundColor) { options.backgroundColor = new _Color2.default.Color('transparent'); } else { options.backgroundColor = new _Color2.default.Color(options.backgroundColor); } if (!options.padding) { options.padding = 0; } else { options.padding = parseFloat(options.padding); } // bar styles if (!options.fillColor) { options.fillColor = new _Color2.default.Color('#888888'); } else { options.fillColor = new _Color2.default.Color(options.fillColor); } if (!options.borderColor) { options.borderColor = new _Color2.default.Color('transparent'); } else { options.borderColor = new _Color2.default.Color(options.borderColor); } if (!options.borderWidth) { options.borderWidth = 0; } else { options.borderWidth = parseFloat(options.borderWidth); } // labels on the bars if (options.labelPosition !== 'bottom') { options.labelPosition = 'above'; } if (!options.labelFontSize) { //options.labelFontSize = 12; options.labelFontSizeAsPct = 0.33; } else if (typeof options.labelFontSize === 'string' && options.labelFontSize.indexOf('%') !== -1) { options.labelFontSizeAsPct = parseFloat(options.labelFontSize) / 100; } else { options.labelFontSize = parseFloat(options.labelFontSize); options.labelFontSizeAsPct = null; } if (!options.labelFontColor) { options.labelFontColor = options.gridFontColor; } else { options.labelFontColor = new _Color2.default.Color(options.labelFontColor); } if (!options.labelFontFamily) { options.labelFontFamily = 'Arial'; } if (!options.labelFontWeight) { options.labelFontWeight = '400'; } // values floating on top of each bar if (options.showValues === undefined || options.showValues === false) { options.showValues = false; } else { options.showValues = true; } if (!options.valueFontColor) { options.valueFontColor = options.gridFontColor; } if (!options.valueFontSize) { //options.valueFontSize = 50; options.valueFontSizeAsPct = 0.66; } else if (typeof options.valueFontSize === 'string' && options.valueFontSize.indexOf('%') !== -1) { options.valueFontSizeAsPct = parseFloat(options.valueFontSize) / 100; } else { options.valueFontSize = parseFloat(options.valueFontSize); options.valueFontSizeAsPct = null; } if (!options.valueFontFamily) { options.valueFontFamily = 'Arial'; } if (!options.valueFontWeight) { options.valueFontWeight = '400'; } if (!options.stripeWidth) { options.stripeWidth = 0; } else { options.stripeWidth = parseFloat(options.stripeWidth); } if (!options.stripeSpacing) { options.stripeSpacing = 10; } else { options.stripeSpacing = parseFloat(options.stripeSpacing); } if (!options.stripeColor) { options.stripeColor = new _Color2.default.Color('#ffffff'); } else { options.stripeColor = new _Color2.default.Color(options.stripeColor); } // show legend if (options.showLegend === undefined || options.showLegend === null || options.showLegend === true) { options.showLegend = true; } else { options.showLegend = false; } if (!options.legendFontSize) { options.legendFontSize = 24; } else { options.legendFontSize = parseFloat(options.legendFontSize); } if (!options.legendFontFamily) { options.legendFontFamily = 'Arial'; } if (!options.legendFontWeight) { options.legendFontWeight = '400'; } if (!options.legendFontColor) { options.legendFontColor = new _Color2.default.Color('#ffffff'); } else { options.legendFontColor = new _Color2.default.Color(options.legendFontColor); } if (!options.legendPadding) { options.legendPadding = 0; } else { options.legendPadding = parseFloat(options.legendPadding); } if (!options.legendBackgroundColor) { options.legendBackgroundColor = new _Color2.default.Color('transparent'); } else { options.legendBackgroundColor = new _Color2.default.Color(options.legendBackgroundColor); } if (!options.knockoutCenterColor) { options.knockoutCenterColor = new _Color2.default.Color('rgba(47, 47, 47, 1)'); } else { options.knockoutCenterColor = new _Color2.default.Color(options.knockoutCenterColor); } if (!options.knockoutOuterColor) { options.knockoutOuterColor = new _Color2.default.Color('rgba(47, 47, 47, 0.85)'); } else { options.knockoutOuterColor = new _Color2.default.Color(options.knockoutOuterColor); } var pxRatio = window.devicePixelRatio || 1; var knockoutCircleRadiusAsPct = 0.75; var valueSizeAsPctOfKnockoutDiameter = 0.75; var legendLabelValueSpacing = 10; var legendSpacing = 20; var legendLineHeight = 1.75; this.render = function (exportAsImage, scale) { if (!data) { return false; } var canvas = htmlCanvas; var ctx = canvas.getContext('2d'); if (!scale) { scale = 1; } var backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; if (exportAsImage) { canvas = document.createElement('CANVAS'); canvas.width = htmlCanvas.width * scale; canvas.height = htmlCanvas.height * scale; ctx = canvas.getContext('2d'); } // upscale this thang if the device pixel ratio is higher than 1 ctx.save(); if (pxRatio > 1 || scale !== 1) { ctx.scale(pxRatio / backingStoreRatio * scale, pxRatio / backingStoreRatio * scale); } var canvasWidth = canvas.width / (pxRatio / backingStoreRatio * scale); var canvasHeight = canvas.height / (pxRatio / backingStoreRatio * scale); // fill background ctx.clearRect(0, 0, canvasWidth, canvasHeight); if (options.backgroundColor.getRgba() !== 'transparent') { ctx.fillStyle = options.backgroundColor.getRgba(); ctx.fillRect(0, 0, canvasWidth, canvasHeight); } // calculate the total of all values var totalValue = _lodash2.default.sum(data, function (datum) { return datum.value; }); // calculate the widest value ctx.font = options.legendFontWeight + ' ' + options.legendFontSize + 'px ' + options.legendFontFamily; var datumWithWidestValue = _lodash2.default.max(data, function (datum) { var displayValue = datum.prefix + datum.value + datum.suffix; if (datum.displayValue) { displayValue = datum.displayValue; } return ctx.measureText(displayValue).width; }); var displayValue = datumWithWidestValue.prefix + datumWithWidestValue.value + datumWithWidestValue.suffix; if (datumWithWidestValue.displayValue) { displayValue = datumWithWidestValue.displayValue; } var datumWithWidestValueWidth = ctx.measureText(displayValue).width; // calculate the widest label var datumWithWidestLabel = _lodash2.default.max(data, function (datum) { return ctx.measureText(datum.name).width; }); var datumWithWidestLabelWidth = ctx.measureText(datumWithWidestLabel.name).width; // calculate grid area plotVars.graphArea = { left: options.padding, top: options.padding, right: options.padding, bottom: options.padding }; plotVars.graphArea.width = canvasWidth - plotVars.graphArea.left - plotVars.graphArea.right; plotVars.graphArea.height = canvasHeight - plotVars.graphArea.top - plotVars.graphArea.bottom; // set up a legend area if (options.showLegend) { // determine the size of the legend var legendHeight = data.length * (options.legendFontSize * legendLineHeight) + options.legendPadding * 2; var legendWidth = datumWithWidestLabelWidth + legendLabelValueSpacing + datumWithWidestValueWidth + options.legendPadding * 2; // determine the position of the legendArea plotVars.legendArea = { top: (canvasHeight - legendHeight) / 2, right: options.padding, bottom: (canvasHeight - legendHeight) / 2, left: canvasWidth - (options.padding + legendWidth) }; plotVars.legendArea.width = canvasWidth - plotVars.legendArea.right - plotVars.legendArea.left; plotVars.legendArea.height = canvasHeight - plotVars.legendArea.bottom - plotVars.legendArea.top; // determine the position of the graphArea plotVars.graphArea.right = options.padding + legendWidth + legendSpacing; plotVars.graphArea.width = canvasWidth - plotVars.graphArea.left - plotVars.graphArea.right; if (plotVars.graphArea.width > plotVars.graphArea.height) { var extraWidth = plotVars.graphArea.width - plotVars.graphArea.height; plotVars.graphArea.left += extraWidth / 2; plotVars.graphArea.right += extraWidth / 2; plotVars.legendArea.left -= extraWidth / 2; plotVars.legendArea.right -= extraWidth / 2; } ctx.fillStyle = options.legendBackgroundColor.toString(); ctx.fillRect(plotVars.legendArea.left, plotVars.legendArea.top, plotVars.legendArea.width, plotVars.legendArea.height); ctx.textAlign = 'left'; ctx.textBaseline = 'bottom'; for (var i = 0; i < data.length; i++) { var displayValue = data[i].prefix + data[i].value + data[i].suffix; if (data[i].displayValue) { displayValue = data[i].displayValue; } ctx.fillStyle = options.legendFontColor.toString(); ctx.fillText(data[i].name, plotVars.legendArea.left + options.legendPadding, plotVars.legendArea.top + (i + 1) * options.legendFontSize * legendLineHeight); ctx.fillStyle = data[i].fillColor.toString(); ctx.fillText(displayValue, plotVars.legendArea.left + options.legendPadding + datumWithWidestLabelWidth + legendLabelValueSpacing, plotVars.legendArea.top + (i + 1) * options.legendFontSize * legendLineHeight); data[i].boundingBox = { x: plotVars.legendArea.left + options.legendPadding, width: datumWithWidestLabelWidth + legendLabelValueSpacing + datumWithWidestValueWidth, y: plotVars.legendArea.top + i * options.legendFontSize * legendLineHeight, height: options.legendFontSize * legendLineHeight }; } } // determine the radius of the stinking pie chart var pieRadius = plotVars.graphArea.height / 2; if (plotVars.graphArea.width < plotVars.graphArea.height) { pieRadius = plotVars.graphArea.width / 2; } if (pieRadius < 0) { pieRadius = 1; } // let's set a var for the center of the pie var pieCenter = { x: plotVars.graphArea.left + (canvasWidth - plotVars.graphArea.left - plotVars.graphArea.right) / 2, y: plotVars.graphArea.top + (canvasHeight - plotVars.graphArea.top - plotVars.graphArea.bottom) / 2 }; // determine now whether something is highlighted or not var somethingIsHighlighted = false; for (var i = 0; i < data.length; i++) { if (data[i].isHighlighted) { somethingIsHighlighted = true; break; } } // render the blasted pie slices var movingRadian = -Math.PI / 2; for (var i = 0; i < data.length; i++) { var percent = data[i].value / totalValue; var fillColor = new _Color2.default.Color(data[i].fillColor); if (somethingIsHighlighted && !data[i].isHighlighted) { fillColor.fade(0.7); } ctx.fillStyle = fillColor.toString(); var strokeColor = new _Color2.default.Color(data[i].borderColor); ctx.strokeStyle = strokeColor.toString(); ctx.lineWidth = options.borderWidth; ctx.beginPath(); ctx.moveTo(pieCenter.x, pieCenter.y); ctx.lineTo(pieCenter.x + Math.cos(movingRadian) * pieRadius, pieCenter.y + Math.sin(movingRadian) * pieRadius); ctx.arc(pieCenter.x, pieCenter.y, pieRadius, movingRadian, movingRadian + percent * Math.PI * 2); ctx.lineTo(pieCenter.x, pieCenter.y); ctx.fill(); ctx.stroke(); if (options.stripeWidth && (!somethingIsHighlighted || data[i].isHighlighted)) { ctx.save(); ctx.clip(); ctx.lineWidth = options.stripeWidth; ctx.strokeStyle = options.stripeColor.toString(); ctx.beginPath(); for (var x = pieCenter.x - pieRadius - pieRadius * 2; x < pieCenter.x + pieRadius; x += options.stripeSpacing) { ctx.moveTo(x, pieCenter.y + pieRadius); ctx.lineTo(x + pieRadius * 2, pieCenter.y - pieRadius); } ctx.stroke(); ctx.restore(); } movingRadian += percent * Math.PI * 2; } // render the knockout with the percentage on top var fillGradient = ctx.createRadialGradient(pieCenter.x, pieCenter.y, 0, pieCenter.x, pieCenter.y, pieRadius * knockoutCircleRadiusAsPct); fillGradient.addColorStop(0.55, options.knockoutCenterColor); fillGradient.addColorStop(1, options.knockoutOuterColor); ctx.fillStyle = fillGradient; ctx.beginPath(); ctx.arc(pieCenter.x, pieCenter.y, pieRadius * knockoutCircleRadiusAsPct, 0, Math.PI * 2); ctx.fill(); if (somethingIsHighlighted) { // find the font size that makes the widest value fit in the knockout circle var highlightedValueFontSize = Math.floor(pieRadius * 2 * knockoutCircleRadiusAsPct); while (true) { var displayValue = datumWithWidestValue.prefix + datumWithWidestValue.value + datumWithWidestValue.suffix; if (datumWithWidestValue.displayValue) { displayValue = datumWithWidestValue.displayValue; } ctx.font = options.valueFontWeight + ' ' + highlightedValueFontSize + 'px ' + options.valueFontFamily; if (ctx.measureText(displayValue).width < pieRadius * 2 * knockoutCircleRadiusAsPct * valueSizeAsPctOfKnockoutDiameter) { break; } highlightedValueFontSize = Math.floor(highlightedValueFontSize * 0.9); } var highlightedLabelFontSize = Math.floor(pieRadius * 2 * knockoutCircleRadiusAsPct); while (true) { ctx.font = options.labelFontWeight + ' ' + highlightedLabelFontSize + 'px ' + options.labelFontFamily; if (ctx.measureText(datumWithWidestLabel.name).width < pieRadius * 2 * knockoutCircleRadiusAsPct * valueSizeAsPctOfKnockoutDiameter) { break; } highlightedLabelFontSize = Math.floor(highlightedLabelFontSize * 0.9); } highlightedLabelFontSize = _lodash2.default.min([highlightedLabelFontSize, options.labelFontSize]); // render the highlighted part if any for (var i = 0; i < data.length; i++) { if (data[i].isHighlighted) { var displayValue = data[i].prefix + data[i].value + data[i].suffix; if (data[i].displayValue) { displayValue = data[i].displayValue; } ctx.font = options.valueFontWeight + ' ' + highlightedValueFontSize + 'px ' + options.valueFontFamily; ctx.textAlign = 'center'; ctx.textBaseline = 'alphabetic'; ctx.fillStyle = data[i].fillColor.toString(); ctx.fillText(displayValue, pieCenter.x, pieCenter.y); ctx.textBaseline = 'top'; ctx.fillStyle = options.labelFontColor.toString(); ctx.font = options.labelFontWeight + ' ' + highlightedLabelFontSize + 'px ' + options.labelFontFamily; ctx.fillText(data[i].name, pieCenter.x, pieCenter.y); } } } // draw fps if (DEBUG) { ctx.fillStyle = '#666666'; ctx.fillRect(canvasWidth - 40, canvasHeight - 15, 40, 15); ctx.textAlign = 'right'; ctx.textBaseline = 'bottom'; ctx.fillStyle = '#000000'; ctx.font = '11px sans-serif'; ctx.fillText(String(Math.round(fps)) + ' fps', canvasWidth - 5, canvasHeight - 1); } ctx.restore(); if (exportAsImage) { return canvas.toDataURL('image/png'); } }; /*** * This publicly exposed method can be used to highlight a pie slice from outside of the class ***/ this.highlightPieSlice = function (dataSliceName) { for (var i = 0; i < data.length; i++) { if (data[i].name === dataSliceName) { data[i].isHighlighted = true; } else { data[i].isHighlighted = false; } } }; this.getBase64Image = function (scale) { // call render with a special flag return this.render(true, scale); }; /*** * Initialize some basic vars including the html canvas to render on ***/ function _init() { var _this = this; htmlCanvas = document.createElement('CANVAS'); htmlContainer.appendChild(htmlCanvas); self.setData(graphData); setTimeout(fillParent, 1); resizeListener = window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { fillParent.call(_this); }, 50); }); fullScreenChangeListener = window.addEventListener('webkitfullscreenchange', fullscreenChange); webkitFullScreenChangeListener = window.addEventListener('fullscreenchange', fullscreenChange); mozFullScreenChangeListener = window.addEventListener('mozfullscreenchange', fullscreenChange); msFullScreenChangeListener = window.addEventListener('msfullscreenchange', fullscreenChange); function fullscreenChange(event) { var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement; if (!fullscreenElement) { // exiting full screen var targetElement = event.target; // if this element contains a canvas, make it tiny so we don't mess up the size of its parent // don't worry, the window.resize event that fires next will make it fill its parent just fine var canvases = targetElement.getElementsByTagName('CANVAS'); for (var c = 0; c < canvases.length; c++) { if (canvases[c] === htmlCanvas) { canvases[c].width = 1; canvases[c].height = 1; canvases[c].style.width = '1px'; canvases[c].style.height = '1px'; break; } } } } var guid = _Charts2.default.createGuid(); _ChartDictionary2.default.push({ id: guid, canvasElement: htmlCanvas, chart: this }); htmlCanvas.setAttribute('data-chart-id', guid); // mousemove event if (options.showValues) { htmlCanvas.addEventListener('mouseout', handleMouseOut); htmlCanvas.addEventListener('mousemove', function (event) { var rect = htmlCanvas.getBoundingClientRect(); var pt = { x: event.clientX - rect.left, y: event.clientY - rect.top }; handleMouseMove(pt); }); htmlCanvas.addEventListener('mousedown', function (event) { var rect = htmlCanvas.getBoundingClientRect(); var pt = { x: event.clientX - rect.left, y: event.clientY - rect.top }; handleMouseClick(event, pt); }); } if (window.requestAnimationFrame) { window.requestAnimationFrame(animateFrame); } else if (window.webkitRequestAnimationFrame) { window.webkitRequestAnimationFrame(animateFrame); } else if (window.mozRequestAnimationFrame) { window.mozRequestAnimationFrame(animateFrame); } else if (window.oRequestAnimationFrame) { window.oRequestAnimationFrame(animateFrame); } } function handleMouseOut() { for (var i = 0; i < data.length; i++) { data[i].isHighlighted = false; } needsRender = true; } function handleMouseMove(pt) { var hoveredDataSlice = hitTestPieSlices(pt, function (dataSlice) { dataSlice.isHighlighted = true; }, function (dataSlice) { dataSlice.isHighlighted = false; }); if (hoveredDataSlice) { if (hoveredDataSlice.onClick) { htmlCanvas.style.cursor = 'pointer'; } else { htmlCanvas.style.cursor = 'default'; } } else { htmlCanvas.style.cursor = 'default'; } needsRender = true; } function handleMouseClick(event, pt) { var hoveredDataSlice = hitTestPieSlices(pt); if (hoveredDataSlice) { if (hoveredDataSlice.onClick) { hoveredDataSlice.onClick(event); } } } function hitTestPieSlices(pt, onHit, onMiss) { var ctx = htmlCanvas.getContext('2d'); // upscale this thang if the device pixel ratio is higher than 1 var backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; var canvasWidth = htmlCanvas.width / (pxRatio / backingStoreRatio); var canvasHeight = htmlCanvas.height / (pxRatio / backingStoreRatio); // determine the radius of the stinking pie chart var pieRadius = plotVars.graphArea.height / 2; if (plotVars.graphArea.width < plotVars.graphArea.height) { pieRadius = plotVars.graphArea.width / 2; } // let's set a var for the center of the pie var pieCenter = { x: plotVars.graphArea.left + (canvasWidth - plotVars.graphArea.left - plotVars.graphArea.right) / 2, y: plotVars.graphArea.top + (canvasHeight - plotVars.graphArea.top - plotVars.graphArea.bottom) / 2 }; // calculate the theta and radius based on the x, y var theta = Math.atan((pt.y - pieCenter.y) / (pt.x - pieCenter.x)); if (pt.y >= pieCenter.y && pt.x >= pieCenter.x) { // quadrant 1 theta += 0; } else if (pt.y >= pieCenter.y && pt.x < pieCenter.x) { // quadrant 2 theta += Math.PI; } else if (pt.y < pieCenter.y && pt.x < pieCenter.x) { // quadrant 3 theta += Math.PI; } else if (pt.y < pieCenter.y && pt.x >= pieCenter.x) { // quadrant 4 theta += 0; } var radius = Math.sqrt((pt.x - pieCenter.x) * (pt.x - pieCenter.x) + (pt.y - pieCenter.y) * (pt.y - pieCenter.y)); // calculate the total of all values var totalValue = _lodash2.default.sum(data, function (datum) { return datum.value; }); // hit test all the pie slices var highlightedDataSlice = null; var movingRadian = -Math.PI / 2; for (var i = 0; i < data.length; i++) { var percent = data[i].value / totalValue; var startRadian = movingRadian; var endRadian = movingRadian + percent * Math.PI * 2; // if the mouse is over this pie slice, mark it as highlighted if (theta >= startRadian && theta < endRadian && radius <= pieRadius) { if (onHit) { onHit(data[i]); } highlightedDataSlice = data[i]; } else { if (onMiss) { onMiss(data[i]); } } movingRadian += percent * Math.PI * 2; } // if you've already highlighted a pie slice, exit now if (highlightedDataSlice) return highlightedDataSlice; // hit test the legend for (var i = 0; i < data.length; i++) { if (data[i].boundingBox) { if (pt.x >= data[i].boundingBox.x && pt.x < data[i].boundingBox.x + data[i].boundingBox.width && pt.y >= data[i].boundingBox.y && pt.y < data[i].boundingBox.y + data[i].boundingBox.height) { if (onHit) { onHit(data[i]); } highlightedDataSlice = data[i]; } else { if (onMiss) { onMiss(data[i]); } } } } return highlightedDataSlice; } /*** * Fills the parent container with this canvas element ***/ function fillParent() { if (htmlCanvas && htmlCanvas.parentNode) { var style = window.getComputedStyle(htmlCanvas.parentNode); var width = htmlCanvas.parentNode.offsetWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight); var height = htmlCanvas.parentNode.offsetHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom); // upscale this thang if the device pixel ratio is higher than 1 htmlCanvas.width = width * pxRatio; htmlCanvas.height = height * pxRatio; htmlCanvas.style.width = width + 'px'; htmlCanvas.style.height = height + 'px'; } needsRender = true; } /*** * This function sets/resets the data for the graph ***/ this.setData = function (someData) { data = someData.slice(); if (data && data.length) { for (var i = 0; i < data.length; i++) { var parts = _Numbers2.default.separateNumberUnits(data[i].value); if (data[i].prefix === undefined) { data[i].prefix = parts.prefix; } if (data[i].suffix === undefined) { data[i].suffix = parts.suffix; } data[i].value = parts.value; if (data[i].fillColor) { data[i].fillColor = new _Color2.default.Color(data[i].fillColor); } else { data[i].fillColor = options.fillColor; } if (data[i].borderColor) { data[i].borderColor = new _Color2.default.Color(data[i].borderColor); } else { data[i].borderColor = options.borderColor; } if (data[i].stripeColor) { data[i].stripeColor = new _Color2.default.Color(data[i].stripeColor); } else { data[i].stripeColor = options.stripeColor; } } //console.log(data); } needsRender = true; }; /*** * The animateFrame method is called many times per second to calculate any * movement needed in the graph. It then calls render() to update the display. * Even if there is no animation in the graph this method ensures the view is updated frequently in case * mouse events change the view ***/ function animateFrame() { var thisFrame = new Date().getTime(); var elapsed = thisFrame - lastFrame; // elapsed time since last render fps = 1000 / elapsed; if (needsRender) { self.render(); needsRender = false; } lastFrame = thisFrame; if (!isDestroyed) { if (window.requestAnimationFrame) { window.requestAnimationFrame(animateFrame); } else if (window.webkitRequestAnimationFrame) { window.webkitRequestAnimationFrame(animateFrame); } else if (window.mozRequestAnimationFrame) { window.mozRequestAnimationFrame(animateFrame); } else if (window.oRequestAnimationFrame) { window.oRequestAnimationFrame(animateFrame); } } } var lastFrame = new Date().getTime(); // the timestamp of the last time the frame was last rendered var fps = 0; this.destroy = function () { if (fullScreenChangeListener) { window.removeEventListener('fullscreenchange', fullScreenChangeListener); } if (webkitFullScreenChangeListener) { window.removeEventListener('webkitfullscreenchange', webkitFullScreenChangeListener); } if (mozFullScreenChangeListener) { window.removeEventListener('mozfullscreenchange', mozFullScreenChangeListener); } if (msFullScreenChangeListener) { window.removeEventListener('msfullscreenchange', msFullScreenChangeListener); } if (resizeListener) { window.removeEventListener('resize', resizeListener); } if (htmlCanvas && htmlCanvas.parentNode) { htmlCanvas.parentNode.removeChild(htmlCanvas); } isDestroyed = true; }; // Initialize _init.call(this); }; exports.default = PieChart;