first commit

This commit is contained in:
aschwarz
2023-04-26 13:17:21 +02:00
commit 535741001e
1612 changed files with 820287 additions and 0 deletions

12
chart/zoom/.gitignore vendored Executable file
View File

@ -0,0 +1,12 @@
.DS_Store
node_modules/*
custom/*
docs/index.md
bower_components/
coverage/*
nbproject/*

25
chart/zoom/.travis.yml Executable file
View File

@ -0,0 +1,25 @@
language: node_js
node_js:
- "6.2"
before_install:
- "export CHROME_BIN=/usr/bin/google-chrome"
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
before_script:
- npm install
script:
- gulp jshint
sudo: required
dist: trusty
addons:
firefox: latest
apt:
sources:
- google-chrome
packages:
- google-chrome-stable

64
chart/zoom/CONTRIBUTING.md Executable file
View File

@ -0,0 +1,64 @@
Contributing to Chart.js
========================
Contributions to Chart.js are welcome and encouraged, but please have a look through the guidelines in this document before raising an issue, or writing code for the project.
Using issues
------------
The [issue tracker](https://github.com/chartjs/Chart.js/issues) is the preferred channel for reporting bugs, requesting new features and submitting pull requests.
If you're suggesting a new chart type, please take a look at [writing new chart types](https://github.com/chartjs/Chart.js/blob/master/docs/07-Advanced.md#writing-new-chart-types) in the documentation or consider [creating a plugin](https://github.com/chartjs/Chart.js/blob/master/docs/07-Advanced.md#creating-plugins).
To keep the library lightweight for everyone, it's unlikely we'll add many more chart types to the core of Chart.js, but issues are a good medium to design and spec out how new chart types could work and look.
Please do not use issues for support requests. For help using Chart.js, please take a look at the [`chartjs`](https://stackoverflow.com/questions/tagged/chartjs) tag on Stack Overflow.
Reporting bugs
--------------
Well structured, detailed bug reports are hugely valuable for the project.
Guidlines for reporting bugs:
- Check the issue search to see if it has already been reported
- Isolate the problem to a simple test case
- Provide a demonstration of the problem on [JS Bin](https://jsbin.com) or similar
Please provide any additional details associated with the bug, if it's browser or screen density specific, or only happens with a certain configuration or data.
Local development
-----------------
Run `npm install` to install all the libraries, then run `gulp dev --test` to build and run tests as you make changes.
Pull requests
-------------
Clear, concise pull requests are excellent at continuing the project's community driven growth. But please review [these guidelines](https://github.com/blog/1943-how-to-write-the-perfect-pull-request) and the guidelines below before starting work on the project.
Be advised that **Chart.js 1.0.2 is in feature-complete status**. Pull requests adding new features to the 1.x branch will be disregarded.
Guidelines:
- Please create an issue first:
- For bugs, we can discuss the fixing approach
- For enhancements, we can discuss if it is within the project scope and avoid duplicate effort
- Please make changes to the files in [`/src`](https://github.com/chartjs/Chart.js/tree/master/src), not `Chart.js` or `Chart.min.js` in the repo root directory, this avoids merge conflicts
- Tabs for indentation, not spaces please
- If adding new functionality, please also update the relevant `.md` file in [`/docs`](https://github.com/chartjs/Chart.js/tree/master/docs)
- Please make your commits in logical sections with clear commit messages
Joining the project
-------------
- Active committers and contributors are invited to introduce yourself and request commit access to this project. Please send an email to hello@nickdownie.com or file an issue.
- We have a very active Slack community that you can join at https://chartjs-slack-automation.herokuapp.com. If you think you can help, we'd love to have you!
License
-------
By contributing your code, you agree to license your contribution under the [MIT license](https://github.com/chartjs/Chart.js/blob/master/LICENSE.md).

8
chart/zoom/LICENSE.md Executable file
View File

@ -0,0 +1,8 @@
The MIT License (MIT)
Copyright (c) 2013-2016 Nick Downie
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

69
chart/zoom/README.md Executable file
View File

@ -0,0 +1,69 @@
# chartjs-plugin-zoom
A zoom and pan plugin for Chart.js >= 2.1.0
Panning can be done via the mouse or with a finger.
Zooming is done via the mouse wheel or via a pinch gesture. [Hammer JS](https://hammerjs.github.io/) is used for gesture recognition.
[Live Codepen Demo](https://codepen.io/pen/PGabEK)
## Configuration
To configure the zoom and pan plugin, you can simply add new config options to your chart config.
```javascript
{
// Container for pan options
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow panning in the y direction
mode: 'xy'
},
// Container for zoom options
zoom: {
// Boolean to enable zooming
enabled: true,
// Zooming directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow zooming in the y direction
mode: 'xy',
}
}
```
## To-do Items
The following features still need to be done:
* Pan limits. We should be able to set limits for all axes or for a single axis, identified by ID, that are the maximum and minimum values, in data values, that can be panned to.
* Zoom limits. Similar to pan limits but for zooming
* Panning of category scales (the ones that use strings as labels)
* Zooming of category scales (the ones that use strings as labels)
## Installation
To download a zip, go to the chartjs-plugin-zoom.js on Github
To install via npm / bower:
```bash
npm install chartjs-plugin-zoom --save
```
Prior to v0.4.0, this plugin was known as 'Chart.Zoom.js'. Old versions are still available on npm under that name.
## Documentation
You can find documentation for Chart.js at [www.chartjs.org/docs](https://www.chartjs.org/docs).
Examples for this plugin are available in the [samples folder](samples).
## Contributing
Before submitting an issue or a pull request to the project, please take a moment to look over the [contributing guidelines](https://github.com/chartjs/chartjs-plugin-zoom.js/blob/master/CONTRIBUTING.md) first.
## License
chartjs-plugin-zoom.js is available under the [MIT license](https://opensource.org/licenses/MIT).

Binary file not shown.

502
chart/zoom/chartjs-plugin-zoom.js Executable file
View File

@ -0,0 +1,502 @@
/*!
* chartjs-plugin-zoom
* https://chartjs.org/
* Version: 0.4.5
*
* Copyright 2016 Evert Timberg
* Released under the MIT license
* https://github.com/chartjs/chartjs-plugin-zoom/blob/master/LICENSE.md
*/
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
/*jslint browser:true, devel:true, white:true, vars:true */
/*global require*/
// hammer JS for touch support
var Hammer = require('hammerjs');
Hammer = typeof(Hammer) === 'function' ? Hammer : window.Hammer;
// Get the chart variable
var Chart = require('chart.js');
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
var helpers = Chart.helpers;
// Take the zoom namespace of Chart
var zoomNS = Chart.Zoom = Chart.Zoom || {};
// Where we store functions to handle different scale types
var zoomFunctions = zoomNS.zoomFunctions = zoomNS.zoomFunctions || {};
var panFunctions = zoomNS.panFunctions = zoomNS.panFunctions || {};
// Default options if none are provided
var defaultOptions = zoomNS.defaults = {
pan: {
enabled: true,
mode: 'xy',
speed: 20,
threshold: 10,
},
zoom: {
enabled: true,
mode: 'xy',
sensitivity: 3,
}
};
function directionEnabled(mode, dir) {
if (mode === undefined) {
return true;
} else if (typeof mode === 'string') {
return mode.indexOf(dir) !== -1;
}
return false;
}
function zoomIndexScale(scale, zoom, center, zoomOptions) {
var labels = scale.chart.data.labels;
var minIndex = scale.minIndex;
var lastLabelIndex = labels.length - 1;
var maxIndex = scale.maxIndex;
var sensitivity = zoomOptions.sensitivity;
var chartCenter = scale.isHorizontal() ? scale.left + (scale.width/2) : scale.top + (scale.height/2);
var centerPointer = scale.isHorizontal() ? center.x : center.y;
zoomNS.zoomCumulativeDelta = zoom > 1 ? zoomNS.zoomCumulativeDelta + 1 : zoomNS.zoomCumulativeDelta - 1;
if (Math.abs(zoomNS.zoomCumulativeDelta) > sensitivity){
if(zoomNS.zoomCumulativeDelta < 0){
if(centerPointer <= chartCenter){
if (minIndex <= 0){
maxIndex = Math.min(lastLabelIndex, maxIndex + 1);
} else{
minIndex = Math.max(0, minIndex - 1);
}
} else if(centerPointer > chartCenter){
if (maxIndex >= lastLabelIndex){
minIndex = Math.max(0, minIndex - 1);
} else{
maxIndex = Math.min(lastLabelIndex, maxIndex + 1);
}
}
zoomNS.zoomCumulativeDelta = 0;
}
else if(zoomNS.zoomCumulativeDelta > 0){
if(centerPointer <= chartCenter){
minIndex = minIndex < maxIndex ? minIndex = Math.min(maxIndex, minIndex + 1) : minIndex;
} else if(centerPointer > chartCenter){
maxIndex = maxIndex > minIndex ? maxIndex = Math.max(minIndex, maxIndex - 1) : maxIndex;
}
zoomNS.zoomCumulativeDelta = 0;
}
scale.options.ticks.min = labels[minIndex];
scale.options.ticks.max = labels[maxIndex];
}
}
function zoomTimeScale(scale, zoom, center) {
var options = scale.options;
var range;
var min_percent;
if (scale.isHorizontal()) {
range = scale.right - scale.left;
min_percent = (center.x - scale.left) / range;
} else {
range = scale.bottom - scale.top;
min_percent = (center.y - scale.top) / range;
}
var max_percent = 1 - min_percent;
var newDiff = range * (zoom - 1);
var minDelta = newDiff * min_percent;
var maxDelta = newDiff * max_percent;
options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) + minDelta);
options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - maxDelta);
}
function zoomNumericalScale(scale, zoom, center) {
var range = scale.max - scale.min;
var newDiff = range * (zoom - 1);
var cursorPixel = scale.isHorizontal() ? center.x : center.y;
var min_percent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
var max_percent = 1 - min_percent;
var minDelta = newDiff * min_percent;
var maxDelta = newDiff * max_percent;
scale.options.ticks.min = scale.min + minDelta;
scale.options.ticks.max = scale.max - maxDelta;
}
function zoomScale(scale, zoom, center, zoomOptions) {
var fn = zoomFunctions[scale.options.type];
if (fn) {
fn(scale, zoom, center, zoomOptions);
}
}
function doZoom(chartInstance, zoom, center) {
var ca = chartInstance.chartArea;
if (!center) {
center = {
x: (ca.left + ca.right) / 2,
y: (ca.top + ca.bottom) / 2,
};
}
var zoomOptions = chartInstance.options.zoom;
if (zoomOptions && helpers.getValueOrDefault(zoomOptions.enabled, defaultOptions.zoom.enabled)) {
// Do the zoom here
var zoomMode = helpers.getValueOrDefault(chartInstance.options.zoom.mode, defaultOptions.zoom.mode);
zoomOptions.sensitivity = helpers.getValueOrDefault(chartInstance.options.zoom.sensitivity, defaultOptions.zoom.sensitivity);
helpers.each(chartInstance.scales, function(scale, id) {
if (scale.isHorizontal() && directionEnabled(zoomMode, 'x')) {
zoomScale(scale, zoom, center, zoomOptions);
} else if (!scale.isHorizontal() && directionEnabled(zoomMode, 'y')) {
// Do Y zoom
zoomScale(scale, zoom, center, zoomOptions);
}
});
chartInstance.update(0);
}
}
function panIndexScale(scale, delta, panOptions) {
var labels = scale.chart.data.labels;
var lastLabelIndex = labels.length - 1;
var offsetAmt = Math.max((scale.ticks.length - ((scale.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var panSpeed = panOptions.speed;
var minIndex = scale.minIndex;
var step = Math.round(scale.width / (offsetAmt * panSpeed));
var maxIndex;
zoomNS.panCumulativeDelta += delta;
minIndex = zoomNS.panCumulativeDelta > step ? Math.max(0, minIndex -1) : zoomNS.panCumulativeDelta < -step ? Math.min(lastLabelIndex - offsetAmt + 1, minIndex + 1) : minIndex;
zoomNS.panCumulativeDelta = minIndex !== scale.minIndex ? 0 : zoomNS.panCumulativeDelta;
maxIndex = Math.min(lastLabelIndex, minIndex + offsetAmt - 1);
scale.options.ticks.min = labels[minIndex];
scale.options.ticks.max = labels[maxIndex];
}
function panTimeScale(scale, delta) {
var options = scale.options;
options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) - delta);
options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - delta);
}
function panNumericalScale(scale, delta) {
var tickOpts = scale.options.ticks;
var start = scale.start,
end = scale.end;
if (tickOpts.reverse) {
tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
} else {
tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
}
}
function panScale(scale, delta, panOptions) {
var fn = panFunctions[scale.options.type];
if (fn) {
fn(scale, delta, panOptions);
}
}
function doPan(chartInstance, deltaX, deltaY) {
var panOptions = chartInstance.options.pan;
if (panOptions && helpers.getValueOrDefault(panOptions.enabled, defaultOptions.pan.enabled)) {
var panMode = helpers.getValueOrDefault(chartInstance.options.pan.mode, defaultOptions.pan.mode);
panOptions.speed = helpers.getValueOrDefault(chartInstance.options.pan.speed, defaultOptions.pan.speed);
helpers.each(chartInstance.scales, function(scale, id) {
if (scale.isHorizontal() && directionEnabled(panMode, 'x') && deltaX !== 0) {
panScale(scale, deltaX, panOptions);
} else if (!scale.isHorizontal() && directionEnabled(panMode, 'y') && deltaY !== 0) {
panScale(scale, deltaY, panOptions);
}
});
chartInstance.update(0);
}
}
function positionInChartArea(chartInstance, position) {
return (position.x >= chartInstance.chartArea.left && position.x <= chartInstance.chartArea.right) &&
(position.y >= chartInstance.chartArea.top && position.y <= chartInstance.chartArea.bottom);
}
function getYAxis(chartInstance) {
var scales = chartInstance.scales;
for (var scaleId in scales) {
var scale = scales[scaleId];
if (!scale.isHorizontal()) {
return scale;
}
}
}
// Store these for later
zoomNS.zoomFunctions.category = zoomIndexScale;
zoomNS.zoomFunctions.time = zoomTimeScale;
zoomNS.zoomFunctions.linear = zoomNumericalScale;
zoomNS.zoomFunctions.logarithmic = zoomNumericalScale;
zoomNS.panFunctions.category = panIndexScale;
zoomNS.panFunctions.time = panTimeScale;
zoomNS.panFunctions.linear = panNumericalScale;
zoomNS.panFunctions.logarithmic = panNumericalScale;
// Globals for catergory pan and zoom
zoomNS.panCumulativeDelta = 0;
zoomNS.zoomCumulativeDelta = 0;
// Chartjs Zoom Plugin
var zoomPlugin = {
afterInit: function(chartInstance) {
helpers.each(chartInstance.scales, function(scale) {
scale.originalOptions = JSON.parse(JSON.stringify(scale.options));
});
chartInstance.resetZoom = function() {
helpers.each(chartInstance.scales, function(scale, id) {
var timeOptions = scale.options.time;
var tickOptions = scale.options.ticks;
if (timeOptions) {
delete timeOptions.min;
delete timeOptions.max;
}
if (tickOptions) {
delete tickOptions.min;
delete tickOptions.max;
}
scale.options = helpers.configMerge(scale.options, scale.originalOptions);
});
helpers.each(chartInstance.data.datasets, function(dataset, id) {
dataset._meta = null;
});
chartInstance.update();
};
},
beforeInit: function(chartInstance) {
chartInstance.zoom = {};
var node = chartInstance.zoom.node = chartInstance.chart.ctx.canvas;
var options = chartInstance.options;
var panThreshold = helpers.getValueOrDefault(options.pan ? options.pan.threshold : undefined, zoomNS.defaults.pan.threshold);
if (options.zoom && options.zoom.drag) {
// Only want to zoom horizontal axis
options.zoom.mode = 'x';
chartInstance.zoom._mouseDownHandler = function(event) {
chartInstance.zoom._dragZoomStart = event;
};
node.addEventListener('mousedown', chartInstance.zoom._mouseDownHandler);
chartInstance.zoom._mouseMoveHandler = function(event){
if (chartInstance.zoom._dragZoomStart) {
chartInstance.zoom._dragZoomEnd = event;
chartInstance.update(0);
}
chartInstance.update(0);
};
node.addEventListener('mousemove', chartInstance.zoom._mouseMoveHandler);
chartInstance.zoom._mouseUpHandler = function(event){
if (chartInstance.zoom._dragZoomStart) {
var chartArea = chartInstance.chartArea;
var yAxis = getYAxis(chartInstance);
var beginPoint = chartInstance.zoom._dragZoomStart;
var offsetX = beginPoint.target.getBoundingClientRect().left;
var startX = Math.min(beginPoint.clientX, event.clientX) - offsetX;
var endX = Math.max(beginPoint.clientX, event.clientX) - offsetX;
var dragDistance = endX - startX;
var chartDistance = chartArea.right - chartArea.left;
var zoom = 1 + ((chartDistance - dragDistance) / chartDistance );
if (dragDistance > 0) {
doZoom(chartInstance, zoom, {
x: (dragDistance / 2) + startX,
y: (yAxis.bottom - yAxis.top) / 2,
});
}
chartInstance.zoom._dragZoomStart = null;
chartInstance.zoom._dragZoomEnd = null;
}
};
node.addEventListener('mouseup', chartInstance.zoom._mouseUpHandler);
} else {
chartInstance.zoom._wheelHandler = function(event) {
var rect = event.target.getBoundingClientRect();
var offsetX = event.clientX - rect.left;
var offsetY = event.clientY - rect.top;
var center = {
x : offsetX,
y : offsetY
};
if (event.deltaY < 0) {
doZoom(chartInstance, 1.1, center);
} else {
doZoom(chartInstance, 0.909, center);
}
// Prevent the event from triggering the default behavior (eg. Content scrolling).
event.preventDefault();
};
node.addEventListener('wheel', chartInstance.zoom._wheelHandler);
}
if (Hammer) {
var mc = new Hammer.Manager(node);
mc.add(new Hammer.Pinch());
mc.add(new Hammer.Pan({
threshold: panThreshold
}));
// Hammer reports the total scaling. We need the incremental amount
var currentPinchScaling;
var handlePinch = function handlePinch(e) {
var diff = 1 / (currentPinchScaling) * e.scale;
doZoom(chartInstance, diff, e.center);
// Keep track of overall scale
currentPinchScaling = e.scale;
};
mc.on('pinchstart', function(e) {
currentPinchScaling = 1; // reset tracker
});
mc.on('pinch', handlePinch);
mc.on('pinchend', function(e) {
handlePinch(e);
currentPinchScaling = null; // reset
zoomNS.zoomCumulativeDelta = 0;
});
var currentDeltaX = null, currentDeltaY = null, panning = false;
var handlePan = function handlePan(e) {
if (currentDeltaX !== null && currentDeltaY !== null) {
panning = true;
var deltaX = e.deltaX - currentDeltaX;
var deltaY = e.deltaY - currentDeltaY;
currentDeltaX = e.deltaX;
currentDeltaY = e.deltaY;
doPan(chartInstance, deltaX, deltaY);
}
};
mc.on('panstart', function(e) {
currentDeltaX = 0;
currentDeltaY = 0;
handlePan(e);
});
mc.on('panmove', handlePan);
mc.on('panend', function(e) {
currentDeltaX = null;
currentDeltaY = null;
zoomNS.panCumulativeDelta = 0;
setTimeout(function() { panning = false; }, 500);
});
chartInstance.zoom._ghostClickHandler = function(e) {
if (panning) {
e.stopImmediatePropagation();
e.preventDefault();
}
};
node.addEventListener('click', chartInstance.zoom._ghostClickHandler);
chartInstance._mc = mc;
}
},
beforeDatasetsDraw: function(chartInstance) {
var ctx = chartInstance.chart.ctx;
var chartArea = chartInstance.chartArea;
ctx.save();
ctx.beginPath();
if (chartInstance.zoom._dragZoomEnd) {
var yAxis = getYAxis(chartInstance);
var beginPoint = chartInstance.zoom._dragZoomStart;
var endPoint = chartInstance.zoom._dragZoomEnd;
var offsetX = beginPoint.target.getBoundingClientRect().left;
var startX = Math.min(beginPoint.clientX, endPoint.clientX) - offsetX;
var endX = Math.max(beginPoint.clientX, endPoint.clientX) - offsetX;
var rectWidth = endX - startX;
ctx.fillStyle = 'rgba(225,225,225,0.3)';
ctx.lineWidth = 5;
ctx.fillRect(startX, yAxis.top, rectWidth, yAxis.bottom - yAxis.top);
}
ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
ctx.clip();
},
afterDatasetsDraw: function(chartInstance) {
chartInstance.chart.ctx.restore();
},
destroy: function(chartInstance) {
if (chartInstance.zoom) {
var options = chartInstance.options;
var node = chartInstance.zoom.node;
if (options.zoom && options.zoom.drag) {
node.removeEventListener('mousedown', chartInstance.zoom._mouseDownHandler);
node.removeEventListener('mousemove', chartInstance.zoom._mouseMoveHandler);
node.removeEventListener('mouseup', chartInstance.zoom._mouseUpHandler);
} else {
node.removeEventListener('wheel', chartInstance.zoom._wheelHandler);
}
if (Hammer) {
node.removeEventListener('click', chartInstance.zoom._ghostClickHandler);
}
delete chartInstance.zoom;
var mc = chartInstance._mc;
if (mc) {
mc.remove('pinchstart');
mc.remove('pinch');
mc.remove('pinchend');
mc.remove('panstart');
mc.remove('pan');
mc.remove('panend');
}
}
}
};
module.exports = zoomPlugin;
Chart.pluginService.register(zoomPlugin);
},{"chart.js":1,"hammerjs":1}]},{},[2]);

