Hi matt,
Cheers for you response!
Ofcourse i can URL my chart, sorry about that.
The change of most importance is this function procentTable()
// Run the code when the DOM is ready
$( pieChart );
function pieChart() {
// Config settings
var chartSizePercent = 55; // De grootte van de circle (in procent)
var sliceBorderWidth = 1; // De grootte (in pixels) van de randen van de stukken
var sliceBorderStyle = "#fff"; // Kleur van de rand rondom de stukken
var sliceGradientColour = "#1F1C1C"; // Kleur om 1 kant van de gradient aan te geven (hier kun je de diagram lichter of donkerder maken
var maxPullOutDistance = 20; // Hier kan je de uitschuif verte mee bepalen
var pullOutFrameStep = 2; // Hier geef je de uitschuif snelheid aan
var pullOutFrameInterval = 55; // Geef hier aan hoe snel het uischuiven moeten gaan
var pullOutLabelPadding = 65; // De verte dat de tekst staat na het uitschuiven
var pullOutLabelFont = "bold 18px 'Trebuchet MS', Verdana, sans-serif"; // Tekst gegevens (titel)
var pullOutValueFont = "bold 12px 'Trebuchet MS', Verdana, sans-serif"; // Tekst gegevens
var pullOutValuePrefix = "Aantal: "; // Tekst die voor de tekst moet komen te staan bij het uitschuiven
var pullOutShadowColour = "rgba( 0, 0, 0, .5 )"; // Colour to use for the pull-out slice shadow
var pullOutShadowOffsetX = 10; // X-offset (in pixels) Hoever de schaduw moet gaan
var pullOutShadowOffsetY = 10; // Y-offset (in pixels) Hoever de schaduw moet gaan
var pullOutShadowBlur = 25; // De Donkerheid van de schaduw
var pullOutBorderWidth = 2; // De dikte van de rand als het stuk uitgeschoven is
var pullOutBorderStyle = "#333"; // De kleur van de rand als het uitgeschoven is
var chartStartAngle = -.5 * Math.PI; // Start de chart op 12u
// Declare some variables for the chart
var canvas; // The canvas element in the page
var currentPullOutSlice = -1; // Welke slice er al standaard uitgeschoven moet zijn (-1 is geen slice)
var currentPullOutDistance = 0; // How many pixels the pulled-out slice is currently pulled out in the animation
var animationId = 0; // Tracks the interval ID for the animation created by setInterval()
var chartData = []; // Chart data (labels, values, and angles)
var chartColours = []; // Kleuren van de slices (die matche met die van de tabel
var totalValue = 0; // Total of all the values in the chart
var canvasWidth; // Width of the canvas, in pixels
var canvasHeight; // Height of the canvas, in pixels
var centreX; // X-coordinate of centre of the canvas/chart
var centreY; // Y-coordinate of centre of the canvas/chart
var chartRadius; // Radius of the pie chart, in pixels
// Set things up and draw the chart
init();
/**
* Set up the chart data and colours, as well as the chart and table click handlers,
* and draw the initial pie chart
*/
function init() {
// Get the canvas element in the page
canvas = document.getElementById('chart');
// Exit if the browser isn't canvas-capable
if ( typeof canvas.getContext === 'undefined' ) return;
// Initialise some properties of the canvas and chart
canvasWidth = canvas.width;
canvasHeight = canvas.height;
centreX = canvasWidth / 2;
centreY = canvasHeight / 2;
chartRadius = Math.min( canvasWidth, canvasHeight ) / 2 * ( chartSizePercent / 100 );
// Grab the data from the table,
// and assign click handlers to the table data cells
var currentRow = -1;
var currentCell = 0;
$('#chartData td').each( function() {
currentCell++;
if ( currentCell % 2 != 0 ) {
currentRow++;
chartData[currentRow] = [];
chartData[currentRow]['label'] = $(this).text();
} else {
var value = parseFloat($(this).text());
totalValue += value;
value = value.toFixed(0);
chartData[currentRow]['value'] = value;
}
// Store the slice index in this cell, and attach a click handler to it
$(this).data( 'slice', currentRow );
$(this).hover( handleTableClick );
// Extract and store the cell colour
if ( rgb = $(this).css('color').match( /rgb\((\d+), (\d+), (\d+)/) ) {
chartColours[currentRow] = [ rgb[1], rgb[2], rgb[3] ];
} else if ( hex = $(this).css('color').match(/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/) ) {
chartColours[currentRow] = [ parseInt(hex[1],16) ,parseInt(hex[2],16), parseInt(hex[3], 16) ];
} else {
alert( "Error: Colour could not be determined! Please specify table colours using the format '#xxxxxx'" );
return;
}
} );
procentTable ();
// Now compute and store the start and end angles of each slice in the chart data
var currentPos = 0; // The current position of the slice in the pie (from 0 to 1)
for ( var slice in chartData ) {
chartData[slice]['startAngle'] = 2 * Math.PI * currentPos;
chartData[slice]['endAngle'] = 2 * Math.PI * ( currentPos + ( chartData[slice]['value'] / totalValue ) );
currentPos += chartData[slice]['value'] / totalValue;
}
// All ready! Now draw the pie chart, and add the click handler to it
drawChart();
$('#chart').click ( handleChartClick );
}
function procentTable()
{
var currentRow = -1;
var currentCell = 0;
var currentProcent = 0;
$('#chartData td').each
(
function()
{
currentCell++;
if ( currentCell % 2 != 0 )
{
currentRow++;
currentProcent++;
}
else
{
var percentvalue = "" + ( parseFloat( chartData[currentRow]['value'] / totalValue * 100).toFixed(2)) + "%";
var percentRow = document.getElementById('chartData').rows[currentProcent];
var cell = percentRow.insertCell(2);
cell.innerHTML = percentvalue;
var select = percentRow.insertCell(3);
select.innerHTML = "<input type='checkbox' onclick='toggleSlice( "+currentProcent+")'>";
}
$(cell).data( 'slice', currentRow );
$(cell).hover( handleTableClick );
$(select).data( 'slice', currentRow );
$(select).hover( handleTableClick );
// Store the slice index in this cell, and attach a click handler to it
//$(this).data( 'slice', currentRow );
//$(this).click( handleTableClick );
}
);
}
/**
* Process mouse clicks in the chart area.
*
* If a slice was clicked, toggle it in or out.
* If the user clicked outside the pie, push any slices back in.
*
* @param Event The click event
*/
function handleChartClick ( clickEvent ) {
// Get the mouse cursor position at the time of the click, relative to the canvas
var mouseX = clickEvent.pageX - this.offsetLeft;
var mouseY = clickEvent.pageY - this.offsetTop;
// Was the click inside the pie chart?
var xFromCentre = mouseX - centreX;
var yFromCentre = mouseY - centreY;
var distanceFromCentre = Math.sqrt( Math.pow( Math.abs( xFromCentre ), 2 ) + Math.pow( Math.abs( yFromCentre ), 2 ) );
if ( distanceFromCentre <= chartRadius ) {
// Yes, the click was inside the chart.
// Find the slice that was clicked by comparing angles relative to the chart centre.
var clickAngle = Math.atan2( yFromCentre, xFromCentre ) - chartStartAngle;
if ( clickAngle < 0 ) clickAngle = 2 * Math.PI + clickAngle;
for ( var slice in chartData ) {
if ( clickAngle >= chartData[slice]['startAngle'] && clickAngle <= chartData[slice]['endAngle'] ) {
// Slice found. Pull it out or push it in, as required.
toggleSlice ( slice );
return;
}
}
}
// User must have clicked outside the pie. Push any pulled-out slice back in.
pushIn();
}
/**
* Process mouse clicks in the table area.
*
* Retrieve the slice number from the jQuery data stored in the
* clicked table cell, then toggle the slice
*
* @param Event The click event
*/
function handleTableClick ( clickEvent ) {
var slice = $(this).data('slice');
toggleSlice ( slice );
}
/**
* Push a slice in or out.
*
* If it's already pulled out, push it in. Otherwise, pull it out.
*
* @param Number The slice index (between 0 and the number of slices - 1)
*/
function toggleSlice ( slice ) {
if ( slice == currentPullOutSlice ) {
pushIn();
} else {
startPullOut ( slice );
}
}
/**
* Start pulling a slice out from the pie.
*
* @param Number The slice index (between 0 and the number of slices - 1)
*/
function startPullOut ( slice ) {
// Exit if we're already pulling out this slice
if ( currentPullOutSlice == slice ) return;
// Record the slice that we're pulling out, clear any previous animation, then start the animation
currentPullOutSlice = slice;
currentPullOutDistance = 0;
clearInterval( animationId );
animationId = setInterval( function() { animatePullOut( slice ); }, pullOutFrameInterval );
// Highlight the corresponding row in the key table
$('#chartData td').removeClass('highlight');
var labelCell = $('#chartData td:eq(' + (slice*4) + ')');
var valueCell = $('#chartData td:eq(' + (slice*4+1) + ')');
var percentCell = $('#chartData td:eq(' + (slice*4+2) + ')');
var selectCell = $('#chartData td:eq(' + (slice*4+3) + ')');
labelCell.addClass('highlight');
valueCell.addClass('highlight');
percentCell.addClass('highlight');
selectCell.addClass('highlight');
}
/**
* Draw a frame of the pull-out animation.
*
* @param Number The index of the slice being pulled out
*/
function animatePullOut ( slice ) {
// Pull the slice out some more
currentPullOutDistance += pullOutFrameStep;
// If we've pulled it right out, stop animating
if ( currentPullOutDistance >= maxPullOutDistance ) {
clearInterval( animationId );
return;
}
// Draw the frame
drawChart();
}
/**
* Push any pulled-out slice back in.
*
* Resets the animation variables and redraws the chart.
* Also un-highlights all rows in the table.
*/
function pushIn() {
currentPullOutSlice = -1;
currentPullOutDistance = 0;
clearInterval( animationId );
drawChart();
$('#chartData td').removeClass('highlight');
}
/**
* Draw the chart.
*
* Loop through each slice of the pie, and draw it.
*/
function drawChart() {
// Get a drawing context
var context = canvas.getContext('2d');
// Clear the canvas, ready for the new frame
context.clearRect ( 0, 0, canvasWidth, canvasHeight );
// Draw each slice of the chart, skipping the pull-out slice (if any)
for ( var slice in chartData ) {
if ( slice != currentPullOutSlice ) drawSlice( context, slice );
}
// If there's a pull-out slice in effect, draw it.
// (We draw the pull-out slice last so its drop shadow doesn't get painted over.)
if ( currentPullOutSlice != -1 ) drawSlice( context, currentPullOutSlice );
}
/**
* Draw an individual slice in the chart.
*
* @param Context A canvas context to draw on
* @param Number The index of the slice to draw
*/
function drawSlice ( context, slice ) {
// Compute the adjusted start and end angles for the slice
var startAngle = chartData[slice]['startAngle'] + chartStartAngle;
var endAngle = chartData[slice]['endAngle'] + chartStartAngle;
if ( slice == currentPullOutSlice ) {
// We're pulling (or have pulled) this slice out.
// Offset it from the pie centre, draw the text label,
// and add a drop shadow.
var midAngle = (startAngle + endAngle) / 2;
var actualPullOutDistance = currentPullOutDistance * easeOut( currentPullOutDistance/maxPullOutDistance, .8 );
startX = centreX + Math.cos(midAngle) * actualPullOutDistance;
startY = centreY + Math.sin(midAngle) * actualPullOutDistance;
context.fillStyle = 'rgb(' + chartColours[slice].join(',') + ')';
context.textAlign = "center";
context.font = pullOutLabelFont;
context.fillText( chartData[slice]['label'], centreX + Math.cos(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ), centreY + Math.sin(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ) );
context.font = pullOutValueFont;
context.fillText( pullOutValuePrefix + chartData[slice]['value'] + " (" + ( parseFloat( chartData[slice]['value'] / totalValue * 100).toFixed(2) ) + "%)", centreX + Math.cos(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ), centreY + Math.sin(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ) + 20 );
context.shadowOffsetX = pullOutShadowOffsetX;
context.shadowOffsetY = pullOutShadowOffsetY;
context.shadowBlur = pullOutShadowBlur;
} else {
// This slice isn't pulled out, so draw it from the pie centre
startX = centreX;
startY = centreY;
}
// Set up the gradient fill for the slice
var sliceGradient = context.createLinearGradient( 0, 0, canvasWidth*.75, canvasHeight*.75 );
sliceGradient.addColorStop( 0, sliceGradientColour );
sliceGradient.addColorStop( 1, 'rgb(' + chartColours[slice].join(',') + ')' );
// Draw the slice
context.beginPath();
context.moveTo( startX, startY );
context.arc( startX, startY, chartRadius, startAngle, endAngle, false );
context.lineTo( startX, startY );
context.closePath();
context.fillStyle = sliceGradient;
context.shadowColor = ( slice == currentPullOutSlice ) ? pullOutShadowColour : "rgba( 0, 0, 0, 0 )";
context.fill();
context.shadowColor = "rgba( 0, 0, 0, 0 )";
// Style the slice border appropriately
if ( slice == currentPullOutSlice ) {
context.lineWidth = pullOutBorderWidth;
context.strokeStyle = pullOutBorderStyle;
} else {
context.lineWidth = sliceBorderWidth;
context.strokeStyle = sliceBorderStyle;
}
// Draw the slice border
context.stroke();
}
/**
* Easing function.
*
* A bit hacky but it seems to work! (Note to self: Re-read my school maths books sometime)
*
* @param Number The ratio of the current distance travelled to the maximum distance
* @param Number The power (higher numbers = more gradual easing)
* @return Number The new ratio
*/
function easeOut( ratio, power ) {
return ( Math.pow ( 1 - ratio, power ) + 1 );
}
};
As you can see i create an checkbox behind every row of the table. My actual question is if there is any possbility that you can pop out the slices of every box that is checked.
I hope you can help me with this one,
Greetz,
Dumdi
[Edited by Dum_Di_Dum on 28-Feb-12 01:34]