Better events

This commit is contained in:
Tanner Linsley 2015-05-12 10:34:47 -06:00
parent e709b13e77
commit afb22d15ae
3 changed files with 126 additions and 79 deletions

187
Chart.js vendored
View File

@ -59,7 +59,7 @@
animation: true,
// Number - Number of animation steps
animationSteps: 60,
animationDuration: 1000,
// String - Animation easing effect
animationEasing: "easeOutQuart",
@ -124,7 +124,7 @@
tooltipEvents: ["mousemove", "touchstart", "touchmove", "mouseout"],
// String - Tooltip background colour
tooltipFillColor: "rgba(0,0,0,0.8)",
tooltipBackgroundColor: "rgba(0,0,0,0.8)",
// String - Tooltip label font declaration for the scale label
tooltipFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
@ -934,14 +934,14 @@
return this;
},
reflow : noop,
render : function(reflow){
render : function(reflow, customDuration){
if (reflow){
this.reflow();
}
if (this.options.animation && !reflow){
var animation = new Chart.Animation();
animation.numSteps = this.options.animationSteps;
animation.numSteps = (customDuration || this.options.animationDuration) / 16.66; //60 fps
animation.easing = this.options.animationEasing;
// render function
@ -1059,8 +1059,8 @@
//Include any colour information about the element
tooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));
tooltipColors.push({
fill: element._vm.fillColor || element.fillColor,
stroke: element._vm.strokeColor || element.strokeColor
fill: element._vm.backgroundColor || element.backgroundColor,
stroke: element._vm.borderColor || element.borderColor
});
}, this);
@ -1083,7 +1083,7 @@
xPadding: this.options.tooltipXPadding,
yPadding: this.options.tooltipYPadding,
xOffset: this.options.tooltipXOffset,
fillColor: this.options.tooltipFillColor,
backgroundColor: this.options.tooltipBackgroundColor,
textColor: this.options.tooltipFontColor,
fontFamily: this.options.tooltipFontFamily,
fontStyle: this.options.tooltipFontStyle,
@ -1110,7 +1110,7 @@
y: Math.round(tooltipPosition.y),
xPadding: this.options.tooltipXPadding,
yPadding: this.options.tooltipYPadding,
fillColor: this.options.tooltipFillColor,
backgroundColor: this.options.tooltipBackgroundColor,
textColor: this.options.tooltipFontColor,
fontFamily: this.options.tooltipFontFamily,
fontStyle: this.options.tooltipFontStyle,
@ -1205,7 +1205,12 @@
if(props.indexOf(key) > -1){
// Color transitions if possible
if(typeof value === 'string'){
// TODO support color transitions
try{
var color = Color(this._start[key]).mix(Color(this[key]), ease);
this._vm[key] = color.rgbString();
} catch(err){
this._vm[key] = value;
}
return;
}
// Everything else, presumably numbers
@ -1250,10 +1255,10 @@
ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);
ctx.closePath();
ctx.strokeStyle = this.strokeColor;
ctx.lineWidth = this.strokeWidth;
ctx.strokeStyle = this.borderColor;
ctx.lineWidth = this.borderWidth;
ctx.fillStyle = this.fillColor;
ctx.fillStyle = this.backgroundColor;
ctx.fill();
ctx.stroke();
@ -1323,15 +1328,15 @@
ctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);
ctx.closePath();
ctx.strokeStyle = this.strokeColor;
ctx.lineWidth = this.strokeWidth;
ctx.strokeStyle = this.borderColor;
ctx.lineWidth = this.borderWidth;
ctx.fillStyle = this.fillColor;
ctx.fillStyle = this.backgroundColor;
ctx.fill();
ctx.lineJoin = 'bevel';
if (this.showStroke){
if (this.showBorder){
ctx.stroke();
}
}
@ -1347,11 +1352,11 @@
leftX = vm.x - halfWidth,
rightX = vm.x + halfWidth,
top = vm.base - (vm.base - vm.y),
halfStroke = vm.strokeWidth / 2;
halfStroke = vm.borderWidth / 2;
// Canvas doesn't allow us to stroke inside the width so we can
// adjust the sizes to fit if we're setting a stroke on the line
if (vm.showStroke){
if (vm.borderWidth){
leftX += halfStroke;
rightX -= halfStroke;
top += halfStroke;
@ -1359,9 +1364,9 @@
ctx.beginPath();
ctx.fillStyle = vm.fillColor;
ctx.strokeStyle = vm.strokeColor;
ctx.lineWidth = vm.strokeWidth;
ctx.fillStyle = vm.backgroundColor;
ctx.strokeStyle = vm.borderColor;
ctx.lineWidth = vm.borderWidth;
// It'd be nice to keep this class totally generic to any rectangle
// and simply specify which border to miss out.
@ -1370,7 +1375,7 @@
ctx.lineTo(rightX, top);
ctx.lineTo(rightX, vm.base);
ctx.fill();
if (vm.showStroke){
if (vm.borderWidth){
ctx.stroke();
}
},
@ -1425,7 +1430,7 @@
var tooltipX = this.x - tooltipWidth/2,
tooltipY = this.y - tooltipHeight;
ctx.fillStyle = this.fillColor;
ctx.fillStyle = this.backgroundColor;
// Custom Tooltips
if(this.custom){
@ -1533,7 +1538,7 @@
else{
drawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);
var ctx = this.ctx;
ctx.fillStyle = this.fillColor;
ctx.fillStyle = this.backgroundColor;
ctx.fill();
ctx.closePath();
@ -2104,6 +2109,8 @@
animations: [],
dropFrames: 0,
addAnimation: function(chartInstance, animationObject) {
chartInstance.animating = true;
for (var index = 0; index < this.animations.length; ++ index){
if (this.animations[index].chartInstance === chartInstance){
// replacing an in progress animation
@ -2130,6 +2137,7 @@
if (index){
this.animations.splice(index, 1);
chartInstance.animating = false;
}
},
// calls startDigest with the proper context
@ -2161,6 +2169,7 @@
if (this.animations[i].animationObject.currentStep == this.animations[i].animationObject.numSteps){
// executed the last frame. Remove the animation.
this.animations[i].chartInstance.animating = false;
this.animations.splice(i, 1);
// Keep the index in place to offset the splice
i--;
@ -2245,11 +2254,8 @@
//Boolean - Whether to show vertical lines (except Y axis)
scaleShowVerticalLines: true,
//Boolean - If there is a stroke on each bar
barShowStroke : true,
//Number - Pixel width of the bar stroke
barStrokeWidth : 2,
//Number - Pixel width of the bar border
barBorderWidth : 2,
//Number - Spacing between each of the X value sets
barValueSpacing : 5,
@ -2263,8 +2269,11 @@
//Function - Custom hover handler
onHover : null,
//Function - Custom hover handler
hoverDuration : 400,
//String - A legend template
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].fillColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
legendTemplate : "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\"background-color:<%=datasets[i].backgroundColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>"
};
@ -2301,33 +2310,8 @@
}
});
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, function(e){
var active;
if(e.type == 'mouseout'){
return false;
}
if(this.options.hoverMode == 'bar'){
active = this.getBarAtEvent(e);
// TODO: tooltips for single items
}
else if(this.options.hoverMode == 'bars'){
active = this.getBarsAtEvent(e);
}
else {
// TODO: active = this.getDatasetAtEvent(e);
}
if(this.options.onHover){
this.options.onHover.call(this, active);
}
this.showTooltip(active);
});
}
// Events
helpers.bindEvents(this, this.options.tooltipEvents, this.onHover);
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.BarClass = Chart.Rectangle.extend({
@ -2359,6 +2343,65 @@
this.update();
},
onHover: function(e){
var active;
if(e.type == 'mouseout'){
return false;
}
if(this.options.hoverMode == 'bar'){
active = this.getBarAtEvent(e);
}
else if(this.options.hoverMode == 'bars'){}
// Remove styling for last active
if(this.lastActive){
if(this.options.hoverMode == 'bar'){
this.lastActive.rectangle.backgroundColor = this.data.datasets[this.lastActive.datasetIndex].backgroundColor;
this.lastActive.rectangle.borderColor = this.data.datasets[this.lastActive.datasetIndex].borderColor;
this.lastActive.rectangle.borderWidth = 0;
}
else if(this.options.hoverMode == 'bars'){}
}
// Custom Hover actions
if(this.options.onHover){
this.options.onHover.call(this, active);
}
else if(active){
// or default hover action
if(this.options.hoverMode == 'bar'){
active.rectangle.backgroundColor = this.data.datasets[active.datasetIndex].hoverBackgroundColor || Color(active.rectangle.backgroundColor).saturate(0.5).darken(0.25).rgbString();
active.rectangle.borderColor = this.data.datasets[active.datasetIndex].hoverBorderColor || Color(active.rectangle.borderColor).saturate(0.5).darken(0.25).rgbString();
}
else if(this.options.hoverMode == 'bars'){}
}
if(!this.animating){
// If entering
if(!this.lastActive && active){
this.render(false, this.options.hoverDuration);
}
// If different bar
if(this.lastActive && active && this.lastActive.rectangle !== active.rectangle){
this.render(false, this.options.hoverDuration);
}
// if Leaving
if (this.lastActive && !active){
this.render(false, this.options.hoverDuration);
}
}
this.lastActive = active;
if (this.options.showTooltips){
this.showTooltip(active);
}
},
update : function(){
this.scale.update();
@ -2371,10 +2414,9 @@
value : this.data.datasets[datasetIndex].data[index],
label : this.data.labels[index],
datasetLabel: this.data.datasets[datasetIndex].label,
strokeColor : this.data.datasets[datasetIndex].strokeColor,
fillColor : this.data.datasets[datasetIndex].fillColor,
highlightFill : this.data.datasets[datasetIndex].highlightFill || this.data.datasets[datasetIndex].fillColor,
highlightStroke : this.data.datasets[datasetIndex].highlightStroke || this.data.datasets[datasetIndex].strokeColor,
borderColor : this.data.datasets[datasetIndex].borderColor,
borderWidth : this.data.datasets[datasetIndex].borderWidth,
backgroundColor : this.data.datasets[datasetIndex].backgroundColor,
_start: undefined
});
}, this);
@ -2417,11 +2459,11 @@
var bar;
var eventPosition = helpers.getRelativePosition(e);
for (var datasetIndex = 0; datasetIndex < this.datasets.length; ++datasetIndex) {
for (var barIndex = 0; barIndex < this.datasets[datasetIndex].metaData.length; ++barIndex) {
if (this.datasets[datasetIndex].metaData[barIndex].inRange(eventPosition.x, eventPosition.y)) {
for (var datasetIndex = 0; datasetIndex < this.data.datasets.length; ++datasetIndex) {
for (var barIndex = 0; barIndex < this.data.datasets[datasetIndex].metaData.length; ++barIndex) {
if (this.data.datasets[datasetIndex].metaData[barIndex].inRange(eventPosition.x, eventPosition.y)) {
bar = {
rectangle : this.datasets[datasetIndex].metaData[barIndex],
rectangle : this.data.datasets[datasetIndex].metaData[barIndex],
datasetIndex : datasetIndex,
barIndex : barIndex,
};
@ -2473,7 +2515,7 @@
showVerticalLines : this.options.scaleShowVerticalLines,
gridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,
gridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : "rgba(0,0,0,0)",
padding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,
padding : (this.options.showScale) ? 0 : this.options.borderWidth,
showLabels : this.options.scaleShowLabels,
display : this.options.showScale
};
@ -2502,8 +2544,8 @@
y: this.scale.endPoint,
width : this.scale.calculateBarWidth(this.data.datasets.length),
base : this.scale.endPoint,
strokeColor : this.data.datasets[datasetIndex].strokeColor,
fillColor : this.data.datasets[datasetIndex].fillColor
borderColor : this.data.datasets[datasetIndex].borderColor,
backgroundColor : this.data.datasets[datasetIndex].backgroundColor
}));
},this);
@ -2543,7 +2585,14 @@
// Update the bar basepoint
bar.base = this.scale.endPoint;
//Transition
bar.transition(['x','y','width'], easingDecimal).draw();
bar.transition([
'x',
'y',
'width',
'backgroundColor',
'borderColor',
'borderWidth'
], easingDecimal).draw();
}
}, this);
}

6
Chart.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -81,12 +81,8 @@
}
});
//Set up tooltip events on the chart
if (this.options.showTooltips){
helpers.bindEvents(this, this.options.tooltipEvents, this.onHover);
}
// Events
helpers.bindEvents(this, this.options.tooltipEvents, this.onHover);
//Declare the extension of the default point, to cater for the options passed in to the constructor
this.BarClass = Chart.Rectangle.extend({
@ -173,7 +169,9 @@
this.lastActive = active;
//this.showTooltip(active);
if (this.options.showTooltips){
this.showTooltip(active);
}
},
// Calculate the base point for the bar.
// If the scale has a 0 point, use that as the base