10
chart/zoom/chartjs-plugin-zoom.min.js vendored Executable file

File diff suppressed because one or more lines are too long

4
chart/zoom/config.jshintrc Executable file
View File

@ -0,0 +1,4 @@
{
"node": true,
"predef": [ "require", "module" ]
}

90
chart/zoom/gulpfile.js Executable file
View File

@ -0,0 +1,90 @@
var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
util = require('gulp-util'),
jshint = require('gulp-jshint'),
replace = require('gulp-replace'),
insert = require('gulp-insert'),
inquirer = require('inquirer'),
semver = require('semver'),
exec = require('child_process').exec,
fs = require('fs'),
package = require('./package.json'),
browserify = require('browserify'),
streamify = require('gulp-streamify'),
source = require('vinyl-source-stream'),
merge = require('merge-stream');
var srcDir = './src/';
var outDir = './';
var header = "/*!\n\
* chartjs-plugin-zoom\n\
* https://chartjs.org/\n\
* Version: {{ version }}\n\
*\n\
* Copyright 2016 Evert Timberg\n\
* Released under the MIT license\n\
* https://github.com/chartjs/chartjs-plugin-zoom/blob/master/LICENSE.md\n\
*/\n";
gulp.task('build', buildTask);
gulp.task('bump', bumpTask);
gulp.task('jshint', jshintTask);
function buildTask() {
var nonBundled = browserify('./src/chart.zoom.js')
.ignore('chart.js')
.ignore('hammerjs')
.bundle()
.pipe(source('chartjs-plugin-zoom.js'))
.pipe(insert.prepend(header))
.pipe(streamify(replace('{{ version }}', package.version)))
.pipe(gulp.dest(outDir))
.pipe(streamify(uglify({
preserveComments: 'some'
})))
.pipe(streamify(concat('chartjs-plugin-zoom.min.js')))
.pipe(gulp.dest(outDir));
return nonBundled;
}
/*
* Usage : gulp bump
* Prompts: Version increment to bump
* Output: - New version number written into package.json & bower.json
*/
function bumpTask(complete) {
util.log('Current version:', util.colors.cyan(package.version));
var choices = ['major', 'premajor', 'minor', 'preminor', 'patch', 'prepatch', 'prerelease'].map(function(versionType) {
return versionType + ' (v' + semver.inc(package.version, versionType) + ')';
});
inquirer.prompt({
type: 'list',
name: 'version',
message: 'What version update would you like?',
choices: choices
}, function(res) {
var increment = res.version.split(' ')[0],
newVersion = semver.inc(package.version, increment);
// Set the new versions into the bower/package object
package.version = newVersion;
bower.version = newVersion;
// Write these to their own files, then build the output
fs.writeFileSync('package.json', JSON.stringify(package, null, 2));
fs.writeFileSync('bower.json', JSON.stringify(bower, null, 2));
complete();
});
}
function jshintTask() {
return gulp.src(srcDir + '**/*.js')
.pipe(jshint('config.jshintrc'))
.pipe(jshint.reporter('jshint-stylish'))
.pipe(jshint.reporter('fail'));
}

