Reputation: 117
Hi im using Kinetic to draw some bubbles from data sent via json. My code seems to work and generates the bubbles fine. Im trying to get an effect on mouser over to start with, and then the next stag will be to produce a tool-tip for each bubble, But currently the mouse over will only work on the largest bubble? Can any one see anything wrong with my code
I have added a picture so you can see what is
<script >
var stage = new Kinetic.Stage({
container: 'graph',
width: 1000,
height: 1000
});
var layer = new Kinetic.Layer();
// setup graph padding
var graph;
var xPadding = 30;
var yPadding = 30;
var drawGraph = new Kinetic.Shape ({
sceneFunc: function(ctx){
ctx.beginPath();
ctx.moveTo(xPadding, 0);
ctx.lineTo(xPadding, stage.height() - yPadding);
ctx.lineTo(stage.width(), stage.height() - yPadding);
//Draw the X value texts
// for(var i = 0; i < projects.values.length; i ++) {
// ctx.fillText(data.values[i].X, getXPixel(i), graph.height() - yPadding + 20);
// }
// Draw the Y value texts
ctx.textAlign = "right"
ctx.textBaseline = "middle";
ctx.fillStyle = '#333';
for(var i = 0; i < getMaxY(); i += 5) {
ctx.fillText((i), xPadding - 15, getYPixel(i));
}
ctx.fillStrokeShape(this);
},
stroke: 'black',
strokeWidth: 1
});![enter image description here][2]
$.getJSON( "bubble_data.json", function( data ) {
var maxHour= data.max_hour_task;
$.each( data.projects, function(i) {
//calculate the number of days between two dates
var oneDay = 24*60*60*1000; // hours*minutes*seconds*milliseconds
var startOfQ = new Date(2014,00,00);
var startDate = new Date(data.projects[i].summary.created_on);
var endDate = new Date(data.projects[i].summary.target_date);
var startDayPos = (Math.round(Math.abs((startOfQ.getTime() - startDate.getTime())/(oneDay))))*6;
var diffDays = (Math.round(Math.abs((startDate.getTime() - endDate.getTime())/(oneDay))))*6;
var endDayPos = startDayPos + diffDays ;
hours=(data.projects[i].summary.total_hours);
base = stage.height() - yPadding;
getMaxY(hours);
hours_scale =((stage.height()-(stage.height() - (((stage.height() - yPadding) / maxHour)))) *hours)
total_hours = 970 - hours_scale;
var bubble = new Kinetic.Shape({
sceneFunc: function(ctx) {
var x=this.myX;
var y=this.myY;
var w=this.myW;
var h=this.myH;
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
xe = x + w, // x-end
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
ctx.beginPath();
ctx.moveTo(x, ym);
ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
ctx.closePath();
ctx.fillStrokeShape(this);
},
fill: 'rgba(142, 214, 255, 0.1)',
stroke: 'black',
strokeWidth: 1
});
bubble.myX=startDayPos;
bubble.myY=base;
bubble.myW=endDayPos;
bubble.myH=-hours_scale;
bubble.on('mouseover', function() {
console.log(this);
this.fill('blue');
bubble.draw();
});
bubble.on('mouseout', function() {
console.log(this);
this.fill('rgba(142, 214, 255, 0.1)');
bubble.draw();
});
layer.add(bubble);
});
layer.add(drawGraph);
stage.add(layer);
});
function getMaxY() {
var max = 0;
if(hours > max) {
max = hours;
}
max += 10 - max % 10;
return max;
}
// // function getXPixel(val) {
// // return ((graph.width() - xPadding) / projects.values.length) * val + (xPadding * 1.5);
// // }
function getYPixel(val) {
return stage.height() - (((stage.height() - yPadding) / getMaxY()) * val) - yPadding;
}
</script>
Upvotes: 0
Views: 144
Reputation: 105035
Remember that Kinetic maintains a z-index for each shape -- even for semi-transparent shapes.
So your mouseover & mouseout events will fire for only the topmost shape under the mouse (not for all shapes under the mouse)
If you want to trigger tooltips for all shapes under the mouse you can use stage.getAllIntersections
Note: .getAllIntersections
is a computationally expensive operation so you will take a performance hit when using it.
Upvotes: 1