mirror of
https://github.com/chartjs/Chart.js.git
synced 2024-10-07 04:39:06 +02:00
Initial implementation of a scatter chart. Uses a new style of config from the other charts. For now, the config is not changeable.
This commit is contained in:
parent
d7ad5b6340
commit
67b3d32218
@ -55,6 +55,8 @@
|
||||
// The interesting function
|
||||
fitScalesForChart: function(chartInstance, width, height) {
|
||||
var chartScaleWrapper = this.getWrapperForChart(chartInstance);
|
||||
var xPadding = 10;
|
||||
var yPadding = 10;
|
||||
|
||||
if (chartScaleWrapper) {
|
||||
var leftScales = helpers.where(chartScaleWrapper.scales, function(scaleInstance) {
|
||||
@ -70,6 +72,31 @@
|
||||
return scaleInstance.options.position == "bottom";
|
||||
});
|
||||
|
||||
// Adjust the padding to take into account displaying labels
|
||||
if (topScales.length == 0 || bottomScales.length == 0) {
|
||||
var maxFontHeight = 0;
|
||||
|
||||
var maxFontHeightFunction = function(scaleInstance) {
|
||||
if (scaleInstance.options.labels.show) {
|
||||
// Only consider font sizes for axes that actually show labels
|
||||
maxFontHeight = Math.max(maxFontHeight, scaleInstance.options.labels.fontSize);
|
||||
}
|
||||
};
|
||||
|
||||
helpers.each(leftScales, maxFontHeightFunction);
|
||||
helpers.each(rightScales, maxFontHeightFunction);
|
||||
|
||||
if (topScales.length == 0) {
|
||||
// Add padding so that we can handle drawing the top nicely
|
||||
yPadding += 0.75 * maxFontHeight; // 0.75 since padding added on both sides
|
||||
}
|
||||
|
||||
if (bottomScales.length == 0) {
|
||||
// Add padding so that we can handle drawing the bottom nicely
|
||||
yPadding += 1.5 * maxFontHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Essentially we now have any number of scales on each of the 4 sides.
|
||||
// Our canvas looks like the following.
|
||||
// The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
|
||||
@ -111,6 +138,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
chartWidth -= (2 * xPadding);
|
||||
chartHeight-= (2 * yPadding);
|
||||
|
||||
// Step 2
|
||||
var verticalScaleWidth = (width - chartWidth) / (leftScales.length + rightScales.length);
|
||||
|
||||
@ -139,8 +169,8 @@
|
||||
helpers.each(bottomScales, horizontalScaleMinSizeFunction);
|
||||
|
||||
// Step 5
|
||||
var maxChartHeight = height;
|
||||
var maxChartWidth = width;
|
||||
var maxChartHeight = height - (2 * yPadding);
|
||||
var maxChartWidth = width - (2 * xPadding);
|
||||
|
||||
var chartWidthReduceFunction = function(scaleInstance) {
|
||||
maxChartWidth -= scalesToMinSize[scaleInstance].width;
|
||||
@ -189,8 +219,8 @@
|
||||
helpers.each(bottomScales, horizontalScaleFitFunction);
|
||||
|
||||
// Step 7
|
||||
var totalLeftWidth = 0;
|
||||
var totalTopHeight = 0;
|
||||
var totalLeftWidth = xPadding;
|
||||
var totalTopHeight = yPadding;
|
||||
|
||||
// Calculate total width of all left axes
|
||||
helpers.each(leftScales, function(scaleInstance) {
|
||||
@ -203,8 +233,8 @@
|
||||
});
|
||||
|
||||
// Position the scales
|
||||
var left = 0;
|
||||
var top = 0;
|
||||
var left = xPadding;
|
||||
var top = yPadding;
|
||||
var right = 0;
|
||||
var bottom = 0;
|
||||
|
||||
@ -303,7 +333,8 @@
|
||||
if (this.isHorizontal()) {
|
||||
maxTicks = Math.min(11, Math.ceil(width / 50));
|
||||
} else {
|
||||
maxTicks = Math.min(11, Math.ceil(height / 50));
|
||||
// The factor of 2 used to scale the font size has been experimentally determined.
|
||||
maxTicks = Math.min(11, Math.ceil(height / (2 * this.options.labels.fontSize)));
|
||||
}
|
||||
|
||||
// To get a "nice" value for the tick spacing, we will use the appropriately named
|
||||
@ -332,6 +363,11 @@
|
||||
// We are in a vertical orientation. The top value is the highest. So reverse the array
|
||||
this.ticks.reverse();
|
||||
}
|
||||
|
||||
// At this point, we need to update our max and min given the tick values since we have expanded the
|
||||
// range of the scale
|
||||
this.max = helpers.max(this.ticks);
|
||||
this.min = helpers.min(this.ticks);
|
||||
},
|
||||
buildLabels: function() {
|
||||
// We assume that this has been run after ticks have been generated. We try to figure out
|
||||
@ -498,6 +534,9 @@
|
||||
var setContextLineSettings;
|
||||
var hasZero;
|
||||
|
||||
// Make sure we draw text in the correct color
|
||||
this.ctx.fillStyle = this.options.labels.fontColor;
|
||||
|
||||
if (this.isHorizontal()) {
|
||||
if (this.options.gridLines.show) {
|
||||
// Draw the horizontal line
|
||||
|
490
src/Chart.Scatter.js
Normal file
490
src/Chart.Scatter.js
Normal file
@ -0,0 +1,490 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var root = this,
|
||||
Chart = root.Chart,
|
||||
helpers = Chart.helpers;
|
||||
|
||||
var defaultConfig = {
|
||||
|
||||
///Boolean - Whether grid lines are shown across the chart
|
||||
scaleShowGridLines: true,
|
||||
|
||||
//String - Colour of the grid lines
|
||||
scaleGridLineColor: "rgba(0,0,0,.05)",
|
||||
|
||||
//Number - Width of the grid lines
|
||||
scaleGridLineWidth: 1,
|
||||
|
||||
//Boolean - Whether to show horizontal lines (except X axis)
|
||||
scaleShowHorizontalLines: true,
|
||||
|
||||
//Boolean - Whether to show vertical lines (except Y axis)
|
||||
scaleShowVerticalLines: true,
|
||||
|
||||
//Number - Tension of the bezier curve between points
|
||||
tension: 0.4,
|
||||
|
||||
//Number - Radius of each point dot in pixels
|
||||
pointRadius: 4,
|
||||
|
||||
//Number - Pixel width of point dot border
|
||||
pointBorderWidth: 1,
|
||||
|
||||
//Number - amount extra to add to the radius to cater for hit detection outside the drawn point
|
||||
pointHoverRadius: 20,
|
||||
|
||||
//Number - Pixel width of dataset border
|
||||
borderWidth: 2,
|
||||
|
||||
//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].borderColor%>\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>",
|
||||
|
||||
//Boolean - Whether to horizontally center the label and point dot inside the grid
|
||||
offsetGridLines: false
|
||||
|
||||
};
|
||||
|
||||
|
||||
Chart.Type.extend({
|
||||
name: "Scatter",
|
||||
defaults: defaultConfig,
|
||||
initialize: function(data) {
|
||||
// Save data as a source for updating of values & methods
|
||||
this.data = data;
|
||||
|
||||
//Custom Point Defaults
|
||||
this.PointClass = Chart.Point.extend({
|
||||
_chart: this.chart,
|
||||
offsetGridLines: this.options.offsetGridLines,
|
||||
borderWidth: this.options.pointBorderWidth,
|
||||
radius: this.options.pointRadius,
|
||||
hoverRadius: this.options.pointHoverRadius,
|
||||
});
|
||||
|
||||
// Events
|
||||
helpers.bindEvents(this, this.options.tooltipEvents, this.onHover);
|
||||
|
||||
// Build Scale
|
||||
this.buildScale(this.data.labels);
|
||||
Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height);
|
||||
|
||||
//Create a new line and its points for each dataset and piece of data
|
||||
helpers.each(this.data.datasets, function(dataset, datasetIndex) {
|
||||
dataset.metaDataset = new Chart.Line();
|
||||
dataset.metaData = [];
|
||||
helpers.each(dataset.data, function(dataPoint, index) {
|
||||
dataset.metaData.push(new this.PointClass());
|
||||
}, this);
|
||||
}, this);
|
||||
|
||||
// Set defaults for lines
|
||||
this.eachDataset(function(dataset, datasetIndex) {
|
||||
dataset = helpers.merge(this.options, dataset);
|
||||
helpers.extend(dataset.metaDataset, {
|
||||
_points: dataset.metaData,
|
||||
_datasetIndex: datasetIndex,
|
||||
_chart: this.chart,
|
||||
});
|
||||
// Copy to view model
|
||||
dataset.metaDataset.save();
|
||||
}, this);
|
||||
|
||||
// Set defaults for points
|
||||
this.eachElement(function(point, index, dataset, datasetIndex) {
|
||||
helpers.extend(point, {
|
||||
x: this.xScale.getPixelForValue(index),
|
||||
y: this.chartArea.bottom,
|
||||
_datasetIndex: datasetIndex,
|
||||
_index: index,
|
||||
_chart: this.chart
|
||||
});
|
||||
|
||||
// Default bezier control points
|
||||
helpers.extend(point, {
|
||||
controlPointPreviousX: this.previousPoint(dataset, index).x,
|
||||
controlPointPreviousY: this.nextPoint(dataset, index).y,
|
||||
controlPointNextX: this.previousPoint(dataset, index).x,
|
||||
controlPointNextY: this.nextPoint(dataset, index).y,
|
||||
});
|
||||
// Copy to view model
|
||||
point.save();
|
||||
}, this);
|
||||
|
||||
// Create tooltip instance exclusively for this chart with some defaults.
|
||||
this.tooltip = new Chart.Tooltip({
|
||||
_chart: this.chart,
|
||||
_data: this.data,
|
||||
_options: this.options,
|
||||
}, this);
|
||||
|
||||
this.update();
|
||||
},
|
||||
nextPoint: function(collection, index) {
|
||||
return collection[index - 1] || collection[index];
|
||||
},
|
||||
previousPoint: function(collection, index) {
|
||||
return collection[index + 1] || collection[index];
|
||||
},
|
||||
onHover: function(e) {
|
||||
// If exiting chart
|
||||
if (e.type == 'mouseout') {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.lastActive = this.lastActive || [];
|
||||
|
||||
// Find Active Elements
|
||||
this.active = function() {
|
||||
switch (this.options.hoverMode) {
|
||||
case 'single':
|
||||
return this.getElementAtEvent(e);
|
||||
case 'label':
|
||||
return this.getElementsAtEvent(e);
|
||||
case 'dataset':
|
||||
return this.getDatasetAtEvent(e);
|
||||
default:
|
||||
return e;
|
||||
}
|
||||
}.call(this);
|
||||
|
||||
// On Hover hook
|
||||
if (this.options.onHover) {
|
||||
this.options.onHover.call(this, this.active);
|
||||
}
|
||||
|
||||
// Remove styling for last active (even if it may still be active)
|
||||
if (this.lastActive.length) {
|
||||
switch (this.options.hoverMode) {
|
||||
case 'single':
|
||||
this.lastActive[0].backgroundColor = this.data.datasets[this.lastActive[0]._datasetIndex].pointBackgroundColor;
|
||||
this.lastActive[0].borderColor = this.data.datasets[this.lastActive[0]._datasetIndex].pointBorderColor;
|
||||
this.lastActive[0].borderWidth = this.data.datasets[this.lastActive[0]._datasetIndex].pointBorderWidth;
|
||||
break;
|
||||
case 'label':
|
||||
for (var i = 0; i < this.lastActive.length; i++) {
|
||||
this.lastActive[i].backgroundColor = this.data.datasets[this.lastActive[i]._datasetIndex].pointBackgroundColor;
|
||||
this.lastActive[i].borderColor = this.data.datasets[this.lastActive[i]._datasetIndex].pointBorderColor;
|
||||
this.lastActive[i].borderWidth = this.data.datasets[this.lastActive[0]._datasetIndex].pointBorderWidth;
|
||||
}
|
||||
break;
|
||||
case 'dataset':
|
||||
break;
|
||||
default:
|
||||
// Don't change anything
|
||||
}
|
||||
}
|
||||
|
||||
// Built in hover styling
|
||||
if (this.active.length && this.options.hoverMode) {
|
||||
switch (this.options.hoverMode) {
|
||||
case 'single':
|
||||
this.active[0].backgroundColor = this.data.datasets[this.active[0]._datasetIndex].hoverBackgroundColor || helpers.color(this.active[0].backgroundColor).saturate(0.5).darken(0.35).rgbString();
|
||||
this.active[0].borderColor = this.data.datasets[this.active[0]._datasetIndex].hoverBorderColor || helpers.color(this.active[0].borderColor).saturate(0.5).darken(0.35).rgbString();
|
||||
this.active[0].borderWidth = this.data.datasets[this.active[0]._datasetIndex].borderWidth + 10;
|
||||
break;
|
||||
case 'label':
|
||||
for (var i = 0; i < this.active.length; i++) {
|
||||
this.active[i].backgroundColor = this.data.datasets[this.active[i]._datasetIndex].hoverBackgroundColor || helpers.color(this.active[i].backgroundColor).saturate(0.5).darken(0.35).rgbString();
|
||||
this.active[i].borderColor = this.data.datasets[this.active[i]._datasetIndex].hoverBorderColor || helpers.color(this.active[i].borderColor).saturate(0.5).darken(0.35).rgbString();
|
||||
this.active[i].borderWidth = this.data.datasets[this.active[i]._datasetIndex].borderWidth + 2;
|
||||
}
|
||||
break;
|
||||
case 'dataset':
|
||||
break;
|
||||
default:
|
||||
// Don't change anything
|
||||
}
|
||||
}
|
||||
|
||||
// Built in Tooltips
|
||||
if (this.options.showTooltips) {
|
||||
|
||||
// The usual updates
|
||||
this.tooltip.initialize();
|
||||
|
||||
// Active
|
||||
if (this.active.length) {
|
||||
helpers.extend(this.tooltip, {
|
||||
opacity: 1,
|
||||
_active: this.active,
|
||||
});
|
||||
|
||||
this.tooltip.update();
|
||||
} else {
|
||||
// Inactive
|
||||
helpers.extend(this.tooltip, {
|
||||
opacity: 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Hover animations
|
||||
this.tooltip.pivot();
|
||||
|
||||
if (!this.animating) {
|
||||
var changed;
|
||||
|
||||
helpers.each(this.active, function(element, index) {
|
||||
if (element !== this.lastActive[index]) {
|
||||
changed = true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
// If entering, leaving, or changing elements, animate the change via pivot
|
||||
if ((!this.lastActive.length && this.active.length) ||
|
||||
(this.lastActive.length && !this.active.length) ||
|
||||
(this.lastActive.length && this.active.length && changed)) {
|
||||
|
||||
this.stop();
|
||||
this.render(this.options.hoverAnimationDuration);
|
||||
}
|
||||
}
|
||||
|
||||
// Remember Last Active
|
||||
this.lastActive = this.active;
|
||||
return this;
|
||||
|
||||
},
|
||||
update: function() {
|
||||
Chart.scaleService.fitScalesForChart(this, this.chart.width, this.chart.height);
|
||||
|
||||
// Update the lines
|
||||
this.eachDataset(function(dataset, datasetIndex) {
|
||||
helpers.extend(dataset.metaDataset, {
|
||||
backgroundColor: dataset.backgroundColor || this.options.backgroundColor,
|
||||
borderWidth: dataset.borderWidth || this.options.borderWidth,
|
||||
borderColor: dataset.borderColor || this.options.borderColor,
|
||||
tension: dataset.tension || this.options.tension,
|
||||
scaleTop: this.chartArea.top,
|
||||
scaleBottom: this.chartArea.bottom,
|
||||
_points: dataset.metaData,
|
||||
_datasetIndex: datasetIndex,
|
||||
});
|
||||
dataset.metaDataset.pivot();
|
||||
});
|
||||
|
||||
// Update the points
|
||||
this.eachElement(function(point, index, dataset, datasetIndex) {
|
||||
helpers.extend(point, {
|
||||
x: this.xScale.getPixelForValue(this.data.datasets[datasetIndex].data[index].x),
|
||||
y: this.yScale.getPixelForValue(this.data.datasets[datasetIndex].data[index].y),
|
||||
value: this.data.datasets[datasetIndex].data[index].y,
|
||||
label: this.data.datasets[datasetIndex].data[index].x,
|
||||
datasetLabel: this.data.datasets[datasetIndex].label,
|
||||
// Appearance
|
||||
hoverBackgroundColor: this.data.datasets[datasetIndex].pointHoverBackgroundColor || this.options.pointHoverBackgroundColor,
|
||||
hoverBorderColor: this.data.datasets[datasetIndex].pointHoverBorderColor || this.options.pointHoverBorderColor,
|
||||
hoverRadius: this.data.datasets[datasetIndex].pointHoverRadius || this.options.pointHoverRadius,
|
||||
radius: this.data.datasets[datasetIndex].pointRadius || this.options.pointRadius,
|
||||
borderWidth: this.data.datasets[datasetIndex].pointBorderWidth || this.options.pointBorderWidth,
|
||||
borderColor: this.data.datasets[datasetIndex].pointBorderColor || this.options.pointBorderColor,
|
||||
backgroundColor: this.data.datasets[datasetIndex].pointBackgroundColor || this.options.pointBackgroundColor,
|
||||
tension: this.data.datasets[datasetIndex].metaDataset.tension,
|
||||
_datasetIndex: datasetIndex,
|
||||
_index: index,
|
||||
});
|
||||
}, this);
|
||||
|
||||
// Update control points for the bezier curve
|
||||
this.eachElement(function(point, index, dataset, datasetIndex) {
|
||||
var controlPoints = helpers.splineCurve(
|
||||
this.previousPoint(dataset, index),
|
||||
point,
|
||||
this.nextPoint(dataset, index),
|
||||
point.tension
|
||||
);
|
||||
|
||||
point.controlPointPreviousX = controlPoints.previous.x;
|
||||
point.controlPointNextX = controlPoints.next.x;
|
||||
|
||||
// Prevent the bezier going outside of the bounds of the graph
|
||||
|
||||
// Cap puter bezier handles to the upper/lower scale bounds
|
||||
if (controlPoints.next.y > this.chartArea.bottom) {
|
||||
point.controlPointNextY = this.chartArea.bottom;
|
||||
} else if (controlPoints.next.y < this.chartArea.top) {
|
||||
point.controlPointNextY = this.chartArea.top;
|
||||
} else {
|
||||
point.controlPointNextY = controlPoints.next.y;
|
||||
}
|
||||
|
||||
// Cap inner bezier handles to the upper/lower scale bounds
|
||||
if (controlPoints.previous.y > this.chartArea.bottom) {
|
||||
point.controlPointPreviousY = this.chartArea.bottom;
|
||||
} else if (controlPoints.previous.y < this.chartArea.top) {
|
||||
point.controlPointPreviousY = this.chartArea.top;
|
||||
} else {
|
||||
point.controlPointPreviousY = controlPoints.previous.y;
|
||||
}
|
||||
// Now pivot the point for animation
|
||||
point.pivot();
|
||||
}, this);
|
||||
|
||||
this.render();
|
||||
},
|
||||
buildScale: function(labels) {
|
||||
var self = this;
|
||||
|
||||
var dataTotal = function() {
|
||||
var values = [];
|
||||
self.eachValue(function(value) {
|
||||
values.push(value);
|
||||
});
|
||||
|
||||
return values;
|
||||
};
|
||||
|
||||
var XScaleClass = Chart.scales.getScaleConstructor("linear");
|
||||
var YScaleClass = Chart.scales.getScaleConstructor("linear");
|
||||
|
||||
this.xScale = new XScaleClass({
|
||||
ctx: this.chart.ctx,
|
||||
});
|
||||
|
||||
// Eventually this will be referenced from the user supplied config options.
|
||||
this.xScale.options = {
|
||||
scaleType: "dataset", // default options are 'dataset', 'linear'.
|
||||
show: true,
|
||||
position: "bottom",
|
||||
horizontal: true,
|
||||
|
||||
// grid line settings
|
||||
gridLines: {
|
||||
show: true,
|
||||
color: "rgba(0, 0, 0, 0.05)",
|
||||
lineWidth: 1,
|
||||
drawOnChartArea: true,
|
||||
},
|
||||
|
||||
// scale numbers
|
||||
beginAtZero: false,
|
||||
integersOnly: false,
|
||||
override: null,
|
||||
|
||||
// label settings
|
||||
labels: {
|
||||
show: true,
|
||||
template: "<%=value%>",
|
||||
fontSize: 12,
|
||||
fontStyle: "normal",
|
||||
fontColor: "#666",
|
||||
fontFamily: "Helvetica Neue",
|
||||
},
|
||||
};
|
||||
this.yScale = new YScaleClass({
|
||||
ctx: this.chart.ctx,
|
||||
});
|
||||
this.yScale.options = {
|
||||
scaleType: "linear", // only linear but allow scale type registration. This allows extensions to exist solely for log scale for instance
|
||||
show: true,
|
||||
position: "left",
|
||||
horizontal: false,
|
||||
|
||||
// grid line settings
|
||||
gridLines: {
|
||||
show: true,
|
||||
color: "rgba(0, 0, 0, 0.05)",
|
||||
lineWidth: 1,
|
||||
drawOnChartArea: true,
|
||||
},
|
||||
|
||||
// scale numbers
|
||||
beginAtZero: false,
|
||||
integersOnly: false,
|
||||
override: null,
|
||||
|
||||
// label settings
|
||||
labels: {
|
||||
show: true,
|
||||
template: "<%=value%>",
|
||||
fontSize: 12,
|
||||
fontStyle: "normal",
|
||||
fontColor: "#666",
|
||||
fontFamily: "Helvetica Neue",
|
||||
},
|
||||
};
|
||||
|
||||
this.xScale.calculateRange = function() {
|
||||
this.min = null;
|
||||
this.max = null;
|
||||
|
||||
helpers.each(self.data.datasets, function(dataset) {
|
||||
helpers.each(dataset.data, function(value) {
|
||||
if (this.min === null) {
|
||||
this.min = value.x;
|
||||
} else if (value.x < this.min) {
|
||||
this.min = value.x;
|
||||
}
|
||||
|
||||
if (this.max === null) {
|
||||
this.max = value.x;
|
||||
} else if (value.x > this.max) {
|
||||
this.max = value.x;
|
||||
}
|
||||
}, this);
|
||||
}, this);
|
||||
};
|
||||
|
||||
this.yScale.calculateRange = function() {
|
||||
this.min = null;
|
||||
this.max = null;
|
||||
|
||||
helpers.each(self.data.datasets, function(dataset) {
|
||||
helpers.each(dataset.data, function(value) {
|
||||
if (this.min === null) {
|
||||
this.min = value.y;
|
||||
} else if (value.y < this.min) {
|
||||
this.min = value.y;
|
||||
}
|
||||
|
||||
if (this.max === null) {
|
||||
this.max = value.y;
|
||||
} else if (value.y > this.max) {
|
||||
this.max = value.y;
|
||||
}
|
||||
}, this);
|
||||
}, this);
|
||||
};
|
||||
|
||||
// Register the axes with the scale service
|
||||
Chart.scaleService.registerChartScale(this, this.xScale);
|
||||
Chart.scaleService.registerChartScale(this, this.yScale);
|
||||
},
|
||||
redraw: function() {
|
||||
|
||||
},
|
||||
draw: function(ease) {
|
||||
|
||||
var easingDecimal = ease || 1;
|
||||
this.clear();
|
||||
|
||||
var chartScaleWrapper = Chart.scaleService.getWrapperForChart(this);
|
||||
|
||||
// Draw all the scales
|
||||
helpers.each(chartScaleWrapper.scales, function(scale) {
|
||||
scale.draw(this.chartArea);
|
||||
}, this);
|
||||
|
||||
this.eachDataset(function(dataset, datasetIndex) {
|
||||
// Transition Point Locations
|
||||
helpers.each(dataset.metaData, function(point, index) {
|
||||
point.transition(easingDecimal);
|
||||
}, this);
|
||||
|
||||
// Transition and Draw the line
|
||||
dataset.metaDataset.transition(easingDecimal).draw();
|
||||
|
||||
// Draw the points
|
||||
helpers.each(dataset.metaData, function(point) {
|
||||
point.draw();
|
||||
});
|
||||
}, this);
|
||||
|
||||
// Finally draw the tooltip
|
||||
this.tooltip.transition(easingDecimal).draw();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}).call(this);
|
Loading…
Reference in New Issue
Block a user