33
chart/zoom/package.json Executable file
View File

@ -0,0 +1,33 @@
{
"name": "chartjs-plugin-zoom",
"description": "Simple HTML5 charts using the canvas element.",
"version": "0.4.5",
"author": "Evert Timberg <evert.timberg@gmail.com>",
"license": "MIT",
"main": "src/chart.zoom.js",
"repository": {
"type": "git",
"url": "https://github.com/chartjs/chartjs-plugin-zoom.git"
},
"devDependencies": {
"browserify": "^13.0.0",
"gulp": "3.9.x",
"gulp-concat": "^2.6.0",
"gulp-insert": "^0.5.0",
"gulp-jshint": "^2.0.0",
"gulp-replace": "^0.5.4",
"gulp-streamify": "^1.0.2",
"gulp-uglify": "^1.5.3",
"gulp-util": "^3.0.7",
"inquirer": "^1.0.2",
"jshint": "^2.9.2",
"jshint-stylish": "^2.2.0",
"merge-stream": "^1.0.0",
"semver": "^5.1.0",
"vinyl-source-stream": "^1.1.0"
},
"dependencies": {
"chart.js": "^2.1.5",
"hammerjs": "^2.0.8"
}
}

109
chart/zoom/samples/pan-bar.html Executable file
View File

