[FIX] Graphs not rendering properly
Update jquery.visualize.js to fix graphs not working for Pool, Both.
This commit is contained in:
parent
ef6f7ce1b0
commit
bee2d3a1cc
@ -1,11 +1,9 @@
|
|||||||
/**
|
/*
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
* jQuery-Plugin "visualize"
|
* jQuery inputToButton plugin
|
||||||
* by Scott Jehl, scott@filamentgroup.com
|
* Author: Scott Jehl, scott@filamentgroup.com
|
||||||
* http://www.filamentgroup.com
|
|
||||||
* Copyright (c) 2009 Filament Group
|
* Copyright (c) 2009 Filament Group
|
||||||
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
|
* licensed under MIT (filamentgroup.com/examples/mit-license.txt)
|
||||||
*
|
|
||||||
* --------------------------------------------------------------------
|
* --------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
(function($) {
|
(function($) {
|
||||||
@ -19,239 +17,182 @@ $.fn.visualize = function(options, container){
|
|||||||
appendTitle: true, //table caption text is added to chart
|
appendTitle: true, //table caption text is added to chart
|
||||||
title: null, //grabs from table caption if null
|
title: null, //grabs from table caption if null
|
||||||
appendKey: true, //color key is added to chart
|
appendKey: true, //color key is added to chart
|
||||||
|
rowFilter: '*',
|
||||||
|
colFilter: '*',
|
||||||
colors: ['#be1e2d','#666699','#92d5ea','#ee8310','#8d10ee','#5a3b16','#26a4ed','#f45a90','#e9e744'],
|
colors: ['#be1e2d','#666699','#92d5ea','#ee8310','#8d10ee','#5a3b16','#26a4ed','#f45a90','#e9e744'],
|
||||||
textColors: [], //corresponds with colors array. null/undefined items will fall back to CSS
|
textColors: [], //corresponds with colors array. null/undefined items will fall back to CSS
|
||||||
parseDirection: 'x', //which direction to parse the table data
|
parseDirection: 'x', //which direction to parse the table data
|
||||||
pieMargin: 10, //pie charts only - spacing around pie
|
pieMargin: 20, //pie charts only - spacing around pie
|
||||||
pieLabelsAsPercent: true,
|
pieLabelsAsPercent: true,
|
||||||
pieLabelPos: 'inside',
|
pieLabelPos: 'inside',
|
||||||
lineWeight: 4, //for line and area - stroke weight
|
lineWeight: 4, //for line and area - stroke weight
|
||||||
lineDots: false, //also available: 'single', 'double'
|
|
||||||
dotInnerColor: "#ffffff", // only used for lineDots:'double'
|
|
||||||
lineMargin: (options.lineDots?15:0), //for line and area - spacing around lines
|
|
||||||
barGroupMargin: 10,
|
barGroupMargin: 10,
|
||||||
chartId: '',
|
|
||||||
xLabelParser: null, // function to parse labels as values
|
|
||||||
valueParser: null, // function to parse values. must return a Number
|
|
||||||
chartId: '',
|
|
||||||
chartClass: '',
|
|
||||||
barMargin: 1, //space around bars in bar chart (added to both sides of bar)
|
barMargin: 1, //space around bars in bar chart (added to both sides of bar)
|
||||||
yLabelInterval: 30, //distance between y labels
|
yLabelInterval: 30 //distance between y labels
|
||||||
interaction: false // only used for lineDots != false -- triggers mouseover and mouseout on original table
|
|
||||||
},options);
|
},options);
|
||||||
|
|
||||||
//reset width, height to numbers
|
//reset width, height to numbers
|
||||||
o.width = parseFloat(o.width);
|
o.width = parseFloat(o.width);
|
||||||
o.height = parseFloat(o.height);
|
o.height = parseFloat(o.height);
|
||||||
|
|
||||||
// reset padding if graph is not lines
|
|
||||||
if(o.type != 'line' && o.type != 'area' ) {
|
|
||||||
o.lineMargin = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
var self = $(this);
|
var self = $(this);
|
||||||
|
|
||||||
// scrape data from html table
|
//function to scrape data from html table
|
||||||
var tableData = {};
|
function scrapeTable(){
|
||||||
var colors = o.colors;
|
var colors = o.colors;
|
||||||
var textColors = o.textColors;
|
var textColors = o.textColors;
|
||||||
|
var tableData = {
|
||||||
|
dataGroups: function(){
|
||||||
var parseLabels = function(direction){
|
var dataGroups = [];
|
||||||
var labels = [];
|
|
||||||
if(direction == 'x'){
|
|
||||||
self.find('thead tr').each(function(i){
|
|
||||||
$(this).find('th').each(function(j){
|
|
||||||
if(!labels[j]) {
|
|
||||||
labels[j] = [];
|
|
||||||
}
|
|
||||||
labels[j][i] = $(this).text()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
self.find('tbody tr').each(function(i){
|
|
||||||
$(this).find('th').each(function(j) {
|
|
||||||
if(!labels[i]) {
|
|
||||||
labels[i] = [];
|
|
||||||
}
|
|
||||||
labels[i][j] = $(this).text()
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return labels;
|
|
||||||
};
|
|
||||||
|
|
||||||
var fnParse = o.valueParser || parseFloat;
|
|
||||||
var dataGroups = tableData.dataGroups = [];
|
|
||||||
if(o.parseDirection == 'x'){
|
if(o.parseDirection == 'x'){
|
||||||
self.find('tbody tr').each(function(i,tr){
|
self.find('tr:gt(0)').filter(o.rowFilter).each(function(i){
|
||||||
dataGroups[i] = {};
|
dataGroups[i] = {};
|
||||||
dataGroups[i].points = [];
|
dataGroups[i].points = [];
|
||||||
dataGroups[i].color = colors[i];
|
dataGroups[i].color = colors[i];
|
||||||
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
||||||
$(tr).find('td').each(function(j,td){
|
$(this).find('td').filter(o.colFilter).each(function(){
|
||||||
dataGroups[i].points.push( {
|
dataGroups[i].points.push( parseFloat($(this).text()) );
|
||||||
value: fnParse($(td).text()),
|
|
||||||
elem: td,
|
|
||||||
tableCords: [i,j]
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
} else {
|
else {
|
||||||
var cols = self.find('tbody tr:eq(0) td').size();
|
var cols = self.find('tr:eq(1) td').filter(o.colFilter).size();
|
||||||
for(var i=0; i<cols; i++){
|
for(var i=0; i<cols; i++){
|
||||||
dataGroups[i] = {};
|
dataGroups[i] = {};
|
||||||
dataGroups[i].points = [];
|
dataGroups[i].points = [];
|
||||||
dataGroups[i].color = colors[i];
|
dataGroups[i].color = colors[i];
|
||||||
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
if(textColors[i]){ dataGroups[i].textColor = textColors[i]; }
|
||||||
self.find('tbody tr').each(function(j){
|
self.find('tr:gt(0)').filter(o.rowFilter).each(function(){
|
||||||
dataGroups[i].points.push( {
|
dataGroups[i].points.push( $(this).find('td').filter(o.colFilter).eq(i).text()*1 );
|
||||||
value: $(this).find('td').eq(i).text()*1,
|
|
||||||
elem: this,
|
|
||||||
tableCords: [i,j]
|
|
||||||
} );
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
return dataGroups;
|
||||||
|
|
||||||
var allItems = tableData.allItems = [];
|
|
||||||
$(dataGroups).each(function(i,row){
|
|
||||||
var count = 0;
|
|
||||||
$.each(row.points,function(j,point){
|
|
||||||
allItems.push(point);
|
|
||||||
count += point.value;
|
|
||||||
});
|
|
||||||
row.groupTotal = count;
|
|
||||||
});
|
|
||||||
|
|
||||||
tableData.dataSum = 0;
|
|
||||||
tableData.topValue = 0;
|
|
||||||
tableData.bottomValue = Infinity;
|
|
||||||
$.each(allItems,function(i,item){
|
|
||||||
tableData.dataSum += fnParse(item.value);
|
|
||||||
if(fnParse(item.value,10)>tableData.topValue) {
|
|
||||||
tableData.topValue = fnParse(item.value,10);
|
|
||||||
}
|
|
||||||
if(item.value<tableData.bottomValue) {
|
|
||||||
tableData.bottomValue = fnParse(item.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
var dataSum = tableData.dataSum;
|
|
||||||
var topValue = tableData.topValue;
|
|
||||||
var bottomValue = tableData.bottomValue;
|
|
||||||
|
|
||||||
var xAllLabels = tableData.xAllLabels = parseLabels(o.parseDirection);
|
|
||||||
var yAllLabels = tableData.yAllLabels = parseLabels(o.parseDirection==='x'?'y':'x');
|
|
||||||
|
|
||||||
var xLabels = tableData.xLabels = [];
|
|
||||||
$.each(tableData.xAllLabels,function(i,labels) {
|
|
||||||
tableData.xLabels.push(labels[0]);
|
|
||||||
});
|
|
||||||
|
|
||||||
var totalYRange = tableData.totalYRange = tableData.topValue - tableData.bottomValue;
|
|
||||||
|
|
||||||
var zeroLocX = tableData.zeroLocX = 0;
|
|
||||||
|
|
||||||
if($.isFunction(o.xLabelParser)) {
|
|
||||||
|
|
||||||
var xTopValue = null;
|
|
||||||
var xBottomValue = null;
|
|
||||||
|
|
||||||
$.each(xLabels,function(i,label) {
|
|
||||||
label = xLabels[i] = o.xLabelParser(label);
|
|
||||||
if(i === 0) {
|
|
||||||
xTopValue = label;
|
|
||||||
xBottomValue = label;
|
|
||||||
}
|
|
||||||
if(label>xTopValue) {
|
|
||||||
xTopValue = label;
|
|
||||||
}
|
|
||||||
if(label<xBottomValue) {
|
|
||||||
xBottomValue = label;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var totalXRange = tableData.totalXRange = xTopValue - xBottomValue;
|
|
||||||
|
|
||||||
|
|
||||||
var xScale = tableData.xScale = (o.width -2*o.lineMargin) / totalXRange;
|
|
||||||
var marginDiffX = 0;
|
|
||||||
if(o.lineMargin) {
|
|
||||||
var marginDiffX = -2*xScale-o.lineMargin;
|
|
||||||
}
|
|
||||||
zeroLocX = tableData.zeroLocX = xBottomValue + o.lineMargin;
|
|
||||||
|
|
||||||
tableData.xBottomValue = xBottomValue;
|
|
||||||
tableData.xTopValue = xTopValue;
|
|
||||||
tableData.totalXRange = totalXRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
var yScale = tableData.yScale = (o.height - 2*o.lineMargin) / totalYRange;
|
|
||||||
var zeroLocY = tableData.zeroLocY = (o.height-2*o.lineMargin) * (tableData.topValue/tableData.totalYRange) + o.lineMargin;
|
|
||||||
|
|
||||||
var yLabels = tableData.yLabels = [];
|
|
||||||
|
|
||||||
var numLabels = Math.floor((o.height - 2*o.lineMargin) / 30);
|
|
||||||
var loopInterval = tableData.totalYRange / numLabels; //fix provided from lab
|
|
||||||
loopInterval = Math.round(parseFloat(loopInterval)/5)*5;
|
|
||||||
loopInterval = Math.max(loopInterval, 1);
|
|
||||||
// var start =
|
|
||||||
for(var j=Math.round(parseInt(tableData.bottomValue)/5)*5; j<=tableData.topValue+loopInterval; j+=loopInterval){
|
|
||||||
yLabels.push(j);
|
|
||||||
}
|
|
||||||
if(yLabels[yLabels.length-1] > tableData.topValue+loopInterval) {
|
|
||||||
yLabels.pop();
|
|
||||||
} else if (yLabels[yLabels.length-1] <= tableData.topValue-10) {
|
|
||||||
yLabels.push(tableData.topValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// populate some data
|
|
||||||
$.each(dataGroups,function(i,row){
|
|
||||||
row.yLabels = tableData.yAllLabels[i];
|
|
||||||
$.each(row.points, function(j,point){
|
|
||||||
point.zeroLocY = tableData.zeroLocY;
|
|
||||||
point.zeroLocX = tableData.zeroLocX;
|
|
||||||
point.xLabels = tableData.xAllLabels[j];
|
|
||||||
point.yLabels = tableData.yAllLabels[i];
|
|
||||||
point.color = row.color;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
try{console.log(tableData);}catch(e){}
|
|
||||||
|
|
||||||
var charts = {};
|
|
||||||
|
|
||||||
charts.pie = {
|
|
||||||
interactionPoints: dataGroups,
|
|
||||||
|
|
||||||
setup: function() {
|
|
||||||
charts.pie.draw(true);
|
|
||||||
},
|
},
|
||||||
draw: function(drawHtml){
|
allData: function(){
|
||||||
|
var allData = [];
|
||||||
|
$(this.dataGroups()).each(function(){
|
||||||
|
allData.push(this.points);
|
||||||
|
});
|
||||||
|
return allData;
|
||||||
|
},
|
||||||
|
dataSum: function(){
|
||||||
|
var dataSum = 0;
|
||||||
|
var allData = this.allData().join(',').split(',');
|
||||||
|
$(allData).each(function(){
|
||||||
|
dataSum += parseFloat(this);
|
||||||
|
});
|
||||||
|
return dataSum
|
||||||
|
},
|
||||||
|
topValue: function(){
|
||||||
|
var topValue = 0;
|
||||||
|
var allData = this.allData().join(',').split(',');
|
||||||
|
$(allData).each(function(){
|
||||||
|
if(parseFloat(this,10)>topValue) topValue = parseFloat(this);
|
||||||
|
});
|
||||||
|
return topValue;
|
||||||
|
},
|
||||||
|
bottomValue: function(){
|
||||||
|
var bottomValue = 0;
|
||||||
|
var allData = this.allData().join(',').split(',');
|
||||||
|
$(allData).each(function(){
|
||||||
|
if(this<bottomValue) bottomValue = parseFloat(this);
|
||||||
|
});
|
||||||
|
return bottomValue;
|
||||||
|
},
|
||||||
|
memberTotals: function(){
|
||||||
|
var memberTotals = [];
|
||||||
|
var dataGroups = this.dataGroups();
|
||||||
|
$(dataGroups).each(function(l){
|
||||||
|
var count = 0;
|
||||||
|
$(dataGroups[l].points).each(function(m){
|
||||||
|
count +=dataGroups[l].points[m];
|
||||||
|
});
|
||||||
|
memberTotals.push(count);
|
||||||
|
});
|
||||||
|
return memberTotals;
|
||||||
|
},
|
||||||
|
yTotals: function(){
|
||||||
|
var yTotals = [];
|
||||||
|
var dataGroups = this.dataGroups();
|
||||||
|
var loopLength = this.xLabels().length;
|
||||||
|
for(var i = 0; i<loopLength; i++){
|
||||||
|
yTotals[i] =[];
|
||||||
|
var thisTotal = 0;
|
||||||
|
$(dataGroups).each(function(l){
|
||||||
|
yTotals[i].push(this.points[i]);
|
||||||
|
});
|
||||||
|
yTotals[i].join(',').split(',');
|
||||||
|
$(yTotals[i]).each(function(){
|
||||||
|
thisTotal += parseFloat(this);
|
||||||
|
});
|
||||||
|
yTotals[i] = thisTotal;
|
||||||
|
|
||||||
|
}
|
||||||
|
return yTotals;
|
||||||
|
},
|
||||||
|
topYtotal: function(){
|
||||||
|
var topYtotal = 0;
|
||||||
|
var yTotals = this.yTotals().join(',').split(',');
|
||||||
|
$(yTotals).each(function(){
|
||||||
|
if(parseFloat(this,10)>topYtotal) topYtotal = parseFloat(this);
|
||||||
|
});
|
||||||
|
return topYtotal;
|
||||||
|
},
|
||||||
|
totalYRange: function(){
|
||||||
|
return this.topValue() - this.bottomValue();
|
||||||
|
},
|
||||||
|
xLabels: function(){
|
||||||
|
var xLabels = [];
|
||||||
|
if(o.parseDirection == 'x'){
|
||||||
|
self.find('tr:eq(0) th').filter(o.colFilter).each(function(){
|
||||||
|
xLabels.push($(this).html());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.find('tr:gt(0) th').filter(o.rowFilter).each(function(){
|
||||||
|
xLabels.push($(this).html());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return xLabels;
|
||||||
|
},
|
||||||
|
yLabels: function(){
|
||||||
|
var yLabels = [];
|
||||||
|
yLabels.push(bottomValue);
|
||||||
|
var numLabels = Math.round(o.height / o.yLabelInterval);
|
||||||
|
var loopInterval = Math.ceil(totalYRange / numLabels) || 1;
|
||||||
|
while( yLabels[yLabels.length-1] < topValue - loopInterval){
|
||||||
|
yLabels.push(yLabels[yLabels.length-1] + loopInterval);
|
||||||
|
}
|
||||||
|
yLabels.push(topValue);
|
||||||
|
return yLabels;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return tableData;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//function to create a chart
|
||||||
|
var createChart = {
|
||||||
|
pie: function(){
|
||||||
|
|
||||||
|
canvasContain.addClass('visualize-pie');
|
||||||
|
|
||||||
|
if(o.pieLabelPos == 'outside'){ canvasContain.addClass('visualize-pie-outside'); }
|
||||||
|
|
||||||
var centerx = Math.round(canvas.width()/2);
|
var centerx = Math.round(canvas.width()/2);
|
||||||
var centery = Math.round(canvas.height()/2);
|
var centery = Math.round(canvas.height()/2);
|
||||||
var radius = centery - o.pieMargin;
|
var radius = centery - o.pieMargin;
|
||||||
var counter = 0.0;
|
var counter = 0.0;
|
||||||
|
|
||||||
if(drawHtml) {
|
|
||||||
canvasContain.addClass('visualize-pie');
|
|
||||||
|
|
||||||
if(o.pieLabelPos == 'outside'){ canvasContain.addClass('visualize-pie-outside'); }
|
|
||||||
|
|
||||||
var toRad = function(integer){ return (Math.PI/180)*integer; };
|
var toRad = function(integer){ return (Math.PI/180)*integer; };
|
||||||
var labels = $('<ul class="visualize-labels"></ul>')
|
var labels = $('<ul class="visualize-labels"></ul>')
|
||||||
.insertAfter(canvas);
|
.insertAfter(canvas);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//draw the pie pieces
|
//draw the pie pieces
|
||||||
$.each(dataGroups, function(i,row){
|
$.each(memberTotals, function(i){
|
||||||
var fraction = row.groupTotal / dataSum;
|
var fraction = (this <= 0 || isNaN(this))? 0 : this / dataSum;
|
||||||
if (fraction <= 0 || isNaN(fraction))
|
|
||||||
return;
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(centerx, centery);
|
ctx.moveTo(centerx, centery);
|
||||||
ctx.arc(centerx, centery, radius,
|
ctx.arc(centerx, centery, radius,
|
||||||
@ -263,7 +204,6 @@ $.fn.visualize = function(options, container){
|
|||||||
ctx.fillStyle = dataGroups[i].color;
|
ctx.fillStyle = dataGroups[i].color;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
// draw labels
|
// draw labels
|
||||||
if(drawHtml) {
|
|
||||||
var sliceMiddle = (counter + fraction/2);
|
var sliceMiddle = (counter + fraction/2);
|
||||||
var distance = o.pieLabelPos == 'inside' ? radius/1.5 : radius + radius / 5;
|
var distance = o.pieLabelPos == 'inside' ? radius/1.5 : radius + radius / 5;
|
||||||
var labelx = Math.round(centerx + Math.sin(sliceMiddle * Math.PI * 2) * (distance));
|
var labelx = Math.round(centerx + Math.sin(sliceMiddle * Math.PI * 2) * (distance));
|
||||||
@ -272,15 +212,8 @@ $.fn.visualize = function(options, container){
|
|||||||
var topBottom = (labely > centery) ? 'bottom' : 'top';
|
var topBottom = (labely > centery) ? 'bottom' : 'top';
|
||||||
var percentage = parseFloat((fraction*100).toFixed(2));
|
var percentage = parseFloat((fraction*100).toFixed(2));
|
||||||
|
|
||||||
// interaction variables
|
|
||||||
row.canvasCords = [labelx,labely];
|
|
||||||
row.zeroLocY = tableData.zeroLocY = 0; // related to zeroLocY and plugin API
|
|
||||||
row.zeroLocX = tableData.zeroLocX = 0; // related to zeroLocX and plugin API
|
|
||||||
row.value = row.groupTotal;
|
|
||||||
|
|
||||||
|
|
||||||
if(percentage){
|
if(percentage){
|
||||||
var labelval = (o.pieLabelsAsPercent) ? percentage + '%' : row.groupTotal;
|
var labelval = (o.pieLabelsAsPercent) ? percentage + '%' : this;
|
||||||
var labeltext = $('<span class="visualize-label">' + labelval +'</span>')
|
var labeltext = $('<span class="visualize-label">' + labelval +'</span>')
|
||||||
.css(leftRight, 0)
|
.css(leftRight, 0)
|
||||||
.css(topBottom, 0);
|
.css(topBottom, 0);
|
||||||
@ -295,48 +228,26 @@ $.fn.visualize = function(options, container){
|
|||||||
.css('margin-'+topBottom, -labeltext.outerHeight()/2);
|
.css('margin-'+topBottom, -labeltext.outerHeight()/2);
|
||||||
|
|
||||||
if(dataGroups[i].textColor){ labeltext.css('color', dataGroups[i].textColor); }
|
if(dataGroups[i].textColor){ labeltext.css('color', dataGroups[i].textColor); }
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
counter+=fraction;
|
counter+=fraction;
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
};
|
|
||||||
|
|
||||||
(function(){
|
line: function(area){
|
||||||
|
|
||||||
var xInterval;
|
|
||||||
|
|
||||||
var drawPoint = function (ctx,x,y,color,size) {
|
|
||||||
ctx.moveTo(x,y);
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(x,y,size/2,0,2*Math.PI,false);
|
|
||||||
ctx.closePath();
|
|
||||||
ctx.fillStyle = color;
|
|
||||||
ctx.fill();
|
|
||||||
};
|
|
||||||
|
|
||||||
charts.line = {
|
|
||||||
|
|
||||||
interactionPoints: allItems,
|
|
||||||
|
|
||||||
setup: function(area){
|
|
||||||
|
|
||||||
if(area){ canvasContain.addClass('visualize-area'); }
|
if(area){ canvasContain.addClass('visualize-area'); }
|
||||||
else{ canvasContain.addClass('visualize-line'); }
|
else{ canvasContain.addClass('visualize-line'); }
|
||||||
|
|
||||||
//write X labels
|
//write X labels
|
||||||
|
var xInterval = canvas.width() / (xLabels.length -1);
|
||||||
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
||||||
.width(canvas.width())
|
.width(canvas.width())
|
||||||
.height(canvas.height())
|
.height(canvas.height())
|
||||||
.insertBefore(canvas);
|
.insertBefore(canvas);
|
||||||
|
|
||||||
if(!o.customXLabels) {
|
|
||||||
xInterval = (canvas.width() - 2*o.lineMargin) / (xLabels.length -1);
|
|
||||||
$.each(xLabels, function(i){
|
$.each(xLabels, function(i){
|
||||||
var thisLi = $('<li><span>'+this+'</span></li>')
|
var thisLi = $('<li><span>'+this+'</span></li>')
|
||||||
.prepend('<span class="line" />')
|
.prepend('<span class="line" />')
|
||||||
.css('left', o.lineMargin + xInterval * i)
|
.css('left', xInterval * i)
|
||||||
.appendTo(xlabelsUL);
|
.appendTo(xlabelsUL);
|
||||||
var label = thisLi.find('span:not(.line)');
|
var label = thisLi.find('span:not(.line)');
|
||||||
var leftOffset = label.width()/-2;
|
var leftOffset = label.width()/-2;
|
||||||
@ -346,96 +257,48 @@ $.fn.visualize = function(options, container){
|
|||||||
.css('margin-left', leftOffset)
|
.css('margin-left', leftOffset)
|
||||||
.addClass('label');
|
.addClass('label');
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
o.customXLabels(tableData,xlabelsUL);
|
|
||||||
}
|
|
||||||
|
|
||||||
//write Y labels
|
//write Y labels
|
||||||
var liBottom = (canvas.height() - 2*o.lineMargin) / (yLabels.length-1);
|
var yScale = canvas.height() / totalYRange;
|
||||||
|
var liBottom = canvas.height() / (yLabels.length-1);
|
||||||
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
||||||
.width(canvas.width())
|
.width(canvas.width())
|
||||||
.height(canvas.height())
|
.height(canvas.height())
|
||||||
// .css('margin-top',-o.lineMargin)
|
.insertBefore(canvas);
|
||||||
.insertBefore(scroller);
|
|
||||||
|
|
||||||
$.each(yLabels, function(i){
|
$.each(yLabels, function(i){
|
||||||
var value = Math.floor(this);
|
var thisLi = $('<li><span>'+this+'</span></li>')
|
||||||
var posB = (value-bottomValue)*yScale + o.lineMargin;
|
.prepend('<span class="line" />')
|
||||||
if(posB >= o.height-1 || posB < 0) {
|
.css('bottom',liBottom*i)
|
||||||
return;
|
.prependTo(ylabelsUL);
|
||||||
}
|
|
||||||
var thisLi = $('<li><span>'+value+'</span></li>')
|
|
||||||
.css('bottom', posB);
|
|
||||||
if(Math.abs(posB) < o.height-1) {
|
|
||||||
thisLi.prepend('<span class="line" />');
|
|
||||||
}
|
|
||||||
thisLi.prependTo(ylabelsUL);
|
|
||||||
|
|
||||||
var label = thisLi.find('span:not(.line)');
|
var label = thisLi.find('span:not(.line)');
|
||||||
var topOffset = label.height()/-2;
|
var topOffset = label.height()/-2;
|
||||||
if(!o.lineMargin) {
|
|
||||||
if(i == 0){ topOffset = -label.height(); }
|
if(i == 0){ topOffset = -label.height(); }
|
||||||
else if(i== yLabels.length-1){ topOffset = 0; }
|
else if(i== yLabels.length-1){ topOffset = 0; }
|
||||||
}
|
|
||||||
label
|
label
|
||||||
.css('margin-top', topOffset)
|
.css('margin-top', topOffset)
|
||||||
.addClass('label');
|
.addClass('label');
|
||||||
});
|
});
|
||||||
|
|
||||||
//start from the bottom left
|
//start from the bottom left
|
||||||
ctx.translate(zeroLocX,zeroLocY);
|
ctx.translate(0,zeroLoc);
|
||||||
|
//iterate and draw
|
||||||
charts.line.draw(area);
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
draw: function(area) {
|
|
||||||
// prevent drawing on top of previous draw
|
|
||||||
ctx.clearRect(-zeroLocX,-zeroLocY,o.width,o.height);
|
|
||||||
// Calculate each point properties before hand
|
|
||||||
var integer;
|
|
||||||
$.each(dataGroups,function(i,row){
|
|
||||||
integer = o.lineMargin; // the current offset
|
|
||||||
$.each(row.points, function(j,point){
|
|
||||||
if(o.xLabelParser) {
|
|
||||||
point.canvasCords = [(xLabels[j]-zeroLocX)*xScale - xBottomValue,-(point.value*yScale)];
|
|
||||||
} else {
|
|
||||||
point.canvasCords = [integer,-(point.value*yScale)];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(o.lineDots) {
|
|
||||||
point.dotSize = o.dotSize||o.lineWeight*Math.PI;
|
|
||||||
point.dotInnerSize = o.dotInnerSize||o.lineWeight*Math.PI/2;
|
|
||||||
if(o.lineDots == 'double') {
|
|
||||||
point.innerColor = o.dotInnerColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
integer+=xInterval;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// fire custom event so we can enable rich interaction
|
|
||||||
self.trigger('vizualizeBeforeDraw',{options:o,table:self,canvasContain:canvasContain,tableData:tableData});
|
|
||||||
// draw lines and areas
|
|
||||||
$.each(dataGroups,function(h){
|
$.each(dataGroups,function(h){
|
||||||
// Draw lines
|
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.lineWidth = o.lineWeight;
|
ctx.lineWidth = o.lineWeight;
|
||||||
ctx.lineJoin = 'round';
|
ctx.lineJoin = 'round';
|
||||||
$.each(this.points, function(g){
|
var points = this.points;
|
||||||
var loc = this.canvasCords;
|
var integer = 0;
|
||||||
if(g == 0) {
|
ctx.moveTo(0,-(points[0]*yScale));
|
||||||
ctx.moveTo(loc[0],loc[1]);
|
$.each(points, function(){
|
||||||
}
|
ctx.lineTo(integer,-(this*yScale));
|
||||||
ctx.lineTo(loc[0],loc[1]);
|
integer+=xInterval;
|
||||||
});
|
});
|
||||||
ctx.strokeStyle = this.color;
|
ctx.strokeStyle = this.color;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
// Draw fills
|
|
||||||
if(area){
|
if(area){
|
||||||
var integer = this.points[this.points.length-1].canvasCords[0];
|
|
||||||
if (isFinite(integer))
|
|
||||||
ctx.lineTo(integer,0);
|
ctx.lineTo(integer,0);
|
||||||
ctx.lineTo(o.lineMargin,0);
|
ctx.lineTo(0,0);
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
ctx.fillStyle = this.color;
|
ctx.fillStyle = this.color;
|
||||||
ctx.globalAlpha = .3;
|
ctx.globalAlpha = .3;
|
||||||
@ -444,213 +307,106 @@ $.fn.visualize = function(options, container){
|
|||||||
}
|
}
|
||||||
else {ctx.closePath();}
|
else {ctx.closePath();}
|
||||||
});
|
});
|
||||||
// draw points
|
|
||||||
if(o.lineDots) {
|
|
||||||
$.each(dataGroups,function(h){
|
|
||||||
$.each(this.points, function(g){
|
|
||||||
drawPoint(ctx,this.canvasCords[0],this.canvasCords[1],this.color,this.dotSize);
|
|
||||||
if(o.lineDots === 'double') {
|
|
||||||
drawPoint(ctx,this.canvasCords[0],this.canvasCords[1],this.innerColor,this.dotInnerSize);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
charts.area = {
|
|
||||||
setup: function() {
|
|
||||||
charts.line.setup(true);
|
|
||||||
},
|
},
|
||||||
draw: charts.line.draw
|
|
||||||
};
|
|
||||||
|
|
||||||
(function(){
|
area: function(){
|
||||||
|
createChart.line(true);
|
||||||
|
},
|
||||||
|
|
||||||
var horizontal,bottomLabels;
|
bar: function(){
|
||||||
|
|
||||||
charts.bar = {
|
|
||||||
setup:function(){
|
|
||||||
/**
|
|
||||||
* We can draw horizontal or vertical bars depending on the
|
|
||||||
* value of the 'barDirection' option (which may be 'vertical' or
|
|
||||||
* 'horizontal').
|
|
||||||
*/
|
|
||||||
|
|
||||||
horizontal = (o.barDirection == 'horizontal');
|
|
||||||
|
|
||||||
canvasContain.addClass('visualize-bar');
|
canvasContain.addClass('visualize-bar');
|
||||||
|
|
||||||
/**
|
//write X labels
|
||||||
* Write labels along the bottom of the chart. If we're drawing
|
var xInterval = canvas.width() / (xLabels.length);
|
||||||
* horizontal bars, these will be the yLabels, otherwise they
|
|
||||||
* will be the xLabels. The positioning also varies slightly:
|
|
||||||
* yLabels are values, hence they will span the whole width of
|
|
||||||
* the canvas, whereas xLabels are supposed to line up with the
|
|
||||||
* bars.
|
|
||||||
*/
|
|
||||||
bottomLabels = horizontal ? yLabels : xLabels;
|
|
||||||
|
|
||||||
var xInterval = canvas.width() / (bottomLabels.length - (horizontal ? 1 : 0));
|
|
||||||
|
|
||||||
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
var xlabelsUL = $('<ul class="visualize-labels-x"></ul>')
|
||||||
.width(canvas.width())
|
.width(canvas.width())
|
||||||
.height(canvas.height())
|
.height(canvas.height())
|
||||||
.insertBefore(canvas);
|
.insertBefore(canvas);
|
||||||
|
$.each(xLabels, function(i){
|
||||||
$.each(bottomLabels, function(i){
|
|
||||||
var thisLi = $('<li><span class="label">'+this+'</span></li>')
|
var thisLi = $('<li><span class="label">'+this+'</span></li>')
|
||||||
.prepend('<span class="line" />')
|
.prepend('<span class="line" />')
|
||||||
.css('left', xInterval * i)
|
.css('left', xInterval * i)
|
||||||
.width(xInterval)
|
.width(xInterval)
|
||||||
.appendTo(xlabelsUL);
|
.appendTo(xlabelsUL);
|
||||||
|
|
||||||
if (horizontal) {
|
|
||||||
var label = thisLi.find('span.label');
|
var label = thisLi.find('span.label');
|
||||||
label.css("margin-left", -label.width() / 2);
|
label.addClass('label');
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
//write Y labels
|
||||||
* Write labels along the left of the chart. Follows the same idea
|
var yScale = canvas.height() / totalYRange;
|
||||||
* as the bottom labels.
|
var liBottom = canvas.height() / (yLabels.length-1);
|
||||||
*/
|
|
||||||
var leftLabels = horizontal ? xLabels : yLabels;
|
|
||||||
var liBottom = canvas.height() / (leftLabels.length - (horizontal ? 0 : 1));
|
|
||||||
|
|
||||||
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
var ylabelsUL = $('<ul class="visualize-labels-y"></ul>')
|
||||||
.width(canvas.width())
|
.width(canvas.width())
|
||||||
.height(canvas.height())
|
.height(canvas.height())
|
||||||
.insertBefore(canvas);
|
.insertBefore(canvas);
|
||||||
|
$.each(yLabels, function(i){
|
||||||
$.each(leftLabels, function(i){
|
var thisLi = $('<li><span>'+this+'</span></li>')
|
||||||
var thisLi = $('<li><span>'+this+'</span></li>').prependTo(ylabelsUL);
|
.prepend('<span class="line" />')
|
||||||
|
.css('bottom',liBottom*i)
|
||||||
var label = thisLi.find('span:not(.line)').addClass('label');
|
.prependTo(ylabelsUL);
|
||||||
|
var label = thisLi.find('span:not(.line)');
|
||||||
if (horizontal) {
|
var topOffset = label.height()/-2;
|
||||||
/**
|
if(i == 0){ topOffset = -label.height(); }
|
||||||
* For left labels, we want to vertically align the text
|
else if(i== yLabels.length-1){ topOffset = 0; }
|
||||||
* to the middle of its container, but we don't know how
|
label
|
||||||
* many lines of text we will have, since the labels could
|
.css('margin-top', topOffset)
|
||||||
* be very long.
|
.addClass('label');
|
||||||
*
|
|
||||||
* So we set a min-height of liBottom, and a max-height
|
|
||||||
* of liBottom + 1, so we can then check the label's actual
|
|
||||||
* height to determine if it spans one line or more lines.
|
|
||||||
*/
|
|
||||||
label.css({
|
|
||||||
'min-height': liBottom,
|
|
||||||
'max-height': liBottom + 1,
|
|
||||||
'vertical-align': 'middle'
|
|
||||||
});
|
|
||||||
thisLi.css({'top': liBottom * i, 'min-height': liBottom});
|
|
||||||
|
|
||||||
var r = label[0].getClientRects()[0];
|
|
||||||
if (r.bottom - r.top == liBottom) {
|
|
||||||
/* This means we have only one line of text; hence
|
|
||||||
* we can centre the text vertically by setting the line-height,
|
|
||||||
* as described at:
|
|
||||||
* http://www.ampsoft.net/webdesign-l/vertical-aligned-nav-list.html
|
|
||||||
*
|
|
||||||
* (Although firefox has .height on the rectangle, IE doesn't,
|
|
||||||
* so we use r.bottom - r.top rather than r.height.)
|
|
||||||
*/
|
|
||||||
label.css('line-height', parseInt(liBottom) + 'px');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/*
|
|
||||||
* If there is more than one line of text, then we shouldn't
|
|
||||||
* touch the line height, but we should make sure the text
|
|
||||||
* doesn't overflow the container.
|
|
||||||
*/
|
|
||||||
label.css("overflow", "hidden");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
thisLi.css('bottom', liBottom * i).prepend('<span class="line" />');
|
|
||||||
label.css('margin-top', -label.height() / 2)
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
charts.bar.draw();
|
//start from the bottom left
|
||||||
|
ctx.translate(0,zeroLoc);
|
||||||
},
|
//iterate and draw
|
||||||
|
|
||||||
draw: function() {
|
|
||||||
// Draw bars
|
|
||||||
|
|
||||||
if (horizontal) {
|
|
||||||
// for horizontal, keep the same code, but rotate everything 90 degrees
|
|
||||||
// clockwise.
|
|
||||||
ctx.rotate(Math.PI / 2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// for vertical, translate to the top left corner.
|
|
||||||
ctx.translate(0, zeroLocY);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't attempt to draw anything if all the values are zero,
|
|
||||||
// otherwise we will get weird exceptions from the canvas methods.
|
|
||||||
if (totalYRange <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var yScale = (horizontal ? canvas.width() : canvas.height()) / totalYRange;
|
|
||||||
var barWidth = horizontal ? (canvas.height() / xLabels.length) : (canvas.width() / (bottomLabels.length));
|
|
||||||
var linewidth = (barWidth - o.barGroupMargin*2) / dataGroups.length;
|
|
||||||
|
|
||||||
for(var h=0; h<dataGroups.length; h++){
|
for(var h=0; h<dataGroups.length; h++){
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
|
var linewidth = (xInterval-o.barGroupMargin*2) / dataGroups.length; //removed +1
|
||||||
var strokeWidth = linewidth - (o.barMargin*2);
|
var strokeWidth = linewidth - (o.barMargin*2);
|
||||||
ctx.lineWidth = strokeWidth;
|
ctx.lineWidth = strokeWidth;
|
||||||
var points = dataGroups[h].points;
|
var points = dataGroups[h].points;
|
||||||
var integer = 0;
|
var integer = 0;
|
||||||
for(var i=0; i<points.length; i++){
|
for(var i=0; i<points.length; i++){
|
||||||
// If the last value is zero, IE will go nuts and not draw anything,
|
|
||||||
// so don't try to draw zero values at all.
|
|
||||||
if (points[i].value != 0) {
|
|
||||||
var xVal = (integer-o.barGroupMargin)+(h*linewidth)+linewidth/2;
|
var xVal = (integer-o.barGroupMargin)+(h*linewidth)+linewidth/2;
|
||||||
xVal += o.barGroupMargin*2;
|
xVal += o.barGroupMargin*2;
|
||||||
|
|
||||||
ctx.moveTo(xVal, 0);
|
ctx.moveTo(xVal, 0);
|
||||||
ctx.lineTo(xVal, Math.round(-points[i].value*yScale));
|
ctx.lineTo(xVal, Math.round(-points[i]*yScale));
|
||||||
}
|
integer+=xInterval;
|
||||||
integer+=barWidth;
|
|
||||||
}
|
}
|
||||||
ctx.strokeStyle = dataGroups[h].color;
|
ctx.strokeStyle = dataGroups[h].color;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.closePath();
|
ctx.closePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
//create new canvas, set w&h attrs (not inline styles)
|
//create new canvas, set w&h attrs (not inline styles)
|
||||||
var canvasNode = document.createElement("canvas");
|
var canvasNode = document.createElement("canvas");
|
||||||
var canvas = $(canvasNode)
|
canvasNode.setAttribute('height',o.height);
|
||||||
.attr({
|
canvasNode.setAttribute('width',o.width);
|
||||||
'height': o.height,
|
var canvas = $(canvasNode);
|
||||||
'width': o.width
|
|
||||||
});
|
|
||||||
|
|
||||||
//get title for chart
|
//get title for chart
|
||||||
var title = o.title || self.find('caption').text();
|
var title = o.title || self.find('caption').text();
|
||||||
|
|
||||||
//create canvas wrapper div, set inline w&h, append
|
//create canvas wrapper div, set inline w&h, append
|
||||||
var canvasContain = (container || $('<div '+(o.chartId?'id="'+o.chartId+'" ':'')+'class="visualize '+o.chartClass+'" role="img" aria-label="Chart representing data from the table: '+ title +'" />'))
|
var canvasContain = (container || $('<div class="visualize" role="img" aria-label="Chart representing data from the table: '+ title +'" />'))
|
||||||
.height(o.height)
|
.height(o.height)
|
||||||
.width(o.width);
|
.width(o.width)
|
||||||
|
|
||||||
var scroller = $('<div class="visualize-scroller"></div>')
|
|
||||||
.appendTo(canvasContain)
|
|
||||||
.append(canvas);
|
.append(canvas);
|
||||||
|
|
||||||
|
//scrape table (this should be cleaned up into an obj)
|
||||||
|
var tableData = scrapeTable();
|
||||||
|
var dataGroups = tableData.dataGroups();
|
||||||
|
var allData = tableData.allData();
|
||||||
|
var dataSum = tableData.dataSum();
|
||||||
|
var topValue = tableData.topValue();
|
||||||
|
var bottomValue = tableData.bottomValue();
|
||||||
|
var memberTotals = tableData.memberTotals();
|
||||||
|
var totalYRange = tableData.totalYRange();
|
||||||
|
var zeroLoc = o.height * (topValue/totalYRange);
|
||||||
|
var xLabels = tableData.xLabels();
|
||||||
|
var yLabels = tableData.yLabels();
|
||||||
|
|
||||||
//title/key container
|
//title/key container
|
||||||
if(o.appendTitle || o.appendKey){
|
if(o.appendTitle || o.appendKey){
|
||||||
var infoContain = $('<div class="visualize-info"></div>')
|
var infoContain = $('<div class="visualize-info"></div>')
|
||||||
@ -666,130 +422,40 @@ $.fn.visualize = function(options, container){
|
|||||||
//append key
|
//append key
|
||||||
if(o.appendKey){
|
if(o.appendKey){
|
||||||
var newKey = $('<ul class="visualize-key"></ul>');
|
var newKey = $('<ul class="visualize-key"></ul>');
|
||||||
$.each(yAllLabels, function(i,label){
|
var selector;
|
||||||
$('<li><span class="visualize-key-color" style="background: '+dataGroups[i].color+'"></span><span class="visualize-key-label">'+ label +'</span></li>')
|
if(o.parseDirection == 'x'){
|
||||||
|
selector = self.find('tr:gt(0) th').filter(o.rowFilter);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
selector = self.find('tr:eq(0) th').filter(o.colFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
selector.each(function(i){
|
||||||
|
$('<li><span class="visualize-key-color" style="background: '+dataGroups[i].color+'"></span><span class="visualize-key-label">'+ $(this).text() +'</span></li>')
|
||||||
.appendTo(newKey);
|
.appendTo(newKey);
|
||||||
});
|
});
|
||||||
newKey.appendTo(infoContain);
|
newKey.appendTo(infoContain);
|
||||||
};
|
};
|
||||||
|
|
||||||
// init interaction
|
|
||||||
if(o.interaction) {
|
|
||||||
// sets the canvas to track interaction
|
|
||||||
// IE needs one div on top of the canvas since the VML shapes prevent mousemove from triggering correctly.
|
|
||||||
// Pie charts needs tracker because labels goes on top of the canvas and also messes up with mousemove
|
|
||||||
var tracker = $('<div class="visualize-interaction-tracker"/>')
|
|
||||||
.css({
|
|
||||||
'height': o.height + 'px',
|
|
||||||
'width': o.width + 'px',
|
|
||||||
'position':'relative',
|
|
||||||
'z-index': 200
|
|
||||||
})
|
|
||||||
.insertAfter(canvas);
|
|
||||||
|
|
||||||
var triggerInteraction = function(overOut,data) {
|
|
||||||
var data = $.extend({
|
|
||||||
canvasContain:canvasContain,
|
|
||||||
tableData:tableData
|
|
||||||
},data);
|
|
||||||
self.trigger('vizualize'+overOut,data);
|
|
||||||
};
|
|
||||||
|
|
||||||
var over=false, last=false, started=false;
|
|
||||||
tracker.mousemove(function(e){
|
|
||||||
var x,y,x1,y1,data,dist,i,current,selector,zLabel,elem,color,minDist,found,ev=e.originalEvent;
|
|
||||||
|
|
||||||
// get mouse position relative to the tracker/canvas
|
|
||||||
x = ev.layerX || ev.offsetX || 0;
|
|
||||||
y = ev.layerY || ev.offsetY || 0;
|
|
||||||
|
|
||||||
found = false;
|
|
||||||
minDist = started?30000:(o.type=='pie'?(Math.round(canvas.height()/2)-o.pieMargin)/3:o.lineWeight*4);
|
|
||||||
// iterate datagroups to find points with matching
|
|
||||||
$.each(charts[o.type].interactionPoints,function(i,current){
|
|
||||||
x1 = current.canvasCords[0] + zeroLocX;
|
|
||||||
y1 = current.canvasCords[1] + (o.type=="pie"?0:zeroLocY);
|
|
||||||
dist = Math.sqrt( (x1 - x)*(x1 - x) + (y1 - y)*(y1 - y) );
|
|
||||||
if(dist < minDist) {
|
|
||||||
found = current;
|
|
||||||
minDist = dist;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(o.multiHover && found) {
|
|
||||||
x = found.canvasCords[0] + zeroLocX;
|
|
||||||
y = found.canvasCords[1] + (o.type=="pie"?0:zeroLocY);
|
|
||||||
found = [found];
|
|
||||||
$.each(charts[o.type].interactionPoints,function(i,current){
|
|
||||||
if(current == found[0]) {return;}
|
|
||||||
x1 = current.canvasCords[0] + zeroLocX;
|
|
||||||
y1 = current.canvasCords[1] + zeroLocY;
|
|
||||||
dist = Math.sqrt( (x1 - x)*(x1 - x) + (y1 - y)*(y1 - y) );
|
|
||||||
if(dist <= o.multiHover) {
|
|
||||||
found.push(current);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// trigger over and out only when state changes, instead of on every mousemove
|
|
||||||
over = found;
|
|
||||||
if(over != last) {
|
|
||||||
if(over) {
|
|
||||||
if(last) {
|
|
||||||
triggerInteraction('Out',{point:last});
|
|
||||||
}
|
|
||||||
triggerInteraction('Over',{point:over});
|
|
||||||
last = over;
|
|
||||||
}
|
|
||||||
if(last && !over) {
|
|
||||||
triggerInteraction('Out',{point:last});
|
|
||||||
last=false;
|
|
||||||
}
|
|
||||||
started=true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tracker.mouseleave(function(){
|
|
||||||
triggerInteraction('Out',{
|
|
||||||
point:last,
|
|
||||||
mouseOutGraph:true
|
|
||||||
});
|
|
||||||
over = (last = false);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//append new canvas to page
|
//append new canvas to page
|
||||||
|
|
||||||
if(!container){canvasContain.insertAfter(this); }
|
if(!container){canvasContain.insertAfter(this); }
|
||||||
if( typeof(G_vmlCanvasManager) != 'undefined' ){ G_vmlCanvasManager.init(); G_vmlCanvasManager.initElement(canvas[0]); }
|
if( typeof(G_vmlCanvasManager) != 'undefined' ){ G_vmlCanvasManager.init(); G_vmlCanvasManager.initElement(canvas[0]); }
|
||||||
|
|
||||||
//set up the drawing board
|
//set up the drawing board
|
||||||
var ctx = canvas[0].getContext('2d');
|
var ctx = canvas[0].getContext('2d');
|
||||||
|
|
||||||
// Scroll graphs
|
|
||||||
scroller.scrollLeft(o.width-scroller.width());
|
|
||||||
|
|
||||||
// init plugins
|
|
||||||
$.each($.visualizePlugins,function(i,plugin){
|
|
||||||
plugin.call(self,o,tableData);
|
|
||||||
});
|
|
||||||
|
|
||||||
//create chart
|
//create chart
|
||||||
charts[o.type].setup();
|
createChart[o.type]();
|
||||||
|
|
||||||
|
//clean up some doubled lines that sit on top of canvas borders (done via JS due to IE)
|
||||||
|
$('.visualize-line li:first-child span.line, .visualize-line li:last-child span.line, .visualize-area li:first-child span.line, .visualize-area li:last-child span.line, .visualize-bar li:first-child span.line,.visualize-bar .visualize-labels-y li:last-child span.line').css('border','none');
|
||||||
if(!container){
|
if(!container){
|
||||||
//add event for updating
|
//add event for updating
|
||||||
self.bind('visualizeRefresh', function(){
|
canvasContain.bind('visualizeRefresh', function(){
|
||||||
self.visualize(o, $(this).empty());
|
self.visualize(o, $(this).empty());
|
||||||
});
|
});
|
||||||
//add event for redraw
|
|
||||||
self.bind('visualizeRedraw', function(){
|
|
||||||
charts[o.type].draw();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}).next(); //returns canvas(es)
|
}).next(); //returns canvas(es)
|
||||||
};
|
};
|
||||||
// create array for plugins. if you wish to make a plugin,
|
|
||||||
// just push your init funcion into this array
|
|
||||||
$.visualizePlugins = [];
|
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user