Index: lams_central/web/includes/javascript/chart.js =================================================================== diff -u -ra83b0eec89979dce7415b02afdda324b14018dbb -r5b76fc85b49c6dc9dbedfac8b235e9e3d56ef8fe --- lams_central/web/includes/javascript/chart.js (.../chart.js) (revision a83b0eec89979dce7415b02afdda324b14018dbb) +++ lams_central/web/includes/javascript/chart.js (.../chart.js) (revision 5b76fc85b49c6dc9dbedfac8b235e9e3d56ef8fe) @@ -1,65 +1,76 @@ /** - * Prepares SVG area for drawing and runs concrete chart function. + * Identifies data source and runs chart drawing function. */ -function drawChart(type, chartID, url, legendOnHover){ - // get data with the given URL - d3.json(url, function(error, response){ - if (error) { - // forward error to browser - throw error; - } - - if (!response || $.isEmptyObject(response)) { - // if there is no data to display - return; - } - - // clear previous chart - var rawData = response.data, - chartDiv = $('#' + chartID).empty().show(), - width = chartDiv.width(), - height = chartDiv.height(), - // add SVG elem - svg = d3.select(chartDiv[0]) - .append('svg') - .attr('width', width) - .attr('height', height); - // build domain out of keys - domainX = rawData.map(function(d) { return d.name }), - // 10 color palette - scaleColor = d3.scaleOrdinal(d3.schemeCategory10) - .domain(domainX), - legend = null; - - if (!legendOnHover) { - legend = svg.append('g'); - // build legend first so we know how much space we've got for the chart - $.each(rawData, function(index, d){ - // a small rectangle with proper color - legend.append('rect') - .attr('x', 0) - .attr('y', index * 30) - .attr('width', 15) - .attr('height', 15) - .attr('fill', scaleColor(d.name)); - // label - legend.append('text') - .attr('x', 20) - .attr('y', index * 30 + 11) - .attr('text-anchor', 'start') - .text(d.name + ' (' + Math.round(+d.value) + ' %)'); +function drawChart(type, chartID, dataSource, legendOnHover){ + switch (typeof dataSource) { + case 'string': + // get data with the given URL + d3.json(dataSource, function(error, response){ + if (error) { + // forward error to browser + throw error; + } + + if (!response || $.isEmptyObject(response)) { + // if there is no data to display + return; + } + + _drawChart(type, chartID, response.data, legendOnHover); }); - } - - // draw proper chart - if (type == 'bar') { - _drawBarChart(svg, legend, width, height, rawData, domainX, scaleColor); - } else if (type == 'pie') { - _drawPieChart(svg, legend, width, height, rawData, scaleColor); - } - }); + break; + case 'object': + _drawChart(type, chartID, dataSource, legendOnHover); + break; + } +} +/** + * Prepares SVG area for drawing and runs concrete chart function. + */ +function _drawChart(type, chartID, rawData, legendOnHover) { + // clear previous chart + var chartDiv = $('#' + chartID).empty().show(), + width = chartDiv.width(), + height = chartDiv.height(), + // add SVG elem + svg = d3.select(chartDiv[0]) + .append('svg') + .attr('width', width) + .attr('height', height); + // build domain out of keys + domainX = rawData.map(function(d) { return d.name }), + // 10 color palette + scaleColor = d3.scaleOrdinal(d3.schemeCategory10) + .domain(domainX), + legend = null; + + if (!legendOnHover) { + legend = svg.append('g'); + // build legend first so we know how much space we've got for the chart + $.each(rawData, function(index, d){ + // a small rectangle with proper color + legend.append('rect') + .attr('x', 0) + .attr('y', index * 30) + .attr('width', 15) + .attr('height', 15) + .attr('fill', scaleColor(d.name)); + // label + legend.append('text') + .attr('x', 20) + .attr('y', index * 30 + 11) + .attr('text-anchor', 'start') + .text(d.name + ' (' + Math.round(+d.value) + '%)'); + }); + } + // draw proper chart + if (type == 'bar') { + _drawBarChart(chartDiv, legend, width, height, rawData, domainX, scaleColor); + } else if (type == 'pie') { + _drawPieChart(chartDiv, legend, width, height, rawData, scaleColor); + } } // margins are needed so bar chart Y axis is not clipped @@ -69,10 +80,11 @@ /** * Draws a bar chart. */ -function _drawBarChart(svg, legend, width, height, rawData, domainX, scaleColor) { +function _drawBarChart(chartDiv, legend, width, height, rawData, domainX, scaleColor) { // if all bars easily fit in a half of SVG width, limit the drawing width // otherwise the chart would be too wide - var tooltip = legend ? null : d3.select($(svg.node()).parent()[0]) + var svg = d3.select(chartDiv[0]).select('svg'), + tooltip = legend ? null : d3.select(chartDiv[0]) .append('div') .attr('class', 'chartTooltip'), legendWidth = legend ? legend.node().getBBox().width : 0, @@ -123,7 +135,7 @@ tooltip.transition() .duration(200) .style('opacity', 1); - tooltip.text(d.name + ' (' + Math.round(+d.value) + ' %)') + tooltip.text(d.name + ' (' + Math.round(+d.value) + '%)') .style('left', +offset.left + box.width/2 - $(tooltip.node()).width()/2 - 22 + 'px') .style('top', +offset.top - 20 + 'px'); } @@ -145,9 +157,10 @@ /** * Draws a pie chart. */ -function _drawPieChart(svg, legend, width, height, rawData, scaleColor){ +function _drawPieChart(chartDiv, legend, width, height, rawData, scaleColor){ // calculate how much space we've got for the chart - var tooltip = legend ? null : d3.select($(svg.node()).parent()[0]) + var svg = d3.select(chartDiv[0]).select('svg'), + tooltip = legend ? null : d3.select(chartDiv[0]) .append('div') .attr('class', 'chartTooltip'), legendWidth = legend ? legend.node().getBBox().width : 0, @@ -182,7 +195,7 @@ tooltip.transition() .duration(200) .style('opacity', 1); - tooltip.text(d.data.name + ' (' + Math.round(+d.data.value) + ' %)') + tooltip.text(d.data.name + ' (' + Math.round(+d.data.value) + '%)') .style('left', +offset.left + box.width/2 + 'px') .style('top', +offset.top + box.height/2 + 'px'); } @@ -199,6 +212,21 @@ // move the legend to the right of the chart legend.attr('transform', 'translate(' + (radius * 2 + CHART_MARGIN.right) + ',' + (CHART_MARGIN.top + 20) + ')'); } + + // function to animate changed data + canvas.selectAll("path").each(function(d){ + this.currentData = d; + }); + chartDiv.data('updateFunctions', { + 'pie' : pie, + 'arcTween' : function(a) { + var interpolation = d3.interpolate(this.currentData, a); + this.currentData = interpolation(0); + return function(t) { + return arc(interpolation(t)); + }; + } + }); } function drawHistogram(chartID, url, xAxisLabel, yAxisLabel){ @@ -427,5 +455,4 @@ return focusbar; } -} - +} \ No newline at end of file