@ -0,0 +1,109 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Pan</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'xy',
speed: 10,
threshold: 10
},
zoom: {
enabled: true,
mode: 'y',
limits: {
max: 10,
min: 0.5
}
},
scales: {
xAxes: [{
ticks: {
min: 'March',
max: 'May'
}
}]
}
}
});
};
</script>
</body>
</html>

View File

@ -0,0 +1,108 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Zoom</title>
<script src="../../Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January-16", "February-16", "March-16", "April-16", "May-16", "June-16", "July-16", "August-16", "September-16", "October-16", "November-16", "December-16", "January-17", "February-17", "March-17", "April-17", "May-17", "June-17", "July-17", "August-17", "September-17", "October-17", "November-17", "December-17"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'xy' // is panning about the y axis neccessary for bar charts?
},
zoom: {
enabled: true,
mode: 'x',
sensitivity: 3,
limits: {
max: 10,
min: 0.5
}
},
scales: {
xAxes: [{
ticks: {
min: 'February-16',
max: 'June-16'
}
}]
}
}
});
};
</script>
</body>
</html>

View File

@ -0,0 +1,108 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Zoom</title>
<script src="../../Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January-16", "February-16", "March-16", "April-16", "May-16", "June-16", "July-16", "August-16", "September-16", "October-16", "November-16", "December-16", "January-17", "February-17", "March-17", "April-17", "May-17", "June-17", "July-17", "August-17", "September-17", "October-17", "November-17", "December-17"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'xy' // is panning about the y axis neccessary for bar charts?
},
zoom: {
enabled: true,
mode: 'x',
sensitivity: 3,
limits: {
max: 10,
min: 0.5
}
},
scales: {
xAxes: [{
ticks: {
min: 'February-16',
max: 'June-16'
}
}]
}
}
});
};
</script>
</body>
</html>

