Index: lams_central/web/includes/javascript/chart.js =================================================================== RCS file: /usr/local/cvsroot/lams_central/web/includes/javascript/chart.js,v diff -u -r1.1.2.3 -r1.1.2.4 --- lams_central/web/includes/javascript/chart.js 26 Oct 2015 10:35:48 -0000 1.1.2.3 +++ lams_central/web/includes/javascript/chart.js 18 Nov 2016 17:11:12 -0000 1.1.2.4 @@ -1,7 +1,7 @@ /** * Prepares SVG area for drawing and runs concrete chart function. */ -function drawChart(type, chartID, url){ +function drawChart(type, chartID, url, legendOnHover){ // get data with the given URL d3.json(url, function(error, response){ if (error) { @@ -29,24 +29,27 @@ // 10 color palette scaleColor = d3.scale.category10() .domain(domainX), - legend = svg.append('g'); + legend = null; - // 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) + ' %)'); - }); + 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') { @@ -69,10 +72,13 @@ function _drawBarChart(svg, 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 legendWidth = legend.node().getBBox().width, + var tooltip = legend ? null : d3.select($(svg.node()).parent()[0]) + .append('div') + .attr('class', 'tooltip'), + legendWidth = legend ? legend.node().getBBox().width : 0, // guess how wide the chart can be and compare it to half of available width canvasWidth = (rawData.length * MIN_BAR_WIDTH * 1.1 + CHART_MARGIN.left > width / 2 ? - width - legendWidth - CHART_MARGIN.right + width - legendWidth - (legend ? CHART_MARGIN.right : 0) : width / 2) - CHART_MARGIN.left, canvas = svg.append('g') @@ -108,19 +114,44 @@ .attr("width", scaleX.rangeBand()) .attr("y", function(d) {return y(d.value)}) .attr("height", function(d){return height - y(d.value)}) - .attr('fill', function(d) {return scaleColor(d.name)}); + .attr('fill', function(d) {return scaleColor(d.name)}) + .on('mouseover', function(d) { + if (tooltip) { + var node = d3.select(this).node(), + offset = $(node).offset(), + box = node.getBBox(); + tooltip.transition() + .duration(200) + .style('opacity', 1); + 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'); + } + }) + .on('mouseout', function(d) { + if (tooltip) { + tooltip.transition() + .duration(500) + .style('opacity', 0); + } + }); - // move the legend to the right of the chart - legend.attr('transform', 'translate(' + (canvasWidth + CHART_MARGIN.right) + ',' + (CHART_MARGIN.top + 20) + ')'); + if (legend) { + // move the legend to the right of the chart + legend.attr('transform', 'translate(' + (canvasWidth + CHART_MARGIN.right) + ',' + (CHART_MARGIN.top + 20) + ')'); + } } /** * Draws a pie chart. */ function _drawPieChart(svg, legend, width, height, rawData, scaleColor){ // calculate how much space we've got for the chart - var legendWidth = legend.node().getBBox().width, - canvasWidth = width - legendWidth - CHART_MARGIN.right, + var tooltip = legend ? null : d3.select($(svg.node()).parent()[0]) + .append('div') + .attr('class', 'tooltip'), + legendWidth = legend ? legend.node().getBBox().width : 0, + canvasWidth = width - legendWidth - (legend ? CHART_MARGIN.right : 0), radius = Math.min(canvasWidth, height) / 2, canvas = svg.append('g') // set centre of the pie @@ -142,8 +173,30 @@ // draw pie chunks .append("path") .attr("d", arc) - .style("fill", function(d) { return scaleColor(d.data.name) }); - - // move the legend to the right of the chart - legend.attr('transform', 'translate(' + (radius * 2 + CHART_MARGIN.right) + ',' + (CHART_MARGIN.top + 20) + ')'); + .style("fill", function(d) { return scaleColor(d.data.name) }) + .on('mouseover', function(d) { + if (tooltip) { + var node = d3.select(this).node(), + offset = $(node).offset(), + box = node.getBBox(); + tooltip.transition() + .duration(200) + .style('opacity', 1); + 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'); + } + }) + .on('mouseout', function(d) { + if (tooltip) { + tooltip.transition() + .duration(500) + .style('opacity', 0); + } + }); + + if (legend) { + // move the legend to the right of the chart + legend.attr('transform', 'translate(' + (radius * 2 + CHART_MARGIN.right) + ',' + (CHART_MARGIN.top + 20) + ')'); + } } \ No newline at end of file