View File

@ -0,0 +1,100 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Zoom</title>
<script src="../../Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January-16", "February-16", "March-16", "April-16", "May-16", "June-16", "July-16", "August-16", "September-16", "October-16", "November-16", "December-16", "January-17", "February-17", "March-17", "April-17", "May-17", "June-17", "July-17", "August-17", "September-17", "October-17", "November-17", "December-17"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'xy' // is panning about the y axis neccessary for bar charts?
},
zoom: {
enabled: true,
mode: 'x',
sensitivity: 3,
limits: {
max: 10,
min: 0.5
}
}
}
});
};
</script>
</body>
</html>

107
chart/zoom/samples/zoom-bar.html Executable file
View File

@ -0,0 +1,107 @@
<!doctype html>
<html>
<head>
<title>Bar Chart Zoom</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'y'
},
zoom: {
enabled: true,
mode: 'y',
limits: {
max: 10,
min: 0.5
}
},
scales: {
xAxes: [{
ticks: {
min: 'February',
max: 'June'
}
}]
}
}
});
};
</script>
</body>
</html>

View File

@ -0,0 +1,101 @@
<!doctype html>
<html>
<head>
<title>Horizontal Bar Chart Zoom</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div id="container" style="width: 75%;">
<canvas id="canvas"></canvas>
</div>
<script>
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var randomScalingFactor = function() {
return (Math.random() > 0.5 ? 1.0 : -1.0) * Math.round(Math.random() * 100);
};
var randomColorFactor = function() {
return Math.round(Math.random() * 255);
};
var randomColor = function() {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',.7)';
};
var barChartData = {
labels: ["January-16", "February-16", "March-16", "April-16", "May-16", "June-16", "July-16", "August-16", "September-16", "October-16", "November-16", "December-16", "January-17", "February-17", "March-17", "April-17", "May-17", "June-17", "July-17", "August-17", "September-17", "October-17", "November-17", "December-17"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
hidden: false,
label: 'Dataset 2',
backgroundColor: "rgba(255,187,205,1)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}, {
label: 'Dataset 3',
backgroundColor: "rgba(151,187,205,0.5)",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()]
}]
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'horizontalBar',
data: barChartData,
options: {
// Elements options apply to all of the options unless overridden in a dataset
// In this case, we are setting the border of each bar to be 2px wide and green
elements: {
rectangle: {
borderWidth: 2,
borderColor: 'rgb(0, 255, 0)',
borderSkipped: 'bottom'
}
},
responsive: true,
legend: {
position: 'top',
},
title: {
display: true,
text: 'Chart.js Bar Chart'
},
pan: {
enabled: true,
mode: 'y'
},
zoom: {
enabled: true,
mode: 'xy'
},
scales: {
yAxes: [{
ticks: {
min: 'April-16',
max: 'August-16'
}
}]
}
}
});
};
</script>
</body>
</html>

207
chart/zoom/samples/zoom-log.html Executable file
View File

@ -0,0 +1,207 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../node_modules/chart.js/dist/Chart.bundle.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<div>
<canvas id="canvas"></canvas>
</div>
</div>
<script>
var randomScalingFactor = function() {
return Math.round(Math.random() * 10.0) * Math.pow(10, Math.ceil(Math.random() * 5));
};
var randomColor = function(opacity) {
return 'rgba(' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + Math.round(Math.random() * 255) + ',' + (opacity || '.3') + ')';
};
var scatterChartData = {
datasets: [{
label: "V(node2)",
data: [{
x: 1,
y: -1.711e-2,
}, {
x: 1.26,
y: -2.708e-2,
}, {
x: 1.58,
y: -4.285e-2,
}, {
x: 2.0,
y: -6.772e-2,
}, {
x: 2.51,
y: -1.068e-1,
}, {
x: 3.16,
y: -1.681e-1,
}, {
x: 3.98,
y: -2.635e-1,
}, {
x: 5.01,
y: -4.106e-1,
}, {
x: 6.31,
y: -6.339e-1,
}, {
x: 7.94,
y: -9.659e-1,
}, {
x: 10.00,
y: -1.445,
}, {
x: 12.6,
y: -2.110,
}, {
x: 15.8,
y: -2.992,
}, {
x: 20.0,
y: -4.102,
}, {
x: 25.1,
y: -5.429,
}, {
x: 31.6,
y: -6.944,
}, {
x: 39.8,
y: -8.607,
}, {
x: 50.1,
y: -1.038e1,
}, {
x: 63.1,
y: -1.223e1,
}, {
x: 79.4,
y: -1.413e1,
}, {
x: 100.00,
y: -1.607e1,
}, {
x: 126,
y: -1.803e1,
}, {
x: 158,
y: -2e1,
}, {
x: 200,
y: -2.199e1,
}, {
x: 251,
y: -2.398e1,
}, {
x: 316,
y: -2.597e1,
}, {
x: 398,
y: -2.797e1,
}, {
x: 501,
y: -2.996e1,
}, {
x: 631,
y: -3.196e1,
}, {
x: 794,
y: -3.396e1,
}, {
x: 1000,
y: -3.596e1,
},]
}]
};
scatterChartData.datasets.forEach(function(dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.1);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myScatter = Chart.Scatter(ctx, {
data: scatterChartData,
options: {
title: {
display: true,
text: 'Chart.js Scatter Chart - Logarithmic X-Axis'
},
scales: {
xAxes: [{
type: 'logarithmic',
position: 'bottom',
ticks: {
userCallback: function(tick) {
var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick))));
if (remain === 1 || remain === 2 || remain === 5) {
return tick.toString() + "Hz";
}
return '';
},
maxRotation: 0
},
scaleLabel: {
labelString: 'Frequency',
display: true,
},
}],
yAxes: [{
type: 'linear',
ticks: {
userCallback: function(tick) {
return tick.toFixed(0) + "dB";
}
},
scaleLabel: {
labelString: 'Voltage',
display: true
}
}]
},
pan: {
enabled: true,
mode: 'xy',
limits: {
xmin: 1e-4,
ymin: -50,
ymax: 10
},
xScale0: {
max: 1e4
}
},
zoom: {
enabled: true,
mode: 'xy',
limits: {
max: 10,
min: 0.5
}
}
}
});
};
</script>
</body>
</html>

142
chart/zoom/samples/zoom-time.html Executable file
View File

@ -0,0 +1,142 @@
<!doctype html>
<html>
<head>
<title>Line Chart</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>
<script src="../node_modules/chart.js/dist/Chart.js"></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<script src="../chartjs-plugin-zoom.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%;">
<button onclick="resetZoom()">Reset Zoom</button>
<canvas id="canvas"></canvas>
</div>
<script>
var timeFormat = 'MM/DD/YYYY HH:mm';
function randomScalingFactor() {
return Math.round(Math.random() * 100 * (Math.random() > 0.5 ? -1 : 1));
}
function randomColorFactor() {
return Math.round(Math.random() * 255);
}
function randomColor(opacity) {
return 'rgba(' + randomColorFactor() + ',' + randomColorFactor() + ',' + randomColorFactor() + ',' + (opacity || '.3') + ')';
}
function newDate(days) {
return moment().add(days, 'd').toDate();
}
function newDateString(days) {
return moment().add(days, 'd').format(timeFormat);
}
function newTimestamp(days) {
return moment().add(days, 'd').unix();
}
function resetZoom() {
window.myLine.resetZoom()
}
var config = {
type: 'line',
data: {
labels: [newDate(0), newDate(1), newDate(2), newDate(3), newDate(4), newDate(5), newDate(6)], // Date Objects
datasets: [{
label: "My First dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
fill: false,
borderDash: [5, 5],
}, {
label: "My Second dataset",
data: [randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor(), randomScalingFactor()],
}, {
label: "Dataset with point data",
data: [{
x: newDateString(0),
y: randomScalingFactor()
}, {
x: newDateString(5),
y: randomScalingFactor()
}, {
x: newDateString(7),
y: randomScalingFactor()
}, {
x: newDateString(15),
y: randomScalingFactor()
}],
fill: false
}]
},
options: {
responsive: true,
title:{
display:true,
text:"Chart.js Time Scale"
},
scales: {
xAxes: [{
type: "time",
time: {
format: timeFormat,
// round: 'day'
tooltipFormat: 'll HH:mm'
},
scaleLabel: {
display: true,
labelString: 'Date'
},
ticks: {
maxRotation: 0
}
}, ],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'value'
}
}]
},
zoom: {
enabled: true,
drag: true,
mode: 'x',
limits: {
max: 10,
min: 0.5
}
}
}
};
config.data.datasets.forEach(function(dataset) {
dataset.borderColor = randomColor(0.4);
dataset.backgroundColor = randomColor(0.5);
dataset.pointBorderColor = randomColor(0.7);
dataset.pointBackgroundColor = randomColor(0.5);
dataset.pointBorderWidth = 1;
});
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myLine = new Chart(ctx, config);
};
</script>
</body>
</html>

78
chart/zoom/samples/zoom.html Executable file
View File

@ -0,0 +1,78 @@
<!doctype html>
<html>
<head>
<title>Scatter Chart</title>
<script src="../../Chart.bundle.js"></script>
<script src="../../js1.js"></script>
<script src="../../js1.svg"></script>
<script src="../../js2.js"></script>
<script src="../../js3.js"></script>
<script src="../../Chart.Zoom.js"></script>
<script src='../../samples/utils.js'></script>
<script src="../node_modules/hammerjs/hammer.min.js"></script>
<style>
canvas {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
</style>
</head>
<body>
<div style="width:75%">
<div>
<canvas id="myChart"></canvas>
</div>
</div>
<script>var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange","R1ed", "Blu1e", "Yello1w", "Gr1een", "Pu1rple", "Oran1ge"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3,12, 19, 3, 5, 2, 3]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
// Container for pan options
pan: {
// Boolean to enable panning
enabled: true,
// Panning directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow panning in the y direction
mode: 'x'
},
// Container for zoom options
zoom: {
// Boolean to enable zooming
enabled: true,
// Zooming directions. Remove the appropriate direction to disable
// Eg. 'y' would only allow zooming in the y direction
mode: 'x',
}
}
});
<button onclick="window.myScatter.destroy()">Destroy</button>
<button onclick="window.myScatter.destroy(); window.onload()">Reload</button>
</body>
</html>

488
chart/zoom/src/chart.zoom.js Executable file
View File

@ -0,0 +1,488 @@
/*jslint browser:true, devel:true, white:true, vars:true */
/*global require*/
// hammer JS for touch support
var Hammer = require('hammerjs');
Hammer = typeof(Hammer) === 'function' ? Hammer : window.Hammer;
// Get the chart variable
var Chart = require('chart.js');
Chart = typeof(Chart) === 'function' ? Chart : window.Chart;
var helpers = Chart.helpers;
// Take the zoom namespace of Chart
var zoomNS = Chart.Zoom = Chart.Zoom || {};
// Where we store functions to handle different scale types
var zoomFunctions = zoomNS.zoomFunctions = zoomNS.zoomFunctions || {};
var panFunctions = zoomNS.panFunctions = zoomNS.panFunctions || {};
// Default options if none are provided
var defaultOptions = zoomNS.defaults = {
pan: {
enabled: true,
mode: 'xy',
speed: 20,
threshold: 10,
},
zoom: {
enabled: true,
mode: 'xy',
sensitivity: 3,
}
};
function directionEnabled(mode, dir) {
if (mode === undefined) {
return true;
} else if (typeof mode === 'string') {
return mode.indexOf(dir) !== -1;
}
return false;
}
function zoomIndexScale(scale, zoom, center, zoomOptions) {
var labels = scale.chart.data.labels;
var minIndex = scale.minIndex;
var lastLabelIndex = labels.length - 1;
var maxIndex = scale.maxIndex;
var sensitivity = zoomOptions.sensitivity;
var chartCenter = scale.isHorizontal() ? scale.left + (scale.width/2) : scale.top + (scale.height/2);
var centerPointer = scale.isHorizontal() ? center.x : center.y;
zoomNS.zoomCumulativeDelta = zoom > 1 ? zoomNS.zoomCumulativeDelta + 1 : zoomNS.zoomCumulativeDelta - 1;
if (Math.abs(zoomNS.zoomCumulativeDelta) > sensitivity){
if(zoomNS.zoomCumulativeDelta < 0){
if(centerPointer <= chartCenter){
if (minIndex <= 0){
maxIndex = Math.min(lastLabelIndex, maxIndex + 1);
} else{
minIndex = Math.max(0, minIndex - 1);
}
} else if(centerPointer > chartCenter){
if (maxIndex >= lastLabelIndex){
minIndex = Math.max(0, minIndex - 1);
} else{
maxIndex = Math.min(lastLabelIndex, maxIndex + 1);
}
}
zoomNS.zoomCumulativeDelta = 0;
}
else if(zoomNS.zoomCumulativeDelta > 0){
if(centerPointer <= chartCenter){
minIndex = minIndex < maxIndex ? minIndex = Math.min(maxIndex, minIndex + 1) : minIndex;
} else if(centerPointer > chartCenter){
maxIndex = maxIndex > minIndex ? maxIndex = Math.max(minIndex, maxIndex - 1) : maxIndex;
}
zoomNS.zoomCumulativeDelta = 0;
}
scale.options.ticks.min = labels[minIndex];
scale.options.ticks.max = labels[maxIndex];
}
}
function zoomTimeScale(scale, zoom, center) {
var options = scale.options;
var range;
var min_percent;
if (scale.isHorizontal()) {
range = scale.right - scale.left;
min_percent = (center.x - scale.left) / range;
} else {
range = scale.bottom - scale.top;
min_percent = (center.y - scale.top) / range;
}
var max_percent = 1 - min_percent;
var newDiff = range * (zoom - 1);
var minDelta = newDiff * min_percent;
var maxDelta = newDiff * max_percent;
options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) + minDelta);
options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - maxDelta);
}
function zoomNumericalScale(scale, zoom, center) {
var range = scale.max - scale.min;
var newDiff = range * (zoom - 1);
var cursorPixel = scale.isHorizontal() ? center.x : center.y;
var min_percent = (scale.getValueForPixel(cursorPixel) - scale.min) / range;
var max_percent = 1 - min_percent;
var minDelta = newDiff * min_percent;
var maxDelta = newDiff * max_percent;
scale.options.ticks.min = scale.min + minDelta;
scale.options.ticks.max = scale.max - maxDelta;
}
function zoomScale(scale, zoom, center, zoomOptions) {
var fn = zoomFunctions[scale.options.type];
if (fn) {
fn(scale, zoom, center, zoomOptions);
}
}
function doZoom(chartInstance, zoom, center) {
var ca = chartInstance.chartArea;
if (!center) {
center = {
x: (ca.left + ca.right) / 2,
y: (ca.top + ca.bottom) / 2,
};
}
var zoomOptions = chartInstance.options.zoom;
if (zoomOptions && helpers.getValueOrDefault(zoomOptions.enabled, defaultOptions.zoom.enabled)) {
// Do the zoom here
var zoomMode = helpers.getValueOrDefault(chartInstance.options.zoom.mode, defaultOptions.zoom.mode);
zoomOptions.sensitivity = helpers.getValueOrDefault(chartInstance.options.zoom.sensitivity, defaultOptions.zoom.sensitivity);
helpers.each(chartInstance.scales, function(scale, id) {
if (scale.isHorizontal() && directionEnabled(zoomMode, 'x')) {
zoomScale(scale, zoom, center, zoomOptions);
} else if (!scale.isHorizontal() && directionEnabled(zoomMode, 'y')) {
// Do Y zoom
zoomScale(scale, zoom, center, zoomOptions);
}
});
chartInstance.update(0);
}
}
function panIndexScale(scale, delta, panOptions) {
var labels = scale.chart.data.labels;
var lastLabelIndex = labels.length - 1;
var offsetAmt = Math.max((scale.ticks.length - ((scale.options.gridLines.offsetGridLines) ? 0 : 1)), 1);
var panSpeed = panOptions.speed;
var minIndex = scale.minIndex;
var step = Math.round(scale.width / (offsetAmt * panSpeed));
var maxIndex;
zoomNS.panCumulativeDelta += delta;
minIndex = zoomNS.panCumulativeDelta > step ? Math.max(0, minIndex -1) : zoomNS.panCumulativeDelta < -step ? Math.min(lastLabelIndex - offsetAmt + 1, minIndex + 1) : minIndex;
zoomNS.panCumulativeDelta = minIndex !== scale.minIndex ? 0 : zoomNS.panCumulativeDelta;
maxIndex = Math.min(lastLabelIndex, minIndex + offsetAmt - 1);
scale.options.ticks.min = labels[minIndex];
scale.options.ticks.max = labels[maxIndex];
}
function panTimeScale(scale, delta) {
var options = scale.options;
options.time.min = scale.getValueForPixel(scale.getPixelForValue(scale.firstTick) - delta);
options.time.max = scale.getValueForPixel(scale.getPixelForValue(scale.lastTick) - delta);
}
function panNumericalScale(scale, delta) {
var tickOpts = scale.options.ticks;
var start = scale.start,
end = scale.end;
if (tickOpts.reverse) {
tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
} else {
tickOpts.min = scale.getValueForPixel(scale.getPixelForValue(start) - delta);
tickOpts.max = scale.getValueForPixel(scale.getPixelForValue(end) - delta);
}
}
function panScale(scale, delta, panOptions) {
var fn = panFunctions[scale.options.type];
if (fn) {
fn(scale, delta, panOptions);
}
}
function doPan(chartInstance, deltaX, deltaY) {
var panOptions = chartInstance.options.pan;
if (panOptions && helpers.getValueOrDefault(panOptions.enabled, defaultOptions.pan.enabled)) {
var panMode = helpers.getValueOrDefault(chartInstance.options.pan.mode, defaultOptions.pan.mode);
panOptions.speed = helpers.getValueOrDefault(chartInstance.options.pan.speed, defaultOptions.pan.speed);
helpers.each(chartInstance.scales, function(scale, id) {
if (scale.isHorizontal() && directionEnabled(panMode, 'x') && deltaX !== 0) {
panScale(scale, deltaX, panOptions);
} else if (!scale.isHorizontal() && directionEnabled(panMode, 'y') && deltaY !== 0) {
panScale(scale, deltaY, panOptions);
}
});
chartInstance.update(0);
}
}
function positionInChartArea(chartInstance, position) {
return (position.x >= chartInstance.chartArea.left && position.x <= chartInstance.chartArea.right) &&
(position.y >= chartInstance.chartArea.top && position.y <= chartInstance.chartArea.bottom);
}
function getYAxis(chartInstance) {
var scales = chartInstance.scales;
for (var scaleId in scales) {
var scale = scales[scaleId];
if (!scale.isHorizontal()) {
return scale;
}
}
}
// Store these for later
zoomNS.zoomFunctions.category = zoomIndexScale;
zoomNS.zoomFunctions.time = zoomTimeScale;
zoomNS.zoomFunctions.linear = zoomNumericalScale;
zoomNS.zoomFunctions.logarithmic = zoomNumericalScale;
zoomNS.panFunctions.category = panIndexScale;
zoomNS.panFunctions.time = panTimeScale;
zoomNS.panFunctions.linear = panNumericalScale;
zoomNS.panFunctions.logarithmic = panNumericalScale;
// Globals for catergory pan and zoom
zoomNS.panCumulativeDelta = 0;
zoomNS.zoomCumulativeDelta = 0;
// Chartjs Zoom Plugin
var zoomPlugin = {
afterInit: function(chartInstance) {
helpers.each(chartInstance.scales, function(scale) {
scale.originalOptions = JSON.parse(JSON.stringify(scale.options));
});
chartInstance.resetZoom = function() {
helpers.each(chartInstance.scales, function(scale, id) {
var timeOptions = scale.options.time;
var tickOptions = scale.options.ticks;
if (timeOptions) {
delete timeOptions.min;
delete timeOptions.max;
}
if (tickOptions) {
delete tickOptions.min;
delete tickOptions.max;
}
scale.options = helpers.configMerge(scale.options, scale.originalOptions);
});
helpers.each(chartInstance.data.datasets, function(dataset, id) {
dataset._meta = null;
});
chartInstance.update();
};
},
beforeInit: function(chartInstance) {
chartInstance.zoom = {};
var node = chartInstance.zoom.node = chartInstance.chart.ctx.canvas;
var options = chartInstance.options;
var panThreshold = helpers.getValueOrDefault(options.pan ? options.pan.threshold : undefined, zoomNS.defaults.pan.threshold);
if (options.zoom && options.zoom.drag) {
// Only want to zoom horizontal axis
options.zoom.mode = 'x';
chartInstance.zoom._mouseDownHandler = function(event) {
chartInstance.zoom._dragZoomStart = event;
};
node.addEventListener('mousedown', chartInstance.zoom._mouseDownHandler);
chartInstance.zoom._mouseMoveHandler = function(event){
if (chartInstance.zoom._dragZoomStart) {
chartInstance.zoom._dragZoomEnd = event;
chartInstance.update(0);
}
chartInstance.update(0);
};
node.addEventListener('mousemove', chartInstance.zoom._mouseMoveHandler);
chartInstance.zoom._mouseUpHandler = function(event){
if (chartInstance.zoom._dragZoomStart) {
var chartArea = chartInstance.chartArea;
var yAxis = getYAxis(chartInstance);
var beginPoint = chartInstance.zoom._dragZoomStart;
var offsetX = beginPoint.target.getBoundingClientRect().left;
var startX = Math.min(beginPoint.clientX, event.clientX) - offsetX;
var endX = Math.max(beginPoint.clientX, event.clientX) - offsetX;
var dragDistance = endX - startX;
var chartDistance = chartArea.right - chartArea.left;
var zoom = 1 + ((chartDistance - dragDistance) / chartDistance );
if (dragDistance > 0) {
doZoom(chartInstance, zoom, {
x: (dragDistance / 2) + startX,
y: (yAxis.bottom - yAxis.top) / 2,
});
}
chartInstance.zoom._dragZoomStart = null;
chartInstance.zoom._dragZoomEnd = null;
}
};
node.addEventListener('mouseup', chartInstance.zoom._mouseUpHandler);
} else {
chartInstance.zoom._wheelHandler = function(event) {
var rect = event.target.getBoundingClientRect();
var offsetX = event.clientX - rect.left;
var offsetY = event.clientY - rect.top;
var center = {
x : offsetX,
y : offsetY
};
if (event.deltaY < 0) {
doZoom(chartInstance, 1.1, center);
} else {
doZoom(chartInstance, 0.909, center);
}
// Prevent the event from triggering the default behavior (eg. Content scrolling).
event.preventDefault();
};
node.addEventListener('wheel', chartInstance.zoom._wheelHandler);
}
if (Hammer) {
var mc = new Hammer.Manager(node);
mc.add(new Hammer.Pinch());
mc.add(new Hammer.Pan({
threshold: panThreshold
}));
// Hammer reports the total scaling. We need the incremental amount
var currentPinchScaling;
var handlePinch = function handlePinch(e) {
var diff = 1 / (currentPinchScaling) * e.scale;
doZoom(chartInstance, diff, e.center);
// Keep track of overall scale
currentPinchScaling = e.scale;
};
mc.on('pinchstart', function(e) {
currentPinchScaling = 1; // reset tracker
});
mc.on('pinch', handlePinch);
mc.on('pinchend', function(e) {
handlePinch(e);
currentPinchScaling = null; // reset
zoomNS.zoomCumulativeDelta = 0;
});
var currentDeltaX = null, currentDeltaY = null, panning = false;
var handlePan = function handlePan(e) {
if (currentDeltaX !== null && currentDeltaY !== null) {
panning = true;
var deltaX = e.deltaX - currentDeltaX;
var deltaY = e.deltaY - currentDeltaY;
currentDeltaX = e.deltaX;
currentDeltaY = e.deltaY;
doPan(chartInstance, deltaX, deltaY);
}
};
mc.on('panstart', function(e) {
currentDeltaX = 0;
currentDeltaY = 0;
handlePan(e);
});
mc.on('panmove', handlePan);
mc.on('panend', function(e) {
currentDeltaX = null;
currentDeltaY = null;
zoomNS.panCumulativeDelta = 0;
setTimeout(function() { panning = false; }, 500);
});
chartInstance.zoom._ghostClickHandler = function(e) {
if (panning) {
e.stopImmediatePropagation();
e.preventDefault();
}
};
node.addEventListener('click', chartInstance.zoom._ghostClickHandler);
chartInstance._mc = mc;
}
},
beforeDatasetsDraw: function(chartInstance) {
var ctx = chartInstance.chart.ctx;
var chartArea = chartInstance.chartArea;
ctx.save();
ctx.beginPath();
if (chartInstance.zoom._dragZoomEnd) {
var yAxis = getYAxis(chartInstance);
var beginPoint = chartInstance.zoom._dragZoomStart;
var endPoint = chartInstance.zoom._dragZoomEnd;
var offsetX = beginPoint.target.getBoundingClientRect().left;
var startX = Math.min(beginPoint.clientX, endPoint.clientX) - offsetX;
var endX = Math.max(beginPoint.clientX, endPoint.clientX) - offsetX;
var rectWidth = endX - startX;
ctx.fillStyle = 'rgba(225,225,225,0.3)';
ctx.lineWidth = 5;
ctx.fillRect(startX, yAxis.top, rectWidth, yAxis.bottom - yAxis.top);
}
ctx.rect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
ctx.clip();
},
afterDatasetsDraw: function(chartInstance) {
chartInstance.chart.ctx.restore();
},
destroy: function(chartInstance) {
if (chartInstance.zoom) {
var options = chartInstance.options;
var node = chartInstance.zoom.node;
if (options.zoom && options.zoom.drag) {
node.removeEventListener('mousedown', chartInstance.zoom._mouseDownHandler);
node.removeEventListener('mousemove', chartInstance.zoom._mouseMoveHandler);
node.removeEventListener('mouseup', chartInstance.zoom._mouseUpHandler);
} else {
node.removeEventListener('wheel', chartInstance.zoom._wheelHandler);
}
if (Hammer) {
node.removeEventListener('click', chartInstance.zoom._ghostClickHandler);
}
delete chartInstance.zoom;
var mc = chartInstance._mc;
if (mc) {
mc.remove('pinchstart');
mc.remove('pinch');
mc.remove('pinchend');
mc.remove('panstart');
mc.remove('pan');
mc.remove('panend');
}
}
}
};
module.exports = zoomPlugin;
Chart.pluginService.register(zoomPlugin);