- Update DateTimePicker and fix error pages style
- Update gulp file
- Update moment vendor
This commit is contained in:
William-H-M 2020-01-23 23:10:31 -05:00
parent 5a27b568f5
commit 16d771aea4
623 changed files with 71530 additions and 111943 deletions

View file

@ -77,7 +77,8 @@
"DateJS": "^1.0.0-rc3",
"flot.curvedlines": "^1.1.1",
"flot.orderbars": "*",
"flot-spline": "^0.8.2"
"flot-spline": "^0.8.2",
"moment": "^2.24.0"
},
"resolutions": {
"jquery": "^2.2.3",

View file

@ -4860,6 +4860,11 @@ ul.notifications {
border: 1px solid #e5e5e5; }
/** /Dropzone.js **/
/** Tempus-Dominus **/
.timepicker-picker .separator {
display: none; }
/** /Tempus-Dominus **/
.daterangepicker .ranges li {
color: #73879C; }

File diff suppressed because one or more lines are too long

View file

@ -2,12 +2,14 @@ var gulp = require('gulp'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
rename = require('gulp-rename'),
sass = require('gulp-ruby-sass'),
sass = require('gulp-sass'),
autoprefixer = require('gulp-autoprefixer'),
browserSync = require('browser-sync').create();
var DEST = 'build/';
sass.compiler = require('node-sass');
gulp.task('scripts', function() {
return gulp.src([
'src/js/helpers/*.js',
@ -23,7 +25,8 @@ gulp.task('scripts', function() {
// TODO: Maybe we can simplify how sass compile the minify and unminify version
var compileSASS = function (filename, options) {
return sass('src/scss/*.scss', options)
return gulp.src('src/scss/*.scss')
.pipe(sass(options).on('error', sass.logError))
.pipe(autoprefixer('last 2 versions', '> 5%'))
.pipe(concat(filename))
.pipe(gulp.dest(DEST+'/css'))
@ -35,7 +38,7 @@ gulp.task('sass', function() {
});
gulp.task('sass-minify', function() {
return compileSASS('custom.min.css', {style: 'compressed'});
return compileSASS('custom.min.css', {outputStyle: 'compressed'});
});
gulp.task('browser-sync', function() {

View file

@ -32,11 +32,16 @@
"homepage": "https://github.com/puikinsh/gentelella#readme",
"devDependencies": {
"browser-sync": "^2.26.7",
"gulp": "^4.0.2",
"gulp-autoprefixer": "^7.0.1",
"gulp-concat": "^2.6.1",
"gulp-rename": "^2.0.0",
"gulp-ruby-sass": "^4.0.0",
"gulp-uglify": "^3.0.2"
"gulp-sass": "^4.0.2",
"gulp-uglify": "^3.0.2",
"node-sass": "^4.13.1"
},
"dependencies": {
"bower": "^1.8.8",
"gulp": "^4.0.2"
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -1,23 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Gentelella Alela! | </title>
<title>Gentelella Alela! |</title>
<!-- Bootstrap -->
<link href="../vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link
href="../vendors/bootstrap/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<!-- Font Awesome -->
<link href="../vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link
href="../vendors/font-awesome/css/font-awesome.min.css"
rel="stylesheet"
/>
<!-- NProgress -->
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet">
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet" />
<!-- Custom Theme Style -->
<link href="../build/css/custom.min.css" rel="stylesheet">
<link href="../build/css/custom.min.css" rel="stylesheet" />
</head>
<body class="nav-md">
@ -29,17 +35,25 @@
<div class="text-center text-center">
<h1 class="error-number">403</h1>
<h2>Access denied</h2>
<p>Full authentication is required to access this resource. <a href="#">Report this?</a>
<p>
Full authentication is required to access this resource.
<a href="#">Report this?</a>
</p>
<div class="mid_center">
<h3>Search</h3>
<form>
<div class=" form-group pull-right top_search">
<div class="form-group top_search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<input
type="text"
class="form-control"
placeholder="Search for..."
/>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
<button class="btn btn-secondary" type="button">
Go!
</button>
</span>
</div>
</div>
</form>
@ -54,7 +68,7 @@
<!-- jQuery -->
<script src="../vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- FastClick -->
<script src="../vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->
@ -63,4 +77,4 @@
<!-- Custom Theme Scripts -->
<script src="../build/js/custom.min.js"></script>
</body>
</html>
</html>

View file

@ -1,23 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Gentelella Alela! | </title>
<title>Gentelella Alela! |</title>
<!-- Bootstrap -->
<link href="../vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link
href="../vendors/bootstrap/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<!-- Font Awesome -->
<link href="../vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link
href="../vendors/font-awesome/css/font-awesome.min.css"
rel="stylesheet"
/>
<!-- NProgress -->
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet">
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet" />
<!-- Custom Theme Style -->
<link href="../build/css/custom.min.css" rel="stylesheet">
<link href="../build/css/custom.min.css" rel="stylesheet" />
</head>
<body class="nav-md">
@ -29,17 +35,25 @@
<div class="text-center text-center">
<h1 class="error-number">404</h1>
<h2>Sorry but we couldn't find this page</h2>
<p>This page you are looking for does not exist <a href="#">Report this?</a>
<p>
This page you are looking for does not exist
<a href="#">Report this?</a>
</p>
<div class="mid_center">
<h3>Search</h3>
<form>
<div class=" form-group pull-right top_search">
<div class="form-group top_search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<input
type="text"
class="form-control"
placeholder="Search for..."
/>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
<button class="btn btn-secondary" type="button">
Go!
</button>
</span>
</div>
</div>
</form>
@ -54,7 +68,7 @@
<!-- jQuery -->
<script src="../vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- FastClick -->
<script src="../vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->

View file

@ -1,23 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Meta, title, CSS, favicons, etc. -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Gentelella Alela! | </title>
<title>Gentelella Alela! |</title>
<!-- Bootstrap -->
<link href="../vendors/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">
<link
href="../vendors/bootstrap/dist/css/bootstrap.min.css"
rel="stylesheet"
/>
<!-- Font Awesome -->
<link href="../vendors/font-awesome/css/font-awesome.min.css" rel="stylesheet">
<link
href="../vendors/font-awesome/css/font-awesome.min.css"
rel="stylesheet"
/>
<!-- NProgress -->
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet">
<link href="../vendors/nprogress/nprogress.css" rel="stylesheet" />
<!-- Custom Theme Style -->
<link href="../build/css/custom.min.css" rel="stylesheet">
<link href="../build/css/custom.min.css" rel="stylesheet" />
</head>
<body class="nav-md">
@ -29,17 +35,26 @@
<div class="text-center">
<h1 class="error-number">500</h1>
<h2>Internal Server Error</h2>
<p>We track these errors automatically, but if the problem persists feel free to contact us. In the meantime, try refreshing. <a href="#">Report this?</a>
<p>
We track these errors automatically, but if the problem persists
feel free to contact us. In the meantime, try refreshing.
<a href="#">Report this?</a>
</p>
<div class="mid_center">
<h3>Search</h3>
<form>
<div class=" form-group pull-right top_search">
<div class="form-group top_search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search for...">
<input
type="text"
class="form-control"
placeholder="Search for..."
/>
<span class="input-group-btn">
<button class="btn btn-secondary" type="button">Go!</button>
</span>
<button class="btn btn-secondary" type="button">
Go!
</button>
</span>
</div>
</div>
</form>
@ -54,7 +69,7 @@
<!-- jQuery -->
<script src="../vendors/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="../vendors/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<!-- FastClick -->
<script src="../vendors/fastclick/lib/fastclick.js"></script>
<!-- NProgress -->
@ -63,4 +78,4 @@
<!-- Custom Theme Scripts -->
<script src="../build/js/custom.min.js"></script>
</body>
</html>
</html>

View file

@ -4752,3 +4752,9 @@ ul.notifications {
border: 1px solid #e5e5e5;
}
/** /Dropzone.js **/
/** Tempus-Dominus **/
.timepicker-picker .separator {
display: none;
}
/** /Tempus-Dominus **/

View file

@ -1,18 +1,14 @@
{
"name": "Flot",
"version": "0.8.3",
"main": "jquery.flot.js",
"dependencies": {
"jquery": ">= 1.2.6"
},
"name": "flot",
"homepage": "https://github.com/flot/flot",
"_release": "0.8.3",
"version": "4.1.1",
"_release": "4.1.1",
"_resolution": {
"type": "version",
"tag": "v0.8.3",
"commit": "453b017cc5acfd75e252b93e8635f57f4196d45d"
"tag": "v4.1.1",
"commit": "01490257a542c48188ba6a5785bdc50cc0624c17"
},
"_source": "https://github.com/flot/flot.git",
"_target": "^0.8.3",
"_target": ">=0.8.0",
"_originalSource": "flot"
}

View file

@ -1,3 +1,5 @@
*.min.js
!excanvas.min.js
node_modules/
debug.log
coverage/**
dist/
.vscode

View file

@ -1,3 +1,40 @@
dist: trusty
language: node_js
node_js:
- 0.8
- '8'
addons:
firefox: latest
chrome: stable
cache:
directories:
- node_modules
before_install:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
- npm install -g greenkeeper-lockfile@1
- npm config set //registry.npmjs.org/:_authToken=$NPM_TOKEN
before_script:
- greenkeeper-lockfile-update
- sudo chown root /opt/google/chrome/chrome-sandbox
- sudo chmod 4755 /opt/google/chrome/chrome-sandbox
after_script:
- greenkeeper-lockfile-upload
before_deploy:
- tar -tf $(npm pack)
install:
- npm install
script:
- npm test
- npm run build
- npm run coverage
env:
secure: mkyiKGXQ8wkx4kSi/x7kProXE76E2Ix5xP+xHAcTpMhsFJYsyFE8LR8wC7UWxg80nbww6P1mWpJkMPm2QnWW8OSuKh9pF2bluTU7VAf68JHROA55FZauO0NgLWxF1tog/RLaTXBzoqXBx5+Zlcp2jl4UdsDSIr/1TogSEC7hV3dMiqzTsiC09RnAgtGsUfzDjCGVgyz2yDBMCoi+kfzJiRz7f1dW5GxhUypuV4jjEXTt1V6XrIA0C/uD27LP+kswHadMT6HURPiWEJteKNFz6hnfXttF1XmTwW++kzahDoap607oLszz+g8ss/9F0ILyO3tffyKnoEOImJLogvLUm3slxfHvh9PYh7x8oyPHFtfs7QAJ5Q2Cr23VvwJNslkuNCphEsQJS/HQ70VuSF6MlGrhbsLGp8kEFZrXADqojkGQ/duPk3QykiXUaUxr0uPEllptOLh5TTKYarRM/IVv4kE5iC4egJXouKxwwL5LIglnyCTycEdTLv/IUfYap8ABqi20eBm+AJGk44Z72fl+G/xoPrzbtVosQfPbuLurVJHHDDExHM3bFqfUNnB9xIEwWTihSc6ycI7IhuMQlg1G1t5rRY5YyVQN/4oP4k6qNgYbJs9PrxfyMw7Z+dSg/L2SyJbc/ReNiFkvpTNDYGY/dULvx1uGM1NGdmC+z+nljfk=
deploy:
provider: npm
skip_cleanup: true
email: webapps.ops@ni.com
api_key:
secure: kJyDLyReYLVr01TidziatIzTk1GpTvGLQo7XLAQReDemRkN13905TaYPsrl5IMnkLfk6RaizbCscx7z1MGi3P/U+2DC10OE4pbnUVrcCZLX9RPqLmVgVWxX+pPH+Mu3Td/Ay7CYeNdo031Lufxbc+m0kGlVnMyPBwctU36ES+OI=
on:
tags: true
repo: flot/flot

28
vendors/Flot/API.md vendored
View file

@ -143,7 +143,7 @@ the plot, see below.
The rest of the options are all documented below as they are the same
as the default options passed in via the options parameter in the plot
commmand. When you specify them for a specific data series, they will
command. When you specify them for a specific data series, they will
override the default options for the plot for that data series.
Here's a complete example of a simple data specification:
@ -531,14 +531,18 @@ calendars don't follow a simple base 10 system. For many cases, Flot
abstracts most of this away, but it can still be a bit difficult to
get the data into Flot. So we'll first discuss the data format.
The time series support in Flot is based on Javascript timestamps,
i.e. everywhere a time value is expected or handed over, a Javascript
timestamp number is used. This is a number, not a Date object. A
Javascript timestamp is the number of milliseconds since January 1,
1970 00:00:00 UTC. This is almost the same as Unix timestamps, except it's
in milliseconds, so remember to multiply by 1000!
The time series support in Flot is based on Epoch timestamps, i.e.,
everywhere a time value is expected or handed over, a number is used.
This is a number, not a Date object. Flot supports three different time
bases in which the timestamps can be given: seconds, milliseconds and
microseconds. The timestamp is therefore the number of microseconds,
milliseconds or seconds since January 1, 1970 00:00:00 UTC.
You can see a timestamp like this
The time base in which the timestamps are given to Flot can be selected
by setting the "timeBase" option to "microseconds", "milliseconds"
or "seconds" in axis options. If not set, it defaults to "seconds".
You can see a native Javascript timestamp (in milliseconds) like this
```js
alert((new Date()).getTime())
@ -645,6 +649,7 @@ this:
```js
xaxis: {
mode: "time",
timeBase: "milliseconds",
timeformat: "%Y/%m/%d"
}
```
@ -663,6 +668,7 @@ standard strftime specifiers are supported (plus the nonstandard %q):
%M: minutes, zero-padded (00-59)
%q: quarter (1-4)
%S: seconds, zero-padded (00-59)
%s: sub-seconds, accuracy can be denoted with a number (e.g., %3s)
%y: year (two digits)
%Y: year (four digits)
%p: am/pm
@ -694,6 +700,12 @@ applies if you have not set "timeformat". Use the "%I" and "%p" or
"%P" options if you want to build your own format string with 12-hour
times.
If you want to have ticks with a fixed sub-second accuracy, you can add
a number in the subsecond specifier (e.g., "%3s" for millisecond
accuracy) in the "timeformat" string". If the accuracy for the sub-second
timestamps is not given, Flot will automatically determine the accuracy
depending on the timespan of the axis and the number of ticks, to create.
If the Date object has a strftime property (and it is a function), it
will be used instead of the built-in formatter. Thus you can include
a strftime library such as http://hacks.bluesmoon.info/strftime/ for

16
vendors/Flot/FAQ.md vendored
View file

@ -1,12 +1,14 @@
## Frequently asked questions ##
#### Which browsers are supported by Flot? ####
Flot's distribution source is transpiled to ES5, which all major browsers support.
For more information, [check here.](https://caniuse.com/#feat=es5)
#### How much data can Flot cope with? ####
Flot will happily draw everything you send to it so the answer
depends on the browser. The excanvas emulation used for IE (built with
VML) makes IE by far the slowest browser so be sure to test with that
if IE users are in your target group (for large plots in IE, you can
also check out Flashcanvas which may be faster).
depends on the browser.
1000 points is not a problem, but as soon as you start having more
points than the pixel width, you should probably start thinking about
@ -27,9 +29,7 @@ conversion automatically.
You can grab the image rendered by the canvas element used by Flot
as a PNG or JPEG (remember to set a background). Note that it won't
include anything not drawn in the canvas (such as the legend). And it
doesn't work with excanvas which uses VML, but you could try
Flashcanvas.
include anything not drawn in the canvas (such as the legend).
#### The bars are all tiny in time mode? ####
@ -72,4 +72,4 @@ off-screen).
If you find there's a specific thing we can do to Flot to help, feel
free to submit a bug report. Otherwise, you're welcome to ask for help
on the forum/mailing list, but please don't submit a bug report to
Flot.
Flot.

12
vendors/Flot/Makefile vendored
View file

@ -1,12 +0,0 @@
# Makefile for generating minified files
.PHONY: all
# we cheat and process all .js files instead of an exhaustive list
all: $(patsubst %.js,%.min.js,$(filter-out %.min.js,$(wildcard *.js)))
%.min.js: %.js
yui-compressor $< -o $@
test:
./node_modules/.bin/jshint *jquery.flot.js

1026
vendors/Flot/NEWS.md vendored

File diff suppressed because it is too large Load diff

View file

@ -1,143 +0,0 @@
## Writing plugins ##
All you need to do to make a new plugin is creating an init function
and a set of options (if needed), stuffing it into an object and
putting it in the $.plot.plugins array. For example:
```js
function myCoolPluginInit(plot) {
plot.coolstring = "Hello!";
};
$.plot.plugins.push({ init: myCoolPluginInit, options: { ... } });
// if $.plot is called, it will return a plot object with the
// attribute "coolstring"
```
Now, given that the plugin might run in many different places, it's
a good idea to avoid leaking names. The usual trick here is wrap the
above lines in an anonymous function which is called immediately, like
this: (function () { inner code ... })(). To make it even more robust
in case $ is not bound to jQuery but some other Javascript library, we
can write it as
```js
(function ($) {
// plugin definition
// ...
})(jQuery);
```
There's a complete example below, but you should also check out the
plugins bundled with Flot.
## Complete example ##
Here is a simple debug plugin which alerts each of the series in the
plot. It has a single option that control whether it is enabled and
how much info to output:
```js
(function ($) {
function init(plot) {
var debugLevel = 1;
function checkDebugEnabled(plot, options) {
if (options.debug) {
debugLevel = options.debug;
plot.hooks.processDatapoints.push(alertSeries);
}
}
function alertSeries(plot, series, datapoints) {
var msg = "series " + series.label;
if (debugLevel > 1) {
msg += " with " + series.data.length + " points";
alert(msg);
}
}
plot.hooks.processOptions.push(checkDebugEnabled);
}
var options = { debug: 0 };
$.plot.plugins.push({
init: init,
options: options,
name: "simpledebug",
version: "0.1"
});
})(jQuery);
```
We also define "name" and "version". It's not used by Flot, but might
be helpful for other plugins in resolving dependencies.
Put the above in a file named "jquery.flot.debug.js", include it in an
HTML page and then it can be used with:
```js
$.plot($("#placeholder"), [...], { debug: 2 });
```
This simple plugin illustrates a couple of points:
- It uses the anonymous function trick to avoid name pollution.
- It can be enabled/disabled through an option.
- Variables in the init function can be used to store plot-specific
state between the hooks.
The two last points are important because there may be multiple plots
on the same page, and you'd want to make sure they are not mixed up.
## Shutting down a plugin ##
Each plot object has a shutdown hook which is run when plot.shutdown()
is called. This usually mostly happens in case another plot is made on
top of an existing one.
The purpose of the hook is to give you a chance to unbind any event
handlers you've registered and remove any extra DOM things you've
inserted.
The problem with event handlers is that you can have registered a
handler which is run in some point in the future, e.g. with
setTimeout(). Meanwhile, the plot may have been shutdown and removed,
but because your event handler is still referencing it, it can't be
garbage collected yet, and worse, if your handler eventually runs, it
may overwrite stuff on a completely different plot.
## Some hints on the options ##
Plugins should always support appropriate options to enable/disable
them because the plugin user may have several plots on the same page
where only one should use the plugin. In most cases it's probably a
good idea if the plugin is turned off rather than on per default, just
like most of the powerful features in Flot.
If the plugin needs options that are specific to each series, like the
points or lines options in core Flot, you can put them in "series" in
the options object, e.g.
```js
var options = {
series: {
downsample: {
algorithm: null,
maxpoints: 1000
}
}
}
```
Then they will be copied by Flot into each series, providing default
values in case none are specified.
Think hard and long about naming the options. These names are going to
be public API, and code is going to depend on them if the plugin is
successful.

View file

@ -1,40 +1,20 @@
# Flot [![Build status](https://travis-ci.org/flot/flot.png)](https://travis-ci.org/flot/flot)
# flot [![Build Status](https://travis-ci.org/flot/flot.svg?branch=master)](https://travis-ci.org/flot/flot) [![CircleCI](https://circleci.com/gh/flot/flot.svg?style=svg)](https://circleci.com/gh/flot/flot) [![Coverage Status](https://coveralls.io/repos/github/flot/flot/badge.svg?branch=master)](https://coveralls.io/github/flot/flot?branch=master) [![Greenkeeper badge](https://badges.greenkeeper.io/flot/flot.svg)](https://greenkeeper.io/)
## About ##
Flot is a Javascript plotting library for jQuery.
Read more at the website: <http://www.flotcharts.org/>
flot is a JavaScript plotting library for engineering and scientific
applications derived from Flot: <http://www.flotcharts.org/>
Take a look at the the examples in examples/index.html; they should give a good
impression of what Flot can do, and the source code of the examples is probably
the fastest way to learn how to use Flot.
impression of what flot can do, and the source code of the examples is probably
the fastest way to learn how to use flot.
## Installation ##
Just include the Javascript file after you've included jQuery.
Just include the JavaScript file after you've included jQuery.
Generally, all browsers that support the HTML5 canvas tag are
supported.
For support for Internet Explorer < 9, you can use [Excanvas]
[excanvas], a canvas emulator; this is used in the examples bundled
with Flot. You just include the excanvas script like this:
```html
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]-->
```
If it's not working on your development IE 6.0, check that it has
support for VML which Excanvas is relying on. It appears that some
stripped down versions used for test environments on virtual machines
lack the VML support.
You can also try using [Flashcanvas][flashcanvas], which uses Flash to
do the emulation. Although Flash can be a bit slower to load than VML,
if you've got a lot of points, the Flash version can be much faster
overall. Flot contains some wrapper code for activating Excanvas which
Flashcanvas is compatible with.
Generally, all modern browsers are supported.
You need at least jQuery 1.2.6, but try at least 1.3.2 for interactive
charts because of performance improvements in event handling.
@ -71,8 +51,8 @@ $.plot($("#placeholder"), data, options);
Here, data is an array of data series and options is an object with
settings if you want to customize the plot. Take a look at the
examples for some ideas of what to put in or look at the
[API reference](API.md). Here's a quick example that'll draw a line
examples for some ideas of what to put in or look at the
[API reference](API.md). Here's a quick example that'll draw a line
from (0, 0) to (1, 1):
```js
@ -82,29 +62,17 @@ $.plot($("#placeholder"), [ [[0, 0], [1, 1]] ], { yaxis: { max: 1 } });
The plot function immediately draws the chart and then returns a plot
object with a couple of methods.
## Documentation and examples
## What's with the name? ##
API Documentation is available here: [API reference](docs/API.md)
First: it's pronounced with a short o, like "plot". Not like "flawed".
About how the plugins work: [Plugins](docs/PLUGINS.md)
So "Flot" rhymes with "plot".
High level overview on how interactions are handled internally: [Interactions](docs/interactions.md)
And if you look up "flot" in a Danish-to-English dictionary, some of
the words that come up are "good-looking", "attractive", "stylish",
"smart", "impressive", "extravagant". One of the main goals with Flot
is pretty looks.
Examples are included in the examples folder of this repository, but they can be tried out online as well: [Examples](https://rawgit.com/flot/flot/master/examples/index.html)
## CircleCI
## Notes about the examples ##
In order to have a useful, functional example of time-series plots using time
zones, date.js from [timezone-js][timezone-js] (released under the Apache 2.0
license) and the [Olson][olson] time zone database (released to the public
domain) have been included in the examples directory. They are used in
examples/axes-time-zones/index.html.
[excanvas]: http://code.google.com/p/explorercanvas/
[flashcanvas]: http://code.google.com/p/flashcanvas/
[timezone-js]: https://github.com/mde/timezone-js
[olson]: http://ftp.iana.org/time-zones
[CircleCI](https://circleci.com/) is used in this repo to run [dont-break](https://www.npmjs.com/package/dont-break),
which checks if the current version of flot breaks unit tests on specified dependent projects.

View file

@ -1,8 +0,0 @@
{
"name": "Flot",
"version": "0.8.3",
"main": "jquery.flot.js",
"dependencies": {
"jquery": ">= 1.2.6"
}
}

View file

@ -4,19 +4,27 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: AJAX</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {
var options = {
lines: {
show: true
},
points: {
show: true
series: {
lines: {
show: true,
lineWidth: 2
},
points: {
show: true
}
},
xaxis: {
tickDecimals: 0,

View file

@ -1,87 +1,94 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Adding Annotations</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script type="text/javascript">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Adding Annotations</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {
$(function() {
var d1 = [];
for (var i = 0; i < 20; ++i) {
d1.push([i, Math.sin(i)]);
}
var d1 = [];
for (var i = 0; i < 20; ++i) {
d1.push([i, Math.sin(i)]);
}
var data = [{ data: d1, label: "Pressure", color: "#333" }];
var data = [{ data: d1, label: "Pressure", color: "#333" }];
var markings = [
{ color: "#f6f6f6", yaxis: { from: 1 } },
{ color: "#f6f6f6", yaxis: { to: -1 } },
{ color: "#000", lineWidth: 1, xaxis: { from: 2, to: 2 } },
{ color: "#000", lineWidth: 1, xaxis: { from: 8, to: 8 } }
];
var markings = [
{ color: "#f6f6f6", yaxis: { from: 1 } },
{ color: "#f6f6f6", yaxis: { to: -1 } },
{ color: "#000", lineWidth: 1, xaxis: { from: 2, to: 2 } },
{ color: "#000", lineWidth: 1, xaxis: { from: 8, to: 8 } }
];
var placeholder = $("#placeholder");
var placeholder = $("#placeholder");
var plot = $.plot(placeholder, data, {
bars: { show: true, barWidth: 0.5, fill: 0.9 },
xaxis: { ticks: [], autoscaleMargin: 0.02 },
yaxis: { min: -2, max: 2 },
grid: { markings: markings }
});
var plot = $.plot(placeholder, data, {
series: {
bars: { show: true, barWidth: 0.5, fill: 0.9 }
},
xaxis: { show: false },
yaxis: { min: -2, max: 2, autoScale: "none" },
grid: { markings: markings }
});
var o = plot.pointOffset({ x: 2, y: -1.2});
var o = plot.pointOffset({ x: 2, y: -1.2});
// Append it to the placeholder that Flot already uses for positioning
// Append it to the placeholder that Flot already uses for positioning
placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Warming up</div>");
placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Warming up</div>");
o = plot.pointOffset({ x: 8, y: -1.2});
placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Actual measurements</div>");
o = plot.pointOffset({ x: 8, y: -1.2});
placeholder.append("<div style='position:absolute;left:" + (o.left + 4) + "px;top:" + o.top + "px;color:#666;font-size:smaller'>Actual measurements</div>");
// Draw a little arrow on top of the last label to demonstrate canvas
// drawing
// Draw a little arrow on top of the last label to demonstrate canvas
// drawing
var ctx = plot.getCanvas().getContext("2d");
ctx.beginPath();
o.left += 4;
ctx.moveTo(o.left, o.top);
ctx.lineTo(o.left, o.top - 10);
ctx.lineTo(o.left + 10, o.top - 5);
ctx.lineTo(o.left, o.top);
ctx.fillStyle = "#000";
ctx.fill();
var ctx = plot.getCanvas().getContext("2d");
ctx.beginPath();
o.left += 4;
ctx.moveTo(o.left, o.top);
ctx.lineTo(o.left, o.top - 10);
ctx.lineTo(o.left + 10, o.top - 5);
ctx.lineTo(o.left, o.top);
ctx.fillStyle = "#000";
ctx.fill();
// Add the Flot version string to the footer
// Add the Flot version string to the footer
$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
});
$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
});
</script>
</script>
</head>
<body>
<div id="header">
<h2>Adding Annotations</h2>
</div>
<div id="header">
<h2>Adding Annotations</h2>
</div>
<div id="content">
<div id="content">
<div class="demo-container">
<div id="placeholder" class="demo-placeholder"></div>
</div>
<div class="demo-container">
<div id="placeholder" class="demo-placeholder"></div>
</div>
<p>Flot has support for simple background decorations such as lines and rectangles. They can be useful for marking up certain areas. You can easily add any HTML you need with standard DOM manipulation, e.g. for labels. For drawing custom shapes there is also direct access to the canvas.</p>
<p>Flot has support for simple background decorations such as lines and rectangles. They can be useful for marking up certain areas. You can easily add any HTML you need with standard DOM manipulation, e.g. for labels. For drawing custom shapes there is also direct access to the canvas.</p>
</div>
</div>
<div id="footer">
Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
</div>
<div id="footer">
Copyright &copy; 2007 - 2014 IOLA and Ole Laursen
</div>
</body>
</html>

View file

@ -4,39 +4,47 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Interacting with axes</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {
function generate(start, end, fn) {
var res = [];
for (var i = 0; i <= 100; ++i) {
var x = start + i / 100 * (end - start);
for (var i = 0; i <= 40; ++i) {
var x = start + i / 40 * (end - start);
res.push([x, fn(x)]);
}
return res;
}
var data = [
{ data: generate(0, 10, function (x) { return Math.sqrt(x);}), xaxis: 1, yaxis:1 },
{ data: generate(0, 10, function (x) { return Math.sin(x);}), xaxis: 1, yaxis:2 },
{ data: generate(0, 10, function (x) { return Math.cos(x);}), xaxis: 1, yaxis:3 },
{ data: generate(2, 10, function (x) { return Math.tan(x);}), xaxis: 2, yaxis: 4 }
{ data: generate(0, 10, function (x) { return Math.sqrt(x);}), xaxis: 1, yaxis:1, lines: { show: true, fill: true }},
{ data: generate(0, 10, function (x) { return Math.sin(x);}), xaxis: 1, yaxis:2, points: { show: true }},
{ data: generate(0, 10, function (x) { return (x < 3 || x > 5) ? Math.cos(x) : null;}), xaxis: 1, yaxis:3 },
{ data: generate(2, 10, function (x) { return Math.tan(x);}), xaxis: 2, yaxis: 4, lines: { show: true, steps: true }},
{ data: generate(5, 15, function (x) { return 30 * Math.sin(x/2+3);}), xaxis: 3, yaxis: 5, bars: {show: true, fill: true, barWidth:0.1, align: "center"}}
];
var plot = $.plot("#placeholder", data, {
xaxes: [
{ position: 'bottom' },
{ position: 'bottom'},
{ position: 'top'}
],
yaxes: [
{ position: 'left' },
{ position: 'left' },
{ position: 'right' },
{ position: 'left' }
{ position: 'left' },
{ position: 'right' }
]
});

View file

@ -4,10 +4,17 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Multiple Axes</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/globalize.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/globalize.culture.en-US.js"></script>
<script type="text/javascript">
$(function() {
@ -25,7 +32,10 @@
{ data: oilprices, label: "Oil price ($)" },
{ data: exchangerates, label: "USD/EUR exchange rate", yaxis: 2 }
], {
xaxes: [ { mode: "time" } ],
series: {
lines: {lineWidth: 2}
},
xaxes: [ { mode: "time", timeBase: "milliseconds" } ],
yaxes: [ { min: 0 }, {
// align if we are to the right
alignTicksWithAxis: position == "right" ? 1 : null,

View file

@ -1,3 +1,4 @@
/* eslint-disable */
// -----
// The `timezoneJS.Date` object gives you full-blown timezone support, independent from the timezone set on the end-user's machine running the browser. It uses the Olson zoneinfo files for its timezone data.
//

View file

@ -4,10 +4,16 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Time zones</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/globalize.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="date.js"></script>
<script type="text/javascript">
@ -56,21 +62,24 @@
var plot = $.plot("#placeholderUTC", [d], {
xaxis: {
mode: "time"
mode: "time",
timeBase: "milliseconds"
}
});
var plot = $.plot("#placeholderLocal", [d], {
xaxis: {
mode: "time",
timezone: "browser"
timezone: "browser",
timeBase: "milliseconds"
}
});
var plot = $.plot("#placeholderChicago", [d], {
xaxis: {
mode: "time",
timezone: "America/Chicago"
timezone: "America/Chicago",
timeBase: "milliseconds"
}
});

File diff suppressed because one or more lines are too long

View file

@ -4,9 +4,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Basic Options</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function () {
@ -36,12 +41,14 @@
points: { show: true }
},
xaxis: {
autoScale: "exact",
ticks: [
0, [ Math.PI/2, "\u03c0/2" ], [ Math.PI, "\u03c0" ],
[ Math.PI * 3/2, "3\u03c0/2" ], [ Math.PI * 2, "2\u03c0" ]
]
},
yaxis: {
autoScale: "none",
ticks: 10,
min: -2,
max: 2,

View file

@ -4,9 +4,14 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Basic Usage</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {

File diff suppressed because one or more lines are too long

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Categories</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.categories.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.categories.js"></script>
<script type="text/javascript">
$(function() {
@ -24,7 +29,8 @@
},
xaxis: {
mode: "categories",
tickLength: 0
showTicks: false,
gridLines: false
}
});
@ -57,8 +63,3 @@
</body>
</html>

View file

@ -2,7 +2,8 @@
body {
background: url(background.png) repeat-x;
font: 18px/1.5em "proxima-nova", Helvetica, Arial, sans-serif;
font: 18px "proxima-nova", Helvetica, Arial, sans-serif;
line-height: 1.5;
}
a { color: #069; }
@ -83,15 +84,63 @@ input[type=checkbox] {
-ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
-moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
-webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);
-webkit-tap-highlight-color: rgba(0,0,0,0);
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.demo-placeholder {
width: 100%;
height: 100%;
font-size: 14px;
line-height: 1.2em;
}
.legend table {
border-spacing: 5px;
}
fieldset {
display: block;
-webkit-margin-start: 2px;
-webkit-margin-end: 2px;
-webkit-padding-before: 0.35em;
-webkit-padding-start: 0.75em;
-webkit-padding-end: 0.75em;
-webkit-padding-after: 0.625em;
min-width: -webkit-min-content;
border-width: 2px;
border-style: groove;
border-color: threedface;
border-image: initial;
padding: 10px;
}
.legend {
display: block;
-webkit-padding-start: 2px;
-webkit-padding-end: 2px;
border-width: initial;
border-style: none;
border-color: initial;
border-image: initial;
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
padding-bottom: 10px;
}
.legendLayer .background {
fill: rgba(255, 255, 255, 0.85);
stroke: rgba(0, 0, 0, 0.85);
stroke-width: 1;
}
input[type="radio"] {
margin-top: -1px;
vertical-align: middle;
}
.tickLabel {
line-height: 1.1;
}

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Image Plots</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.image.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.image.js"></script>
<script type="text/javascript">
$(function() {
@ -21,12 +26,14 @@
}
},
xaxis: {
autoScale: "none",
min: -8,
max: 4
max: 8
},
yaxis: {
autoScale: "none",
min: -8,
max: 4
max: 8
}
};

View file

@ -1,80 +1,119 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples</title>
<link href="examples.css" rel="stylesheet" type="text/css">
<style>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples</title>
<link href="examples.css" rel="stylesheet" type="text/css">
<style>
h3 {
margin-top: 30px;
margin-bottom: 5px;
}
h3 {
margin-top: 30px;
margin-bottom: 5px;
}
</style>
<script language="javascript" type="text/javascript" src="../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../jquery.flot.js"></script>
<script type="text/javascript">
</style>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.errorbars.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.logaxis.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.symbol.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.flatdata.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.navigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.fillbetween.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.stack.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touchNavigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.hover.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touch.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.axislabels.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.selection.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.composeImages.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.legend.js"></script>
<script type="text/javascript">
$(function() {
$(function() {
// Add the Flot version string to the footer
// Add the Flot version string to the footer
$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
});
$("#footer").prepend("Flot " + $.plot.version + " &ndash; ");
});
</script>
</script>
</head>
<body>
<div id="header">
<h2>Flot Examples</h2>
</div>
<div id="header">
<h2>Flot Examples</h2>
</div>
<div id="content">
<div id="content">
<p>Here are some examples for <a href="http://www.flotcharts.org">Flot</a>, the Javascript charting library for jQuery:</p>
<p>Here are some examples for <a href="http://www.flotcharts.org">Flot</a>, the Javascript charting library for jQuery:</p>
<h3>Basic Usage</h3>
<h3>Basic Usage</h3>
<ul>
<li><a href="basic-usage/index.html">Basic example</a></li>
<li><a href="series-types/index.html">Different graph types</a> and <a href="categories/index.html">simple categories/textual data</a></li>
<li><a href="basic-options/index.html">Setting various options</a> and <a href="annotating/index.html">annotating a chart</a></li>
<li><a href="ajax/index.html">Updating graphs with AJAX</a> and <a href="realtime/index.html">real-time updates</a></li>
</ul>
<ul>
<li><a href="basic-usage/index.html">Basic example</a></li>
<li><a href="series-types/index.html">Different graph types</a> and <a href="categories/index.html">simple categories/textual data</a></li>
<li><a href="basic-options/index.html">Setting various options</a> and <a href="annotating/index.html">annotating a chart</a></li>
<li><a href="ajax/index.html">Updating graphs with AJAX</a> and <a href="realtime/index.html">real-time updates</a></li>
</ul>
<h3>Interactivity</h3>
<h3>Interactivity</h3>
<ul>
<li><a href="series-toggle/index.html">Turning series on/off</a></li>
<li><a href="selection/index.html">Rectangular selection support and zooming</a> and <a href="zooming/index.html">zooming with overview</a> (both with selection plugin)</li>
<li><a href="interacting/index.html">Interacting with the data points</a></li>
<li><a href="navigate/index.html">Panning and zooming</a> (with navigation plugin)</li>
<li><a href="resize/index.html">Automatically redraw when window is resized</a> (with resize plugin)</li>
</ul>
<ul>
<li><a href="series-toggle/index.html">Turning series on/off</a></li>
<li><a href="selection/index.html">Rectangular selection support and zooming</a> and <a href="zooming/index.html">zooming with overview</a> (both with selection plugin)</li>
<li><a href="interacting/index.html">Interacting with the data points</a></li>
<li><a href="navigate/index.html">Panning and zooming</a> (with navigation plugin)</li>
<li><a href="navigateTouch/index.html">Panning and zooming simple and log-axis charts with Touch</a> (with touchNavigation plugin)</li>
<li><a href="resize/index.html">Automatically redraw when window is resized</a> (with resize plugin)</li>
</ul>
<h3>Additional Features</h3>
<h3>Axes</h3>
<ul>
<li><a href="symbols/index.html">Using other symbols than circles for points</a> (with symbol plugin)</li>
<li><a href="axes-time/index.html">Plotting time series</a>, <a href="visitors/index.html">visitors per day with zooming and weekends</a> (with selection plugin) and <a href="axes-time-zones/index.html">time zone support</a></li>
<li><a href="axes-multiple/index.html">Multiple axes</a> and <a href="axes-interacting/index.html">interacting with the axes</a></li>
<li><a href="threshold/index.html">Thresholding the data</a> (with threshold plugin)</li>
<li><a href="stacking/index.html">Stacked charts</a> (with stacking plugin)</li>
<li><a href="percentiles/index.html">Using filled areas to plot percentiles</a> (with fillbetween plugin)</li>
<li><a href="tracking/index.html">Tracking curves with crosshair</a> (with crosshair plugin)</li>
<li><a href="image/index.html">Plotting prerendered images</a> (with image plugin)</li>
<li><a href="series-errorbars/index.html">Plotting error bars</a> (with errorbars plugin)</li>
<li><a href="series-pie/index.html">Pie charts</a> (with pie plugin)</li>
<li><a href="canvas/index.html">Rendering text with canvas instead of HTML</a> (with canvas plugin)</li>
</ul>
<ul>
<li><a href="axes-time/index.html">Plotting time series</a>, <a href="visitors/index.html">visitors per day with zooming and weekends</a> (with selection plugin)</li>
<li><a href="axes-time-zones/index.html">Time zone support</a></li>
<li><a href="log-scale/index.html">Log scales</a></li>
<li><a href="axes-multiple/index.html">Multiple axes</a></li>
<li><a href="axes-interacting/index.html">Interacting with the axes</a></li>
<li><a href="axes-autoscaling/index.html">Autoscaling options</a></li>
<li><a href="axes-tickLabels/index.html">Tick labels options</a></li>
<li><a href="axes-labels/index.html">Axis labels</a></li>
</ul>
</div>
<h3>Additional Features</h3>
<div id="footer">
Copyright &copy; 2007 - 2013 IOLA and Ole Laursen
</div>
<ul>
<li><a href="symbols/index.html">Using other symbols than circles for points</a> (with symbol plugin)</li>
<li><a href="threshold/index.html">Thresholding the data</a> (with threshold plugin)</li>
<li><a href="stacking/index.html">Stacked charts</a> (with stacking plugin)</li>
<li><a href="percentiles/index.html">Using filled areas to plot percentiles</a> (with fillbetween plugin)</li>
<li><a href="tracking/index.html">Tracking curves with crosshair</a> (with crosshair plugin)</li>
<li><a href="image/index.html">Plotting prerendered images</a> (with image plugin)</li>
<li><a href="series-errorbars/index.html">Plotting error bars</a> (with errorbars plugin)</li>
<li><a href="plot-legend/index.html">Plot Legend</a> </li>
<li><a href="series-pie/index.html">Pie charts</a> (with pie plugin)</li>
</ul>
<br>
<p><i>
Note that these examples use the non-minified source, so they will not work on older browsers such as Internet Explorer.
Use the built source (which comes installed with the NPM package) if you need broader support.
</i></p>
</div>
<div id="footer">
Copyright &copy; 2007 - 2013 IOLA and Ole Laursen
</div>
</body>
</html>

View file

@ -4,9 +4,21 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Interactivity</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/jquery.event.drag.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/jquery.mousewheel.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.navigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touchNavigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.hover.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touch.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.selection.js"></script>
<script type="text/javascript">
$(function() {
@ -38,9 +50,23 @@
yaxis: {
min: -1.2,
max: 1.2
},
zoom: {
interactive: true
},
pan: {
interactive: true,
enableTouch: true
}
});
window.setInterval(function () {
plot.setData([
{ data: sin, label: "sin(x)"},
{ data: cos, label: "cos(x)"}
]);
}, 2000);
$("<div id='tooltip'></div>").css({
position: "absolute",
display: "none",
@ -52,6 +78,10 @@
$("#placeholder").bind("plothover", function (event, pos, item) {
if (!pos.x || !pos.y) {
return;
}
if ($("#enablePosition:checked").length > 0) {
var str = "(" + pos.x.toFixed(2) + ", " + pos.y.toFixed(2) + ")";
$("#hoverdata").text(str);
@ -71,6 +101,10 @@
}
});
$("#placeholder").bind("plothovercleanup", function (event, pos, item) {
$("#tooltip").hide();
});
$("#placeholder").bind("plotclick", function (event, pos, item) {
if (item) {
$("#clickdata").text(" - click point " + item.dataIndex + " in " + item.series.label);

View file

@ -22,11 +22,18 @@
font-size: smaller;
}
</style>
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.navigate.js"></script>
</style>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/jquery.event.drag.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/jquery.mousewheel.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.navigate.js"></script>
<script type="text/javascript">
$(function() {
@ -52,17 +59,20 @@
var plot = $.plot(placeholder, data, {
series: {
lines: {
show: true
},
show: true
},
shadowSize: 0
},
xaxis: {
zoomRange: [0.1, 10],
panRange: [-10, 10]
panRange: [-10, 10],
gridLines: true
},
yaxis: {
zoomRange: [0.1, 10],
panRange: [-10, 10]
panRange: [-10, 10],
gridLines: true,
autoScale: 'exact'
},
zoom: {
interactive: true
@ -72,7 +82,7 @@
}
});
// show pan/zoom messages to illustrate events
// show pan/zoom messages to illustrate events
placeholder.bind("plotpan", function (event, plot) {
var axes = plot.getAxes();
@ -90,7 +100,7 @@
+ " &ndash; " + axes.yaxis.max.toFixed(2));
});
// add zoom out button
// add zoom out button
$("<div class='button' style='right:20px;top:20px'>zoom out</div>")
.appendTo(placeholder)

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Percentiles</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.fillbetween.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.fillbetween.js"></script>
<script type="text/javascript">
$(function() {

View file

@ -3,10 +3,15 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Real-time updates</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<link href="../examples.css" rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {
@ -66,7 +71,7 @@
var plot = $.plot("#placeholder", [ getRandomData() ], {
series: {
shadowSize: 0 // Drawing is faster without shadows
shadowSize: 0 // Drawing is faster without shadows
},
yaxis: {
min: 0,

View file

@ -5,11 +5,17 @@
<title>Flot Examples: Resizing</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<link href="../shared/jquery-ui/jquery-ui.min.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../shared/jquery-ui/jquery-ui.min.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.resize.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../shared/jquery-ui/jquery-ui.min.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.resize.js"></script>
<script type="text/javascript">
$(function() {
@ -23,7 +29,7 @@
var d3 = [[0, 12], [7, 12], null, [7, 2.5], [12, 2.5]];
var placeholder = $("#placeholder");
var plot = $.plot(placeholder, [d1, d2, d3]);
var plot = $.plot(placeholder, [d1, d2, d3]);
// The plugin includes a jQuery plugin for adding resize events to any
// element. Add a callback so we can display the placeholder size.

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Selection</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.selection.js"></script>
<script type="text/javascript">
$(function() {
@ -25,7 +30,7 @@
label: "United States",
data: [[1990, 18.9], [1991, 18.7], [1992, 18.4], [1993, 19.3], [1994, 19.5], [1995, 19.3], [1996, 19.4], [1997, 20.2], [1998, 19.8], [1999, 19.9], [2000, 20.4], [2001, 20.1], [2002, 20.0], [2003, 19.8], [2004, 20.4]]
}, {
label: "Russia",
label: "Russia",
data: [[1992, 13.4], [1993, 12.2], [1994, 10.6], [1995, 10.2], [1996, 10.1], [1997, 9.7], [1998, 9.5], [1999, 9.7], [2000, 9.9], [2001, 9.9], [2002, 9.9], [2003, 10.3], [2004, 10.5]]
}, {
label: "United Kingdom",
@ -57,9 +62,12 @@
noColumns: 2
},
xaxis: {
autoScale: "exact",
tickDecimals: 0
},
yaxis: {
autoScale: "loose",
autoScaleMargin: 0.2,
min: 0
},
selection: {

View file

@ -5,10 +5,17 @@
<title>Flot Examples: Error Bars</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.errorbars.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.navigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/jquery.mousewheel.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.errorbars.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.legend.js"></script>
<script type="text/javascript">
$(function() {
@ -41,9 +48,9 @@
var data1_points = {
show: true,
radius: 5,
fillColor: "blue",
errorbars: "xy",
xerr: {show: true, asymmetric: true, upperCap: "-", lowerCap: "-"},
fillColor: "blue",
errorbars: "xy",
xerr: {show: true, asymmetric: true, upperCap: "-", lowerCap: "-"},
yerr: {show: true, color: "red", upperCap: "-"}
};
@ -56,7 +63,7 @@
var data2_points = {
show: true,
radius: 5,
errorbars: "y",
errorbars: "y",
yerr: {show:true, asymmetric:true, upperCap: drawArrow, lowerCap: drawSemiCircle}
};
@ -69,7 +76,7 @@
var data3_points = {
//do not show points
radius: 0,
errorbars: "y",
errorbars: "y",
yerr: {show:true, upperCap: "-", lowerCap: "-", radius: 5}
};
@ -85,7 +92,7 @@
}
var data = [
{color: "blue", points: data1_points, data: data1, label: "data1"},
{color: "blue", points: data1_points, data: data1, label: "data1"},
{color: "red", points: data2_points, data: data2, label: "data2"},
{color: "green", lines: {show: true}, points: data3_points, data: data3, label: "data3"},
// bars with errors
@ -104,10 +111,12 @@
}
},
xaxis: {
autoScale: 'none',
min: 0.6,
max: 3.1
},
yaxis: {
autoScale: 'none',
min: 0,
max: 3.5
},

View file

@ -75,10 +75,16 @@
}
</style>
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.pie.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.legend.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.pie.js"></script>
<script type="text/javascript">
$(function() {
@ -131,7 +137,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true
}
}
@ -157,7 +163,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true
}
},
@ -189,7 +195,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 1,
label: {
@ -239,7 +245,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 1,
label: {
@ -289,14 +295,14 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 1,
label: {
show: true,
radius: 3/4,
formatter: labelFormatter,
background: {
background: {
opacity: 0.5,
color: "#000"
}
@ -341,14 +347,14 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 3/4,
label: {
show: true,
radius: 3/4,
formatter: labelFormatter,
background: {
background: {
opacity: 0.5,
color: "#000"
}
@ -393,7 +399,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 1,
label: {
@ -439,7 +445,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
combine: {
color: "#999",
@ -479,7 +485,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 500,
label: {
@ -523,7 +529,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true,
radius: 1,
tilt: 0.5,
@ -583,7 +589,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
innerRadius: 0.5,
show: true
}
@ -611,7 +617,7 @@
$.plot(placeholder, data, {
series: {
pie: {
pie: {
show: true
}
},
@ -755,7 +761,7 @@
<li><b>opacity:</b> <i>0.5</i> - Opacity of the highlight overlay on top of the current pie slice. Currently this just uses a white overlay, but support for changing the color of the overlay will also be added at a later date.
</ul>
</ul>
<h2>Changes/Features</h2>
<ul>
<li style="list-style: none;"><i>v1.0 - November 20th, 2009 - Brian Medendorp</i></li>
@ -800,7 +806,7 @@
<li>Merged original pie modifications by Sergey Nosenko into the latest SVN version <i>(as of May 15th, 2009)</i> so that it will work with ie8.</li>
<li>Pie graph will now be centered in the canvas unless moved because of the legend or manually via the options. Additionally it prevents the pie from being moved beyond the edge of the canvas.</li>
<li>Modified the code related to the labelFormatter option to apply flot's legend labelFormatter first. This is so that the labels will be consistent, but still provide extra formatting for the positioned labels (such as adding the percentage value).</li>
<li>Positioned labels now have their backgrounds applied as a seperate element (much like the legend background) so that the opacity value can be set independently from the label itself (foreground). Additionally, the background color defaults to that of the matching slice.</li>
<li>Positioned labels now have their backgrounds applied as a separate element (much like the legend background) so that the opacity value can be set independently from the label itself (foreground). Additionally, the background color defaults to that of the matching slice.</li>
<li>As long as the labelOffset and radiusLimit are not set to hard values, the pie will be shrunk if the labels will extend outside the edge of the canvas</li>
<li>Added new options "radiusLimitFactor" and "radiusLimit" which limits how large the (visual) radius of the pie is in relation to the full radius (as calculated from the canvas dimensions) or a hard-pixel value (respectively). This allows for pushing the labels "outside" the pie.</li>
<li>Added a new option "labelHidePercent" that does not show the positioned labels of slices smaller than the specified percentage. This is to help prevent a bunch of overlapping labels from small slices.</li>

View file

@ -4,9 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Toggling Series</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.legend.js"></script>
<script type="text/javascript">
$(function() {
@ -15,7 +21,7 @@
"usa": {
label: "USA",
data: [[1988, 483994], [1989, 479060], [1990, 457648], [1991, 401949], [1992, 424705], [1993, 402375], [1994, 377867], [1995, 357382], [1996, 337946], [1997, 336185], [1998, 328611], [1999, 329421], [2000, 342172], [2001, 344932], [2002, 387303], [2003, 440813], [2004, 480451], [2005, 504638], [2006, 528692]]
},
},
"russia": {
label: "Russia",
data: [[1988, 218000], [1989, 203000], [1990, 171000], [1992, 42500], [1993, 37600], [1994, 36600], [1995, 21700], [1996, 19200], [1997, 21300], [1998, 13600], [1999, 14000], [2000, 19100], [2001, 21300], [2002, 23600], [2003, 25100], [2004, 26100], [2005, 31100], [2006, 34700]]
@ -51,7 +57,7 @@
++i;
});
// insert checkboxes
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append("<br/><input type='checkbox' name='" + key +
@ -75,6 +81,9 @@
if (data.length > 0) {
$.plot("#placeholder", data, {
legend: {
show: true
},
yaxis: {
min: 0
},

View file

@ -3,10 +3,15 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Series Types</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<link href="../examples.css" rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script type="text/javascript">
$(function() {

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Stacking</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.stack.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.stack.js"></script>
<script type="text/javascript">
$(function() {
@ -45,7 +50,10 @@
show: bars,
barWidth: 0.6
}
}
},
yaxis: {
autoScale:"exact"
}
});
}

View file

@ -3,11 +3,16 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Symbols</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.symbol.js"></script>
<link href="../examples.css" rel="stylesheet" type="text/css">
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.symbol.js"></script>
<script type="text/javascript">
$(function() {
@ -27,17 +32,20 @@
var data = [
{ data: generate(2, 1.8), points: { symbol: "circle" } },
{ data: generate(3, 1.5), points: { symbol: "square" } },
{ data: generate(4, 0.9), points: { symbol: "diamond" } },
{ data: generate(6, 1.4), points: { symbol: "triangle" } },
{ data: generate(7, 1.1), points: { symbol: "cross" } }
{ data: generate(3, 1.5), points: { symbol: "square" } },
{ data: generate(4, 0.9), points: { symbol: "diamond" } },
{ data: generate(6, 1.4), points: { symbol: "triangle" } },
{ data: generate(7, 1.1), points: { symbol: "cross" } },
{ data: generate(8, 1.0), points: { symbol: "ellipse" } },
{ data: generate(9, 1.3), points: { symbol: "plus" } }
];
$.plot("#placeholder", data, {
series: {
points: {
show: true,
radius: 3
radius: 3,
lineWidth: 2
}
},
grid: {

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Thresholds</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.threshold.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.threshold.js"></script>
<script type="text/javascript">
$(function() {

View file

@ -4,10 +4,20 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Tracking</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.crosshair.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.navigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touchNavigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.hover.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touch.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.legend.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.crosshair.js"></script>
<script type="text/javascript">
$(function() {
@ -22,16 +32,21 @@
{ data: sin, label: "sin(x) = -0.00"},
{ data: cos, label: "cos(x) = -0.00" }
], {
legend: {
show: true
},
series: {
lines: {
show: true
show: true,
lineWidth: 2
}
},
crosshair: {
mode: "x"
mode: "xy"
},
grid: {
hoverable: true,
clickable: true,
autoHighlight: false
},
yaxis: {
@ -40,7 +55,7 @@
}
});
var legends = $("#placeholder .legendLabel");
var legends = $("#placeholder .legendLayer text tspan");
legends.each(function () {
// fix the widths so they don't jump around
@ -53,34 +68,28 @@
function updateLegend() {
updateLegendTimeout = null;
var pos = latestPosition;
var axes = plot.getAxes();
if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
return;
}
var i, j, dataset = plot.getData();
for (i = 0; i < dataset.length; ++i) {
var series = dataset[i];
// Find the nearest points, x-wise
for (j = 0; j < series.data.length; ++j) {
if (series.data[j][0] > pos.x) {
break;
}
}
// Now Interpolate
var y,
p1 = series.data[j - 1],
p2 = series.data[j];
if (p1 == null) {
y = p2[1];
} else if (p2 == null) {
@ -88,17 +97,18 @@
} else {
y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
}
legends.eq(i).text(series.label.replace(/=.*/, "= " + y.toFixed(2)));
}
}
$("#placeholder").bind("plothover", function (event, pos, item) {
$("#placeholder").bind("plothover", function (event, pos, item) {
latestPosition = pos;
if (!updateLegendTimeout) {
updateLegendTimeout = setTimeout(updateLegend, 50);
}
});
}).bind("plotclick", function (event, pos, item) {
plot.lockCrosshair(pos);
});;
// Add the Flot version string to the footer

View file

@ -4,11 +4,21 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Visitors</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../lib/globalize.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.navigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touchNavigate.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.hover.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.touch.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.time.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.selection.js"></script>
<script type="text/javascript">
$(function() {
@ -53,7 +63,9 @@
var options = {
xaxis: {
mode: "time",
tickLength: 5
timeBase: "milliseconds",
tickLength: 5,
gridLines: false
},
selection: {
mode: "x"
@ -80,7 +92,7 @@
yaxis: {
ticks: [],
min: 0,
autoscaleMargin: 0.1
autoScaleMargin: 0.1
},
selection: {
mode: "x"

View file

@ -4,10 +4,15 @@
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Flot Examples: Selection and zooming</title>
<link href="../examples.css" rel="stylesheet" type="text/css">
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../../excanvas.min.js"></script><![endif]-->
<script language="javascript" type="text/javascript" src="../../jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../jquery.flot.selection.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.canvaswrapper.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.colorhelpers.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.saturated.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.browser.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.drawSeries.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.uiConstants.js"></script>
<script language="javascript" type="text/javascript" src="../../source/jquery.flot.selection.js"></script>
<script type="text/javascript">
$(function() {
@ -39,7 +44,11 @@
show: true
}
},
xaxis: {
autoScale: "none"
},
yaxis: {
autoScale:"none",
ticks: 10
},
selection: {
@ -65,9 +74,11 @@
shadowSize: 0
},
xaxis: {
autoScale: "none",
ticks: 4
},
yaxis: {
autoScale: "none",
ticks: 3,
min: -2,
max: 2

1428
vendors/Flot/excanvas.js vendored

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -1,27 +0,0 @@
{
"name": "flot",
"version": "0.8.3",
"title": "Flot",
"author": {
"name": "Ole Laursen",
"url": "https://github.com/OleLaursen"
},
"licenses": [{
"type": "MIT",
"url": "http://github.com/flot/flot/blob/master/LICENSE.txt"
}],
"dependencies": {
"jquery": ">=1.2.6"
},
"description": "Flot is a pure JavaScript plotting library for jQuery, with a focus on simple usage, attractive looks and interactive features.",
"keywords": ["plot", "chart", "graph", "visualization", "canvas", "graphics"],
"homepage": "http://www.flotcharts.org",
"docs": "http://github.com/flot/flot/blob/master/API.md",
"demo": "http://www.flotcharts.org/flot/examples/",
"bugs": "http://github.com/flot/flot/issues",
"maintainers": [{
"name": "David Schnur",
"email": "dnschnur@gmail.com",
"url": "http://github.com/dnschnur"
}]
}

View file

@ -1,180 +0,0 @@
/* Plugin for jQuery for working with colors.
*
* Version 1.1.
*
* Inspiration from jQuery color animation plugin by John Resig.
*
* Released under the MIT license by Ole Laursen, October 2009.
*
* Examples:
*
* $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
* var c = $.color.extract($("#mydiv"), 'background-color');
* console.log(c.r, c.g, c.b, c.a);
* $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
*
* Note that .scale() and .add() return the same modified object
* instead of making a new one.
*
* V. 1.1: Fix error handling so e.g. parsing an empty string does
* produce a color rather than just crashing.
*/
(function($) {
$.color = {};
// construct color object with some convenient chainable helpers
$.color.make = function (r, g, b, a) {
var o = {};
o.r = r || 0;
o.g = g || 0;
o.b = b || 0;
o.a = a != null ? a : 1;
o.add = function (c, d) {
for (var i = 0; i < c.length; ++i)
o[c.charAt(i)] += d;
return o.normalize();
};
o.scale = function (c, f) {
for (var i = 0; i < c.length; ++i)
o[c.charAt(i)] *= f;
return o.normalize();
};
o.toString = function () {
if (o.a >= 1.0) {
return "rgb("+[o.r, o.g, o.b].join(",")+")";
} else {
return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
}
};
o.normalize = function () {
function clamp(min, value, max) {
return value < min ? min: (value > max ? max: value);
}
o.r = clamp(0, parseInt(o.r), 255);
o.g = clamp(0, parseInt(o.g), 255);
o.b = clamp(0, parseInt(o.b), 255);
o.a = clamp(0, o.a, 1);
return o;
};
o.clone = function () {
return $.color.make(o.r, o.b, o.g, o.a);
};
return o.normalize();
}
// extract CSS color property from element, going up in the DOM
// if it's "transparent"
$.color.extract = function (elem, css) {
var c;
do {
c = elem.css(css).toLowerCase();
// keep going until we find an element that has color, or
// we hit the body or root (have no parent)
if (c != '' && c != 'transparent')
break;
elem = elem.parent();
} while (elem.length && !$.nodeName(elem.get(0), "body"));
// catch Safari's way of signalling transparent
if (c == "rgba(0, 0, 0, 0)")
c = "transparent";
return $.color.parse(c);
}
// parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
// returns color object, if parsing failed, you get black (0, 0,
// 0) out
$.color.parse = function (str) {
var res, m = $.color.make;
// Look for rgb(num,num,num)
if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
// Look for rgba(num,num,num,num)
if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
// Look for rgb(num%,num%,num%)
if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
// Look for rgba(num%,num%,num%,num)
if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
// Look for #a0b1c2
if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
// Look for #fff
if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
// Otherwise, we're most likely dealing with a named color
var name = $.trim(str).toLowerCase();
if (name == "transparent")
return m(255, 255, 255, 0);
else {
// default to black
res = lookupColors[name] || [0, 0, 0];
return m(res[0], res[1], res[2]);
}
}
var lookupColors = {
aqua:[0,255,255],
azure:[240,255,255],
beige:[245,245,220],
black:[0,0,0],
blue:[0,0,255],
brown:[165,42,42],
cyan:[0,255,255],
darkblue:[0,0,139],
darkcyan:[0,139,139],
darkgrey:[169,169,169],
darkgreen:[0,100,0],
darkkhaki:[189,183,107],
darkmagenta:[139,0,139],
darkolivegreen:[85,107,47],
darkorange:[255,140,0],
darkorchid:[153,50,204],
darkred:[139,0,0],
darksalmon:[233,150,122],
darkviolet:[148,0,211],
fuchsia:[255,0,255],
gold:[255,215,0],
green:[0,128,0],
indigo:[75,0,130],
khaki:[240,230,140],
lightblue:[173,216,230],
lightcyan:[224,255,255],
lightgreen:[144,238,144],
lightgrey:[211,211,211],
lightpink:[255,182,193],
lightyellow:[255,255,224],
lime:[0,255,0],
magenta:[255,0,255],
maroon:[128,0,0],
navy:[0,0,128],
olive:[128,128,0],
orange:[255,165,0],
pink:[255,192,203],
purple:[128,0,128],
violet:[128,0,128],
red:[255,0,0],
silver:[192,192,192],
white:[255,255,255],
yellow:[255,255,0]
};
})(jQuery);

View file

@ -1,345 +0,0 @@
/* Flot plugin for drawing all elements of a plot on the canvas.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Flot normally produces certain elements, like axis labels and the legend, using
HTML elements. This permits greater interactivity and customization, and often
looks better, due to cross-browser canvas text inconsistencies and limitations.
It can also be desirable to render the plot entirely in canvas, particularly
if the goal is to save it as an image, or if Flot is being used in a context
where the HTML DOM does not exist, as is the case within Node.js. This plugin
switches out Flot's standard drawing operations for canvas-only replacements.
Currently the plugin supports only axis labels, but it will eventually allow
every element of the plot to be rendered directly to canvas.
The plugin supports these options:
{
canvas: boolean
}
The "canvas" option controls whether full canvas drawing is enabled, making it
possible to toggle on and off. This is useful when a plot uses HTML text in the
browser, but needs to redraw with canvas text when exporting as an image.
*/
(function($) {
var options = {
canvas: true
};
var render, getTextInfo, addText;
// Cache the prototype hasOwnProperty for faster access
var hasOwnProperty = Object.prototype.hasOwnProperty;
function init(plot, classes) {
var Canvas = classes.Canvas;
// We only want to replace the functions once; the second time around
// we would just get our new function back. This whole replacing of
// prototype functions is a disaster, and needs to be changed ASAP.
if (render == null) {
getTextInfo = Canvas.prototype.getTextInfo,
addText = Canvas.prototype.addText,
render = Canvas.prototype.render;
}
// Finishes rendering the canvas, including overlaid text
Canvas.prototype.render = function() {
if (!plot.getOptions().canvas) {
return render.call(this);
}
var context = this.context,
cache = this._textCache;
// For each text layer, render elements marked as active
context.save();
context.textBaseline = "middle";
for (var layerKey in cache) {
if (hasOwnProperty.call(cache, layerKey)) {
var layerCache = cache[layerKey];
for (var styleKey in layerCache) {
if (hasOwnProperty.call(layerCache, styleKey)) {
var styleCache = layerCache[styleKey],
updateStyles = true;
for (var key in styleCache) {
if (hasOwnProperty.call(styleCache, key)) {
var info = styleCache[key],
positions = info.positions,
lines = info.lines;
// Since every element at this level of the cache have the
// same font and fill styles, we can just change them once
// using the values from the first element.
if (updateStyles) {
context.fillStyle = info.font.color;
context.font = info.font.definition;
updateStyles = false;
}
for (var i = 0, position; position = positions[i]; i++) {
if (position.active) {
for (var j = 0, line; line = position.lines[j]; j++) {
context.fillText(lines[j].text, line[0], line[1]);
}
} else {
positions.splice(i--, 1);
}
}
if (positions.length == 0) {
delete styleCache[key];
}
}
}
}
}
}
}
context.restore();
};
// Creates (if necessary) and returns a text info object.
//
// When the canvas option is set, the object looks like this:
//
// {
// width: Width of the text's bounding box.
// height: Height of the text's bounding box.
// positions: Array of positions at which this text is drawn.
// lines: [{
// height: Height of this line.
// widths: Width of this line.
// text: Text on this line.
// }],
// font: {
// definition: Canvas font property string.
// color: Color of the text.
// },
// }
//
// The positions array contains objects that look like this:
//
// {
// active: Flag indicating whether the text should be visible.
// lines: Array of [x, y] coordinates at which to draw the line.
// x: X coordinate at which to draw the text.
// y: Y coordinate at which to draw the text.
// }
Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
if (!plot.getOptions().canvas) {
return getTextInfo.call(this, layer, text, font, angle, width);
}
var textStyle, layerCache, styleCache, info;
// Cast the value to a string, in case we were given a number
text = "" + text;
// If the font is a font-spec object, generate a CSS definition
if (typeof font === "object") {
textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
} else {
textStyle = font;
}
// Retrieve (or create) the cache for the text's layer and styles
layerCache = this._textCache[layer];
if (layerCache == null) {
layerCache = this._textCache[layer] = {};
}
styleCache = layerCache[textStyle];
if (styleCache == null) {
styleCache = layerCache[textStyle] = {};
}
info = styleCache[text];
if (info == null) {
var context = this.context;
// If the font was provided as CSS, create a div with those
// classes and examine it to generate a canvas font spec.
if (typeof font !== "object") {
var element = $("<div>&nbsp;</div>")
.css("position", "absolute")
.addClass(typeof font === "string" ? font : null)
.appendTo(this.getTextLayer(layer));
font = {
lineHeight: element.height(),
style: element.css("font-style"),
variant: element.css("font-variant"),
weight: element.css("font-weight"),
family: element.css("font-family"),
color: element.css("color")
};
// Setting line-height to 1, without units, sets it equal
// to the font-size, even if the font-size is abstract,
// like 'smaller'. This enables us to read the real size
// via the element's height, working around browsers that
// return the literal 'smaller' value.
font.size = element.css("line-height", 1).height();
element.remove();
}
textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
// Create a new info object, initializing the dimensions to
// zero so we can count them up line-by-line.
info = styleCache[text] = {
width: 0,
height: 0,
positions: [],
lines: [],
font: {
definition: textStyle,
color: font.color
}
};
context.save();
context.font = textStyle;
// Canvas can't handle multi-line strings; break on various
// newlines, including HTML brs, to build a list of lines.
// Note that we could split directly on regexps, but IE < 9 is
// broken; revisit when we drop IE 7/8 support.
var lines = (text + "").replace(/<br ?\/?>|\r\n|\r/g, "\n").split("\n");
for (var i = 0; i < lines.length; ++i) {
var lineText = lines[i],
measured = context.measureText(lineText);
info.width = Math.max(measured.width, info.width);
info.height += font.lineHeight;
info.lines.push({
text: lineText,
width: measured.width,
height: font.lineHeight
});
}
context.restore();
}
return info;
};
// Adds a text string to the canvas text overlay.
Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
if (!plot.getOptions().canvas) {
return addText.call(this, layer, x, y, text, font, angle, width, halign, valign);
}
var info = this.getTextInfo(layer, text, font, angle, width),
positions = info.positions,
lines = info.lines;
// Text is drawn with baseline 'middle', which we need to account
// for by adding half a line's height to the y position.
y += info.height / lines.length / 2;
// Tweak the initial y-position to match vertical alignment
if (valign == "middle") {
y = Math.round(y - info.height / 2);
} else if (valign == "bottom") {
y = Math.round(y - info.height);
} else {
y = Math.round(y);
}
// FIXME: LEGACY BROWSER FIX
// AFFECTS: Opera < 12.00
// Offset the y coordinate, since Opera is off pretty
// consistently compared to the other browsers.
if (!!(window.opera && window.opera.version().split(".")[0] < 12)) {
y -= 2;
}
// Determine whether this text already exists at this position.
// If so, mark it for inclusion in the next render pass.
for (var i = 0, position; position = positions[i]; i++) {
if (position.x == x && position.y == y) {
position.active = true;
return;
}
}
// If the text doesn't exist at this position, create a new entry
position = {
active: true,
lines: [],
x: x,
y: y
};
positions.push(position);
// Fill in the x & y positions of each line, adjusting them
// individually for horizontal alignment.
for (var i = 0, line; line = lines[i]; i++) {
if (halign == "center") {
position.lines.push([Math.round(x - line.width / 2), y]);
} else if (halign == "right") {
position.lines.push([Math.round(x - line.width), y]);
} else {
position.lines.push([Math.round(x), y]);
}
y += line.height;
}
};
}
$.plot.plugins.push({
init: init,
options: options,
name: "canvas",
version: "1.0"
});
})(jQuery);

View file

@ -1,190 +0,0 @@
/* Flot plugin for plotting textual data or categories.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
allows you to plot such a dataset directly.
To enable it, you must specify mode: "categories" on the axis with the textual
labels, e.g.
$.plot("#placeholder", data, { xaxis: { mode: "categories" } });
By default, the labels are ordered as they are met in the data series. If you
need a different ordering, you can specify "categories" on the axis options
and list the categories there:
xaxis: {
mode: "categories",
categories: ["February", "March", "April"]
}
If you need to customize the distances between the categories, you can specify
"categories" as an object mapping labels to values
xaxis: {
mode: "categories",
categories: { "February": 1, "March": 3, "April": 4 }
}
If you don't specify all categories, the remaining categories will be numbered
from the max value plus 1 (with a spacing of 1 between each).
Internally, the plugin works by transforming the input data through an auto-
generated mapping where the first category becomes 0, the second 1, etc.
Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
is visible in hover and click events that return numbers rather than the
category labels). The plugin also overrides the tick generator to spit out the
categories as ticks instead of the values.
If you need to map a value back to its label, the mapping is always accessible
as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
*/
(function ($) {
var options = {
xaxis: {
categories: null
},
yaxis: {
categories: null
}
};
function processRawData(plot, series, data, datapoints) {
// if categories are enabled, we need to disable
// auto-transformation to numbers so the strings are intact
// for later processing
var xCategories = series.xaxis.options.mode == "categories",
yCategories = series.yaxis.options.mode == "categories";
if (!(xCategories || yCategories))
return;
var format = datapoints.format;
if (!format) {
// FIXME: auto-detection should really not be defined here
var s = series;
format = [];
format.push({ x: true, number: true, required: true });
format.push({ y: true, number: true, required: true });
if (s.bars.show || (s.lines.show && s.lines.fill)) {
var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
if (s.bars.horizontal) {
delete format[format.length - 1].y;
format[format.length - 1].x = true;
}
}
datapoints.format = format;
}
for (var m = 0; m < format.length; ++m) {
if (format[m].x && xCategories)
format[m].number = false;
if (format[m].y && yCategories)
format[m].number = false;
}
}
function getNextIndex(categories) {
var index = -1;
for (var v in categories)
if (categories[v] > index)
index = categories[v];
return index + 1;
}
function categoriesTickGenerator(axis) {
var res = [];
for (var label in axis.categories) {
var v = axis.categories[label];
if (v >= axis.min && v <= axis.max)
res.push([v, label]);
}
res.sort(function (a, b) { return a[0] - b[0]; });
return res;
}
function setupCategoriesForAxis(series, axis, datapoints) {
if (series[axis].options.mode != "categories")
return;
if (!series[axis].categories) {
// parse options
var c = {}, o = series[axis].options.categories || {};
if ($.isArray(o)) {
for (var i = 0; i < o.length; ++i)
c[o[i]] = i;
}
else {
for (var v in o)
c[v] = o[v];
}
series[axis].categories = c;
}
// fix ticks
if (!series[axis].options.ticks)
series[axis].options.ticks = categoriesTickGenerator;
transformPointsOnAxis(datapoints, axis, series[axis].categories);
}
function transformPointsOnAxis(datapoints, axis, categories) {
// go through the points, transforming them
var points = datapoints.points,
ps = datapoints.pointsize,
format = datapoints.format,
formatColumn = axis.charAt(0),
index = getNextIndex(categories);
for (var i = 0; i < points.length; i += ps) {
if (points[i] == null)
continue;
for (var m = 0; m < ps; ++m) {
var val = points[i + m];
if (val == null || !format[m][formatColumn])
continue;
if (!(val in categories)) {
categories[val] = index;
++index;
}
points[i + m] = categories[val];
}
}
}
function processDatapoints(plot, series, datapoints) {
setupCategoriesForAxis(series, "xaxis", datapoints);
setupCategoriesForAxis(series, "yaxis", datapoints);
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.processDatapoints.push(processDatapoints);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'categories',
version: '1.0'
});
})(jQuery);

View file

@ -1,176 +0,0 @@
/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
crosshair: {
mode: null or "x" or "y" or "xy"
color: color
lineWidth: number
}
Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
crosshair that lets you trace the values on the x axis, "y" enables a
horizontal crosshair and "xy" enables them both. "color" is the color of the
crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
the drawn lines (default is 1).
The plugin also adds four public methods:
- setCrosshair( pos )
Set the position of the crosshair. Note that this is cleared if the user
moves the mouse. "pos" is in coordinates of the plot and should be on the
form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
axes), which is coincidentally the same format as what you get from a
"plothover" event. If "pos" is null, the crosshair is cleared.
- clearCrosshair()
Clear the crosshair.
- lockCrosshair(pos)
Cause the crosshair to lock to the current location, no longer updating if
the user moves the mouse. Optionally supply a position (passed on to
setCrosshair()) to move it to.
Example usage:
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
$("#graph").bind( "plothover", function ( evt, position, item ) {
if ( item ) {
// Lock the crosshair to the data point being hovered
myFlot.lockCrosshair({
x: item.datapoint[ 0 ],
y: item.datapoint[ 1 ]
});
} else {
// Return normal crosshair operation
myFlot.unlockCrosshair();
}
});
- unlockCrosshair()
Free the crosshair to move again after locking it.
*/
(function ($) {
var options = {
crosshair: {
mode: null, // one of null, "x", "y" or "xy",
color: "rgba(170, 0, 0, 0.80)",
lineWidth: 1
}
};
function init(plot) {
// position of crosshair in pixels
var crosshair = { x: -1, y: -1, locked: false };
plot.setCrosshair = function setCrosshair(pos) {
if (!pos)
crosshair.x = -1;
else {
var o = plot.p2c(pos);
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
}
plot.triggerRedrawOverlay();
};
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
plot.lockCrosshair = function lockCrosshair(pos) {
if (pos)
plot.setCrosshair(pos);
crosshair.locked = true;
};
plot.unlockCrosshair = function unlockCrosshair() {
crosshair.locked = false;
};
function onMouseOut(e) {
if (crosshair.locked)
return;
if (crosshair.x != -1) {
crosshair.x = -1;
plot.triggerRedrawOverlay();
}
}
function onMouseMove(e) {
if (crosshair.locked)
return;
if (plot.getSelection && plot.getSelection()) {
crosshair.x = -1; // hide the crosshair while selecting
return;
}
var offset = plot.offset();
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
plot.triggerRedrawOverlay();
}
plot.hooks.bindEvents.push(function (plot, eventHolder) {
if (!plot.getOptions().crosshair.mode)
return;
eventHolder.mouseout(onMouseOut);
eventHolder.mousemove(onMouseMove);
});
plot.hooks.drawOverlay.push(function (plot, ctx) {
var c = plot.getOptions().crosshair;
if (!c.mode)
return;
var plotOffset = plot.getPlotOffset();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
if (crosshair.x != -1) {
var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
ctx.strokeStyle = c.color;
ctx.lineWidth = c.lineWidth;
ctx.lineJoin = "round";
ctx.beginPath();
if (c.mode.indexOf("x") != -1) {
var drawX = Math.floor(crosshair.x) + adj;
ctx.moveTo(drawX, 0);
ctx.lineTo(drawX, plot.height());
}
if (c.mode.indexOf("y") != -1) {
var drawY = Math.floor(crosshair.y) + adj;
ctx.moveTo(0, drawY);
ctx.lineTo(plot.width(), drawY);
}
ctx.stroke();
}
ctx.restore();
});
plot.hooks.shutdown.push(function (plot, eventHolder) {
eventHolder.unbind("mouseout", onMouseOut);
eventHolder.unbind("mousemove", onMouseMove);
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'crosshair',
version: '1.0'
});
})(jQuery);

View file

@ -1,353 +0,0 @@
/* Flot plugin for plotting error bars.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Error bars are used to show standard deviation and other statistical
properties in a plot.
* Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
This plugin allows you to plot error-bars over points. Set "errorbars" inside
the points series to the axis name over which there will be error values in
your data array (*even* if you do not intend to plot them later, by setting
"show: null" on xerr/yerr).
The plugin supports these options:
series: {
points: {
errorbars: "x" or "y" or "xy",
xerr: {
show: null/false or true,
asymmetric: null/false or true,
upperCap: null or "-" or function,
lowerCap: null or "-" or function,
color: null or color,
radius: null or number
},
yerr: { same options as xerr }
}
}
Each data point array is expected to be of the type:
"x" [ x, y, xerr ]
"y" [ x, y, yerr ]
"xy" [ x, y, xerr, yerr ]
Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric
error-bars on X and asymmetric on Y would be:
[ x, y, xerr, yerr_lower, yerr_upper ]
By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
draw a small cap perpendicular to the error bar. They can also be set to a
user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.
function drawSemiCircle( ctx, x, y, radius ) {
ctx.beginPath();
ctx.arc( x, y, radius, 0, Math.PI, false );
ctx.moveTo( x - radius, y );
ctx.lineTo( x + radius, y );
ctx.stroke();
}
Color and radius both default to the same ones of the points series if not
set. The independent radius parameter on xerr/yerr is useful for the case when
we may want to add error-bars to a line, without showing the interconnecting
points (with radius: 0), and still showing end caps on the error-bars.
shadowSize and lineWidth are derived as well from the points series.
*/
(function ($) {
var options = {
series: {
points: {
errorbars: null, //should be 'x', 'y' or 'xy'
xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
}
}
};
function processRawData(plot, series, data, datapoints){
if (!series.points.errorbars)
return;
// x,y values
var format = [
{ x: true, number: true, required: true },
{ y: true, number: true, required: true }
];
var errors = series.points.errorbars;
// error bars - first X then Y
if (errors == 'x' || errors == 'xy') {
// lower / upper error
if (series.points.xerr.asymmetric) {
format.push({ x: true, number: true, required: true });
format.push({ x: true, number: true, required: true });
} else
format.push({ x: true, number: true, required: true });
}
if (errors == 'y' || errors == 'xy') {
// lower / upper error
if (series.points.yerr.asymmetric) {
format.push({ y: true, number: true, required: true });
format.push({ y: true, number: true, required: true });
} else
format.push({ y: true, number: true, required: true });
}
datapoints.format = format;
}
function parseErrors(series, i){
var points = series.datapoints.points;
// read errors from points array
var exl = null,
exu = null,
eyl = null,
eyu = null;
var xerr = series.points.xerr,
yerr = series.points.yerr;
var eb = series.points.errorbars;
// error bars - first X
if (eb == 'x' || eb == 'xy') {
if (xerr.asymmetric) {
exl = points[i + 2];
exu = points[i + 3];
if (eb == 'xy')
if (yerr.asymmetric){
eyl = points[i + 4];
eyu = points[i + 5];
} else eyl = points[i + 4];
} else {
exl = points[i + 2];
if (eb == 'xy')
if (yerr.asymmetric) {
eyl = points[i + 3];
eyu = points[i + 4];
} else eyl = points[i + 3];
}
// only Y
} else if (eb == 'y')
if (yerr.asymmetric) {
eyl = points[i + 2];
eyu = points[i + 3];
} else eyl = points[i + 2];
// symmetric errors?
if (exu == null) exu = exl;
if (eyu == null) eyu = eyl;
var errRanges = [exl, exu, eyl, eyu];
// nullify if not showing
if (!xerr.show){
errRanges[0] = null;
errRanges[1] = null;
}
if (!yerr.show){
errRanges[2] = null;
errRanges[3] = null;
}
return errRanges;
}
function drawSeriesErrors(plot, ctx, s){
var points = s.datapoints.points,
ps = s.datapoints.pointsize,
ax = [s.xaxis, s.yaxis],
radius = s.points.radius,
err = [s.points.xerr, s.points.yerr];
//sanity check, in case some inverted axis hack is applied to flot
var invertX = false;
if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
invertX = true;
var tmp = err[0].lowerCap;
err[0].lowerCap = err[0].upperCap;
err[0].upperCap = tmp;
}
var invertY = false;
if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
invertY = true;
var tmp = err[1].lowerCap;
err[1].lowerCap = err[1].upperCap;
err[1].upperCap = tmp;
}
for (var i = 0; i < s.datapoints.points.length; i += ps) {
//parse
var errRanges = parseErrors(s, i);
//cycle xerr & yerr
for (var e = 0; e < err.length; e++){
var minmax = [ax[e].min, ax[e].max];
//draw this error?
if (errRanges[e * err.length]){
//data coordinates
var x = points[i],
y = points[i + 1];
//errorbar ranges
var upper = [x, y][e] + errRanges[e * err.length + 1],
lower = [x, y][e] - errRanges[e * err.length];
//points outside of the canvas
if (err[e].err == 'x')
if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
continue;
if (err[e].err == 'y')
if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
continue;
// prevent errorbars getting out of the canvas
var drawUpper = true,
drawLower = true;
if (upper > minmax[1]) {
drawUpper = false;
upper = minmax[1];
}
if (lower < minmax[0]) {
drawLower = false;
lower = minmax[0];
}
//sanity check, in case some inverted axis hack is applied to flot
if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
//swap coordinates
var tmp = lower;
lower = upper;
upper = tmp;
tmp = drawLower;
drawLower = drawUpper;
drawUpper = tmp;
tmp = minmax[0];
minmax[0] = minmax[1];
minmax[1] = tmp;
}
// convert to pixels
x = ax[0].p2c(x),
y = ax[1].p2c(y),
upper = ax[e].p2c(upper);
lower = ax[e].p2c(lower);
minmax[0] = ax[e].p2c(minmax[0]);
minmax[1] = ax[e].p2c(minmax[1]);
//same style as points by default
var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
//shadow as for points
if (lw > 0 && sw > 0) {
var w = sw / 2;
ctx.lineWidth = w;
ctx.strokeStyle = "rgba(0,0,0,0.1)";
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
ctx.strokeStyle = "rgba(0,0,0,0.2)";
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
}
ctx.strokeStyle = err[e].color? err[e].color: s.color;
ctx.lineWidth = lw;
//draw it
drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
}
}
}
}
function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
//shadow offset
y += offset;
upper += offset;
lower += offset;
// error bar - avoid plotting over circles
if (err.err == 'x'){
if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
else drawUpper = false;
if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
else drawLower = false;
}
else {
if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
else drawUpper = false;
if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
else drawLower = false;
}
//internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
//this is a way to get errorbars on lines without visible connecting dots
radius = err.radius != null? err.radius: radius;
// upper cap
if (drawUpper) {
if (err.upperCap == '-'){
if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
} else if ($.isFunction(err.upperCap)){
if (err.err=='x') err.upperCap(ctx, upper, y, radius);
else err.upperCap(ctx, x, upper, radius);
}
}
// lower cap
if (drawLower) {
if (err.lowerCap == '-'){
if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
} else if ($.isFunction(err.lowerCap)){
if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
else err.lowerCap(ctx, x, lower, radius);
}
}
}
function drawPath(ctx, pts){
ctx.beginPath();
ctx.moveTo(pts[0][0], pts[0][1]);
for (var p=1; p < pts.length; p++)
ctx.lineTo(pts[p][0], pts[p][1]);
ctx.stroke();
}
function draw(plot, ctx){
var plotOffset = plot.getPlotOffset();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
$.each(plot.getData(), function (i, s) {
if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
drawSeriesErrors(plot, ctx, s);
});
ctx.restore();
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.draw.push(draw);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'errorbars',
version: '1.0'
});
})(jQuery);

View file

@ -1,226 +0,0 @@
/* Flot plugin for computing bottoms for filled line and bar charts.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The case: you've got two series that you want to fill the area between. In Flot
terms, you need to use one as the fill bottom of the other. You can specify the
bottom of each data point as the third coordinate manually, or you can use this
plugin to compute it for you.
In order to name the other series, you need to give it an id, like this:
var dataset = [
{ data: [ ... ], id: "foo" } , // use default bottom
{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
];
$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
As a convenience, if the id given is a number that doesn't appear as an id in
the series, it is interpreted as the index in the array instead (so fillBetween:
0 can also mean the first series).
Internally, the plugin modifies the datapoints in each series. For line series,
extra data points might be inserted through interpolation. Note that at points
where the bottom line is not defined (due to a null point or start/end of line),
the current line will show a gap too. The algorithm comes from the
jquery.flot.stack.js plugin, possibly some code could be shared.
*/
(function ( $ ) {
var options = {
series: {
fillBetween: null // or number
}
};
function init( plot ) {
function findBottomSeries( s, allseries ) {
var i;
for ( i = 0; i < allseries.length; ++i ) {
if ( allseries[ i ].id === s.fillBetween ) {
return allseries[ i ];
}
}
if ( typeof s.fillBetween === "number" ) {
if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
return null;
}
return allseries[ s.fillBetween ];
}
return null;
}
function computeFillBottoms( plot, s, datapoints ) {
if ( s.fillBetween == null ) {
return;
}
var other = findBottomSeries( s, plot.getData() );
if ( !other ) {
return;
}
var ps = datapoints.pointsize,
points = datapoints.points,
otherps = other.datapoints.pointsize,
otherpoints = other.datapoints.points,
newpoints = [],
px, py, intery, qx, qy, bottom,
withlines = s.lines.show,
withbottom = ps > 2 && datapoints.format[2].y,
withsteps = withlines && s.lines.steps,
fromgap = true,
i = 0,
j = 0,
l, m;
while ( true ) {
if ( i >= points.length ) {
break;
}
l = newpoints.length;
if ( points[ i ] == null ) {
// copy gaps
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
i += ps;
} else if ( j >= otherpoints.length ) {
// for lines, we can't use the rest of the points
if ( !withlines ) {
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
}
i += ps;
} else if ( otherpoints[ j ] == null ) {
// oops, got a gap
for ( m = 0; m < ps; ++m ) {
newpoints.push( null );
}
fromgap = true;
j += otherps;
} else {
// cases where we actually got two points
px = points[ i ];
py = points[ i + 1 ];
qx = otherpoints[ j ];
qy = otherpoints[ j + 1 ];
bottom = 0;
if ( px === qx ) {
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
//newpoints[ l + 1 ] += qy;
bottom = qy;
i += ps;
j += otherps;
} else if ( px > qx ) {
// we got past point below, might need to
// insert interpolated extra point
if ( withlines && i > 0 && points[ i - ps ] != null ) {
intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
newpoints.push( qx );
newpoints.push( intery );
for ( m = 2; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
bottom = qy;
}
j += otherps;
} else { // px < qx
// if we come from a gap, we just skip this point
if ( fromgap && withlines ) {
i += ps;
continue;
}
for ( m = 0; m < ps; ++m ) {
newpoints.push( points[ i + m ] );
}
// we might be able to interpolate a point below,
// this can give us a better y
if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
}
//newpoints[l + 1] += bottom;
i += ps;
}
fromgap = false;
if ( l !== newpoints.length && withbottom ) {
newpoints[ l + 2 ] = bottom;
}
}
// maintain the line steps invariant
if ( withsteps && l !== newpoints.length && l > 0 &&
newpoints[ l ] !== null &&
newpoints[ l ] !== newpoints[ l - ps ] &&
newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
for (m = 0; m < ps; ++m) {
newpoints[ l + ps + m ] = newpoints[ l + m ];
}
newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
}
}
datapoints.points = newpoints;
}
plot.hooks.processDatapoints.push( computeFillBottoms );
}
$.plot.plugins.push({
init: init,
options: options,
name: "fillbetween",
version: "1.0"
});
})(jQuery);

View file

@ -1,241 +0,0 @@
/* Flot plugin for plotting images.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
(x2, y2) are where you intend the two opposite corners of the image to end up
in the plot. Image must be a fully loaded Javascript image (you can make one
with new Image()). If the image is not complete, it's skipped when plotting.
There are two helpers included for retrieving images. The easiest work the way
that you put in URLs instead of images in the data, like this:
[ "myimage.png", 0, 0, 10, 10 ]
Then call $.plot.image.loadData( data, options, callback ) where data and
options are the same as you pass in to $.plot. This loads the images, replaces
the URLs in the data with the corresponding images and calls "callback" when
all images are loaded (or failed loading). In the callback, you can then call
$.plot with the data set. See the included example.
A more low-level helper, $.plot.image.load(urls, callback) is also included.
Given a list of URLs, it calls callback with an object mapping from URL to
Image object when all images are loaded or have failed loading.
The plugin supports these options:
series: {
images: {
show: boolean
anchor: "corner" or "center"
alpha: [ 0, 1 ]
}
}
They can be specified for a specific series:
$.plot( $("#placeholder"), [{
data: [ ... ],
images: { ... }
])
Note that because the data format is different from usual data points, you
can't use images with anything else in a specific data series.
Setting "anchor" to "center" causes the pixels in the image to be anchored at
the corner pixel centers inside of at the pixel corners, effectively letting
half a pixel stick out to each side in the plot.
A possible future direction could be support for tiling for large images (like
Google Maps).
*/
(function ($) {
var options = {
series: {
images: {
show: false,
alpha: 1,
anchor: "corner" // or "center"
}
}
};
$.plot.image = {};
$.plot.image.loadDataImages = function (series, options, callback) {
var urls = [], points = [];
var defaultShow = options.series.images.show;
$.each(series, function (i, s) {
if (!(defaultShow || s.images.show))
return;
if (s.data)
s = s.data;
$.each(s, function (i, p) {
if (typeof p[0] == "string") {
urls.push(p[0]);
points.push(p);
}
});
});
$.plot.image.load(urls, function (loadedImages) {
$.each(points, function (i, p) {
var url = p[0];
if (loadedImages[url])
p[0] = loadedImages[url];
});
callback();
});
}
$.plot.image.load = function (urls, callback) {
var missing = urls.length, loaded = {};
if (missing == 0)
callback({});
$.each(urls, function (i, url) {
var handler = function () {
--missing;
loaded[url] = this;
if (missing == 0)
callback(loaded);
};
$('<img />').load(handler).error(handler).attr('src', url);
});
};
function drawSeries(plot, ctx, series) {
var plotOffset = plot.getPlotOffset();
if (!series.images || !series.images.show)
return;
var points = series.datapoints.points,
ps = series.datapoints.pointsize;
for (var i = 0; i < points.length; i += ps) {
var img = points[i],
x1 = points[i + 1], y1 = points[i + 2],
x2 = points[i + 3], y2 = points[i + 4],
xaxis = series.xaxis, yaxis = series.yaxis,
tmp;
// actually we should check img.complete, but it
// appears to be a somewhat unreliable indicator in
// IE6 (false even after load event)
if (!img || img.width <= 0 || img.height <= 0)
continue;
if (x1 > x2) {
tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y1 > y2) {
tmp = y2;
y2 = y1;
y1 = tmp;
}
// if the anchor is at the center of the pixel, expand the
// image by 1/2 pixel in each direction
if (series.images.anchor == "center") {
tmp = 0.5 * (x2-x1) / (img.width - 1);
x1 -= tmp;
x2 += tmp;
tmp = 0.5 * (y2-y1) / (img.height - 1);
y1 -= tmp;
y2 += tmp;
}
// clip
if (x1 == x2 || y1 == y2 ||
x1 >= xaxis.max || x2 <= xaxis.min ||
y1 >= yaxis.max || y2 <= yaxis.min)
continue;
var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
if (x1 < xaxis.min) {
sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
x1 = xaxis.min;
}
if (x2 > xaxis.max) {
sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
x2 = xaxis.max;
}
if (y1 < yaxis.min) {
sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
y1 = yaxis.min;
}
if (y2 > yaxis.max) {
sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
y2 = yaxis.max;
}
x1 = xaxis.p2c(x1);
x2 = xaxis.p2c(x2);
y1 = yaxis.p2c(y1);
y2 = yaxis.p2c(y2);
// the transformation may have swapped us
if (x1 > x2) {
tmp = x2;
x2 = x1;
x1 = tmp;
}
if (y1 > y2) {
tmp = y2;
y2 = y1;
y1 = tmp;
}
tmp = ctx.globalAlpha;
ctx.globalAlpha *= series.images.alpha;
ctx.drawImage(img,
sx1, sy1, sx2 - sx1, sy2 - sy1,
x1 + plotOffset.left, y1 + plotOffset.top,
x2 - x1, y2 - y1);
ctx.globalAlpha = tmp;
}
}
function processRawData(plot, series, data, datapoints) {
if (!series.images.show)
return;
// format is Image, x1, y1, x2, y2 (opposite corners)
datapoints.format = [
{ required: true },
{ x: true, number: true, required: true },
{ y: true, number: true, required: true },
{ x: true, number: true, required: true },
{ y: true, number: true, required: true }
];
}
function init(plot) {
plot.hooks.processRawData.push(processRawData);
plot.hooks.drawSeries.push(drawSeries);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'image',
version: '1.1'
});
})(jQuery);

File diff suppressed because it is too large Load diff

View file

@ -1,346 +0,0 @@
/* Flot plugin for adding the ability to pan and zoom the plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The default behaviour is double click and scrollwheel up/down to zoom in, drag
to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
plot.pan( offset ) so you easily can add custom controls. It also fires
"plotpan" and "plotzoom" events, useful for synchronizing plots.
The plugin supports these options:
zoom: {
interactive: false
trigger: "dblclick" // or "click" for single click
amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
}
pan: {
interactive: false
cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
frameRate: 20
}
xaxis, yaxis, x2axis, y2axis: {
zoomRange: null // or [ number, number ] (min range, max range) or false
panRange: null // or [ number, number ] (min, max) or false
}
"interactive" enables the built-in drag/click behaviour. If you enable
interactive for pan, then you'll have a basic plot that supports moving
around; the same for zoom.
"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
the current viewport.
"cursor" is a standard CSS mouse cursor string used for visual feedback to the
user when dragging.
"frameRate" specifies the maximum number of times per second the plot will
update itself while the user is panning around on it (set to null to disable
intermediate pans, the plot will then not update until the mouse button is
released).
"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
[1, 100] the zoom will never scale the axis so that the difference between min
and max is smaller than 1 or larger than 100. You can set either end to null
to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
will be disabled.
"panRange" confines the panning to stay within a range, e.g. with panRange:
[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
will be disabled.
Example API usage:
plot = $.plot(...);
// zoom default amount in on the pixel ( 10, 20 )
plot.zoom({ center: { left: 10, top: 20 } });
// zoom out again
plot.zoomOut({ center: { left: 10, top: 20 } });
// zoom 200% in on the pixel (10, 20)
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
// pan 100 pixels to the left and 20 down
plot.pan({ left: -100, top: 20 })
Here, "center" specifies where the center of the zooming should happen. Note
that this is defined in pixel space, not the space of the data points (you can
use the p2c helpers on the axes in Flot to help you convert between these).
"amount" is the amount to zoom the viewport relative to the current range, so
1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
can set the default in the options.
*/
// First two dependencies, jquery.event.drag.js and
// jquery.mousewheel.js, we put them inline here to save people the
// effort of downloading them.
/*
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
*/
(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);
/* jquery.mousewheel.min.js
* Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
* Licensed under the MIT License (LICENSE.txt).
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
* Thanks to: Seamus Leahy for adding deltaX and deltaY
*
* Version: 3.0.6
*
* Requires: 1.2.2+
*/
(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
(function ($) {
var options = {
xaxis: {
zoomRange: null, // or [number, number] (min range, max range)
panRange: null // or [number, number] (min, max)
},
zoom: {
interactive: false,
trigger: "dblclick", // or "click" for single click
amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
},
pan: {
interactive: false,
cursor: "move",
frameRate: 20
}
};
function init(plot) {
function onZoomClick(e, zoomOut) {
var c = plot.offset();
c.left = e.pageX - c.left;
c.top = e.pageY - c.top;
if (zoomOut)
plot.zoomOut({ center: c });
else
plot.zoom({ center: c });
}
function onMouseWheel(e, delta) {
e.preventDefault();
onZoomClick(e, delta < 0);
return false;
}
var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
panTimeout = null;
function onDragStart(e) {
if (e.which != 1) // only accept left-click
return false;
var c = plot.getPlaceholder().css('cursor');
if (c)
prevCursor = c;
plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
prevPageX = e.pageX;
prevPageY = e.pageY;
}
function onDrag(e) {
var frameRate = plot.getOptions().pan.frameRate;
if (panTimeout || !frameRate)
return;
panTimeout = setTimeout(function () {
plot.pan({ left: prevPageX - e.pageX,
top: prevPageY - e.pageY });
prevPageX = e.pageX;
prevPageY = e.pageY;
panTimeout = null;
}, 1 / frameRate * 1000);
}
function onDragEnd(e) {
if (panTimeout) {
clearTimeout(panTimeout);
panTimeout = null;
}
plot.getPlaceholder().css('cursor', prevCursor);
plot.pan({ left: prevPageX - e.pageX,
top: prevPageY - e.pageY });
}
function bindEvents(plot, eventHolder) {
var o = plot.getOptions();
if (o.zoom.interactive) {
eventHolder[o.zoom.trigger](onZoomClick);
eventHolder.mousewheel(onMouseWheel);
}
if (o.pan.interactive) {
eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
eventHolder.bind("drag", onDrag);
eventHolder.bind("dragend", onDragEnd);
}
}
plot.zoomOut = function (args) {
if (!args)
args = {};
if (!args.amount)
args.amount = plot.getOptions().zoom.amount;
args.amount = 1 / args.amount;
plot.zoom(args);
};
plot.zoom = function (args) {
if (!args)
args = {};
var c = args.center,
amount = args.amount || plot.getOptions().zoom.amount,
w = plot.width(), h = plot.height();
if (!c)
c = { left: w / 2, top: h / 2 };
var xf = c.left / w,
yf = c.top / h,
minmax = {
x: {
min: c.left - xf * w / amount,
max: c.left + (1 - xf) * w / amount
},
y: {
min: c.top - yf * h / amount,
max: c.top + (1 - yf) * h / amount
}
};
$.each(plot.getAxes(), function(_, axis) {
var opts = axis.options,
min = minmax[axis.direction].min,
max = minmax[axis.direction].max,
zr = opts.zoomRange,
pr = opts.panRange;
if (zr === false) // no zooming on this axis
return;
min = axis.c2p(min);
max = axis.c2p(max);
if (min > max) {
// make sure min < max
var tmp = min;
min = max;
max = tmp;
}
//Check that we are in panRange
if (pr) {
if (pr[0] != null && min < pr[0]) {
min = pr[0];
}
if (pr[1] != null && max > pr[1]) {
max = pr[1];
}
}
var range = max - min;
if (zr &&
((zr[0] != null && range < zr[0] && amount >1) ||
(zr[1] != null && range > zr[1] && amount <1)))
return;
opts.min = min;
opts.max = max;
});
plot.setupGrid();
plot.draw();
if (!args.preventEvent)
plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
};
plot.pan = function (args) {
var delta = {
x: +args.left,
y: +args.top
};
if (isNaN(delta.x))
delta.x = 0;
if (isNaN(delta.y))
delta.y = 0;
$.each(plot.getAxes(), function (_, axis) {
var opts = axis.options,
min, max, d = delta[axis.direction];
min = axis.c2p(axis.p2c(axis.min) + d),
max = axis.c2p(axis.p2c(axis.max) + d);
var pr = opts.panRange;
if (pr === false) // no panning on this axis
return;
if (pr) {
// check whether we hit the wall
if (pr[0] != null && pr[0] > min) {
d = pr[0] - min;
min += d;
max += d;
}
if (pr[1] != null && pr[1] < max) {
d = pr[1] - max;
min += d;
max += d;
}
}
opts.min = min;
opts.max = max;
});
plot.setupGrid();
plot.draw();
if (!args.preventEvent)
plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
};
function shutdown(plot, eventHolder) {
eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
eventHolder.unbind("mousewheel", onMouseWheel);
eventHolder.unbind("dragstart", onDragStart);
eventHolder.unbind("drag", onDrag);
eventHolder.unbind("dragend", onDragEnd);
if (panTimeout)
clearTimeout(panTimeout);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'navigate',
version: '1.3'
});
})(jQuery);

View file

@ -1,820 +0,0 @@
/* Flot plugin for rendering pie charts.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin assumes that each series has a single data value, and that each
value is a positive integer or zero. Negative numbers don't make sense for a
pie chart, and have unpredictable results. The values do NOT need to be
passed in as percentages; the plugin will calculate the total and per-slice
percentages internally.
* Created by Brian Medendorp
* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
The plugin supports these options:
series: {
pie: {
show: true/false
radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
offset: {
top: integer value to move the pie up or down
left: integer value to move the pie left or right, or 'auto'
},
stroke: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
width: integer pixel width of the stroke
},
label: {
show: true/false, or 'auto'
formatter: a user-defined function that modifies the text/style of the label text
radius: 0-1 for percentage of fullsize, or a specified pixel length
background: {
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')
opacity: 0-1
},
threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
},
combine: {
threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
label: any text value of what the combined slice should be labeled
}
highlight: {
opacity: 0-1
}
}
}
More detail and specific examples can be found in the included HTML file.
*/
(function($) {
// Maximum redraw attempts when fitting labels within the plot
var REDRAW_ATTEMPTS = 10;
// Factor by which to shrink the pie when fitting labels within the plot
var REDRAW_SHRINK = 0.95;
function init(plot) {
var canvas = null,
target = null,
options = null,
maxRadius = null,
centerLeft = null,
centerTop = null,
processed = false,
ctx = null;
// interactive variables
var highlights = [];
// add hook to determine if pie plugin in enabled, and then perform necessary operations
plot.hooks.processOptions.push(function(plot, options) {
if (options.series.pie.show) {
options.grid.show = false;
// set labels.show
if (options.series.pie.label.show == "auto") {
if (options.legend.show) {
options.series.pie.label.show = false;
} else {
options.series.pie.label.show = true;
}
}
// set radius
if (options.series.pie.radius == "auto") {
if (options.series.pie.label.show) {
options.series.pie.radius = 3/4;
} else {
options.series.pie.radius = 1;
}
}
// ensure sane tilt
if (options.series.pie.tilt > 1) {
options.series.pie.tilt = 1;
} else if (options.series.pie.tilt < 0) {
options.series.pie.tilt = 0;
}
}
});
plot.hooks.bindEvents.push(function(plot, eventHolder) {
var options = plot.getOptions();
if (options.series.pie.show) {
if (options.grid.hoverable) {
eventHolder.unbind("mousemove").mousemove(onMouseMove);
}
if (options.grid.clickable) {
eventHolder.unbind("click").click(onClick);
}
}
});
plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
var options = plot.getOptions();
if (options.series.pie.show) {
processDatapoints(plot, series, data, datapoints);
}
});
plot.hooks.drawOverlay.push(function(plot, octx) {
var options = plot.getOptions();
if (options.series.pie.show) {
drawOverlay(plot, octx);
}
});
plot.hooks.draw.push(function(plot, newCtx) {
var options = plot.getOptions();
if (options.series.pie.show) {
draw(plot, newCtx);
}
});
function processDatapoints(plot, series, datapoints) {
if (!processed) {
processed = true;
canvas = plot.getCanvas();
target = $(canvas).parent();
options = plot.getOptions();
plot.setData(combine(plot.getData()));
}
}
function combine(data) {
var total = 0,
combined = 0,
numCombined = 0,
color = options.series.pie.combine.color,
newdata = [];
// Fix up the raw data from Flot, ensuring the data is numeric
for (var i = 0; i < data.length; ++i) {
var value = data[i].data;
// If the data is an array, we'll assume that it's a standard
// Flot x-y pair, and are concerned only with the second value.
// Note how we use the original array, rather than creating a
// new one; this is more efficient and preserves any extra data
// that the user may have stored in higher indexes.
if ($.isArray(value) && value.length == 1) {
value = value[0];
}
if ($.isArray(value)) {
// Equivalent to $.isNumeric() but compatible with jQuery < 1.7
if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
value[1] = +value[1];
} else {
value[1] = 0;
}
} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
value = [1, +value];
} else {
value = [1, 0];
}
data[i].data = [value];
}
// Sum up all the slices, so we can calculate percentages for each
for (var i = 0; i < data.length; ++i) {
total += data[i].data[0][1];
}
// Count the number of slices with percentages below the combine
// threshold; if it turns out to be just one, we won't combine.
for (var i = 0; i < data.length; ++i) {
var value = data[i].data[0][1];
if (value / total <= options.series.pie.combine.threshold) {
combined += value;
numCombined++;
if (!color) {
color = data[i].color;
}
}
}
for (var i = 0; i < data.length; ++i) {
var value = data[i].data[0][1];
if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
newdata.push(
$.extend(data[i], { /* extend to allow keeping all other original data values
and using them e.g. in labelFormatter. */
data: [[1, value]],
color: data[i].color,
label: data[i].label,
angle: value * Math.PI * 2 / total,
percent: value / (total / 100)
})
);
}
}
if (numCombined > 1) {
newdata.push({
data: [[1, combined]],
color: color,
label: options.series.pie.combine.label,
angle: combined * Math.PI * 2 / total,
percent: combined / (total / 100)
});
}
return newdata;
}
function draw(plot, newCtx) {
if (!target) {
return; // if no series were passed
}
var canvasWidth = plot.getPlaceholder().width(),
canvasHeight = plot.getPlaceholder().height(),
legendWidth = target.children().filter(".legend").children().width() || 0;
ctx = newCtx;
// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
// When combining smaller slices into an 'other' slice, we need to
// add a new series. Since Flot gives plugins no way to modify the
// list of series, the pie plugin uses a hack where the first call
// to processDatapoints results in a call to setData with the new
// list of series, then subsequent processDatapoints do nothing.
// The plugin-global 'processed' flag is used to control this hack;
// it starts out false, and is set to true after the first call to
// processDatapoints.
// Unfortunately this turns future setData calls into no-ops; they
// call processDatapoints, the flag is true, and nothing happens.
// To fix this we'll set the flag back to false here in draw, when
// all series have been processed, so the next sequence of calls to
// processDatapoints once again starts out with a slice-combine.
// This is really a hack; in 0.9 we need to give plugins a proper
// way to modify series before any processing begins.
processed = false;
// calculate maximum radius and center point
maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
centerTop = canvasHeight / 2 + options.series.pie.offset.top;
centerLeft = canvasWidth / 2;
if (options.series.pie.offset.left == "auto") {
if (options.legend.position.match("w")) {
centerLeft += legendWidth / 2;
} else {
centerLeft -= legendWidth / 2;
}
if (centerLeft < maxRadius) {
centerLeft = maxRadius;
} else if (centerLeft > canvasWidth - maxRadius) {
centerLeft = canvasWidth - maxRadius;
}
} else {
centerLeft += options.series.pie.offset.left;
}
var slices = plot.getData(),
attempts = 0;
// Keep shrinking the pie's radius until drawPie returns true,
// indicating that all the labels fit, or we try too many times.
do {
if (attempts > 0) {
maxRadius *= REDRAW_SHRINK;
}
attempts += 1;
clear();
if (options.series.pie.tilt <= 0.8) {
drawShadow();
}
} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
if (attempts >= REDRAW_ATTEMPTS) {
clear();
target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
}
if (plot.setSeries && plot.insertLegend) {
plot.setSeries(slices);
plot.insertLegend();
}
// we're actually done at this point, just defining internal functions at this point
function clear() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
target.children().filter(".pieLabel, .pieLabelBackground").remove();
}
function drawShadow() {
var shadowLeft = options.series.pie.shadow.left;
var shadowTop = options.series.pie.shadow.top;
var edge = 10;
var alpha = options.series.pie.shadow.alpha;
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
return; // shadow would be outside canvas, so don't draw it
}
ctx.save();
ctx.translate(shadowLeft,shadowTop);
ctx.globalAlpha = alpha;
ctx.fillStyle = "#000";
// center and rotate to starting position
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//radius -= edge;
for (var i = 1; i <= edge; i++) {
ctx.beginPath();
ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
ctx.fill();
radius -= i;
}
ctx.restore();
}
function drawPie() {
var startAngle = Math.PI * options.series.pie.startAngle;
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
// center and rotate to starting position
ctx.save();
ctx.translate(centerLeft,centerTop);
ctx.scale(1, options.series.pie.tilt);
//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
// draw slices
ctx.save();
var currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i) {
slices[i].startAngle = currentAngle;
drawSlice(slices[i].angle, slices[i].color, true);
}
ctx.restore();
// draw slice outlines
if (options.series.pie.stroke.width > 0) {
ctx.save();
ctx.lineWidth = options.series.pie.stroke.width;
currentAngle = startAngle;
for (var i = 0; i < slices.length; ++i) {
drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
}
ctx.restore();
}
// draw donut hole
drawDonutHole(ctx);
ctx.restore();
// Draw the labels, returning true if they fit within the plot
if (options.series.pie.label.show) {
return drawLabels();
} else return true;
function drawSlice(angle, color, fill) {
if (angle <= 0 || isNaN(angle)) {
return;
}
if (fill) {
ctx.fillStyle = color;
} else {
ctx.strokeStyle = color;
ctx.lineJoin = "round";
}
ctx.beginPath();
if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
ctx.moveTo(0, 0); // Center of the pie
}
//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
ctx.closePath();
//ctx.rotate(angle); // This doesn't work properly in Opera
currentAngle += angle;
if (fill) {
ctx.fill();
} else {
ctx.stroke();
}
}
function drawLabels() {
var currentAngle = startAngle;
var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
for (var i = 0; i < slices.length; ++i) {
if (slices[i].percent >= options.series.pie.label.threshold * 100) {
if (!drawLabel(slices[i], currentAngle, i)) {
return false;
}
}
currentAngle += slices[i].angle;
}
return true;
function drawLabel(slice, startAngle, index) {
if (slice.data[0][1] == 0) {
return true;
}
// format label text
var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
if (lf) {
text = lf(slice.label, slice);
} else {
text = slice.label;
}
if (plf) {
text = plf(text, slice);
}
var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>";
target.append(html);
var label = target.children("#pieLabel" + index);
var labelTop = (y - label.height() / 2);
var labelLeft = (x - label.width() / 2);
label.css("top", labelTop);
label.css("left", labelLeft);
// check to make sure that the label is not outside the canvas
if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
return false;
}
if (options.series.pie.label.background.opacity != 0) {
// put in the transparent background separately to avoid blended labels and label boxes
var c = options.series.pie.label.background.color;
if (c == null) {
c = slice.color;
}
var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
$("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>")
.css("opacity", options.series.pie.label.background.opacity)
.insertBefore(label);
}
return true;
} // end individual label function
} // end drawLabels function
} // end drawPie function
} // end draw function
// Placed here because it needs to be accessed from multiple locations
function drawDonutHole(layer) {
if (options.series.pie.innerRadius > 0) {
// subtract the center
layer.save();
var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
layer.beginPath();
layer.fillStyle = options.series.pie.stroke.color;
layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
layer.fill();
layer.closePath();
layer.restore();
// add inner stroke
layer.save();
layer.beginPath();
layer.strokeStyle = options.series.pie.stroke.color;
layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
layer.stroke();
layer.closePath();
layer.restore();
// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
}
}
//-- Additional Interactive related functions --
function isPointInPoly(poly, pt) {
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
function findNearbySlice(mouseX, mouseY) {
var slices = plot.getData(),
options = plot.getOptions(),
radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
x, y;
for (var i = 0; i < slices.length; ++i) {
var s = slices[i];
if (s.pie.show) {
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0); // Center of the pie
//ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
ctx.closePath();
x = mouseX - centerLeft;
y = mouseY - centerTop;
if (ctx.isPointInPath) {
if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
ctx.restore();
return {
datapoint: [s.percent, s.data],
dataIndex: 0,
series: s,
seriesIndex: i
};
}
} else {
// excanvas for IE doesn;t support isPointInPath, this is a workaround.
var p1X = radius * Math.cos(s.startAngle),
p1Y = radius * Math.sin(s.startAngle),
p2X = radius * Math.cos(s.startAngle + s.angle / 4),
p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
p3X = radius * Math.cos(s.startAngle + s.angle / 2),
p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
p5X = radius * Math.cos(s.startAngle + s.angle),
p5Y = radius * Math.sin(s.startAngle + s.angle),
arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
arrPoint = [x, y];
// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?
if (isPointInPoly(arrPoly, arrPoint)) {
ctx.restore();
return {
datapoint: [s.percent, s.data],
dataIndex: 0,
series: s,
seriesIndex: i
};
}
}
ctx.restore();
}
}
return null;
}
function onMouseMove(e) {
triggerClickHoverEvent("plothover", e);
}
function onClick(e) {
triggerClickHoverEvent("plotclick", e);
}
// trigger click or hover event (they send the same parameters so we share their code)
function triggerClickHoverEvent(eventname, e) {
var offset = plot.offset();
var canvasX = parseInt(e.pageX - offset.left);
var canvasY = parseInt(e.pageY - offset.top);
var item = findNearbySlice(canvasX, canvasY);
if (options.grid.autoHighlight) {
// clear auto-highlights
for (var i = 0; i < highlights.length; ++i) {
var h = highlights[i];
if (h.auto == eventname && !(item && h.series == item.series)) {
unhighlight(h.series);
}
}
}
// highlight the slice
if (item) {
highlight(item.series, eventname);
}
// trigger any hover bind events
var pos = { pageX: e.pageX, pageY: e.pageY };
target.trigger(eventname, [pos, item]);
}
function highlight(s, auto) {
//if (typeof s == "number") {
// s = series[s];
//}
var i = indexOfHighlight(s);
if (i == -1) {
highlights.push({ series: s, auto: auto });
plot.triggerRedrawOverlay();
} else if (!auto) {
highlights[i].auto = false;
}
}
function unhighlight(s) {
if (s == null) {
highlights = [];
plot.triggerRedrawOverlay();
}
//if (typeof s == "number") {
// s = series[s];
//}
var i = indexOfHighlight(s);
if (i != -1) {
highlights.splice(i, 1);
plot.triggerRedrawOverlay();
}
}
function indexOfHighlight(s) {
for (var i = 0; i < highlights.length; ++i) {
var h = highlights[i];
if (h.series == s)
return i;
}
return -1;
}
function drawOverlay(plot, octx) {
var options = plot.getOptions();
var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
octx.save();
octx.translate(centerLeft, centerTop);
octx.scale(1, options.series.pie.tilt);
for (var i = 0; i < highlights.length; ++i) {
drawHighlight(highlights[i].series);
}
drawDonutHole(octx);
octx.restore();
function drawHighlight(series) {
if (series.angle <= 0 || isNaN(series.angle)) {
return;
}
//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
octx.beginPath();
if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
octx.moveTo(0, 0); // Center of the pie
}
octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
octx.closePath();
octx.fill();
}
}
} // end init (plugin body)
// define pie specific options and their default values
var options = {
series: {
pie: {
show: false,
radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
innerRadius: 0, /* for donut */
startAngle: 3/2,
tilt: 1,
shadow: {
left: 5, // shadow left offset
top: 15, // shadow top offset
alpha: 0.02 // shadow alpha
},
offset: {
top: 0,
left: "auto"
},
stroke: {
color: "#fff",
width: 1
},
label: {
show: "auto",
formatter: function(label, slice) {
return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>";
}, // formatter function
radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
background: {
color: null,
opacity: 0
},
threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
},
combine: {
threshold: -1, // percentage at which to combine little slices into one larger slice
color: null, // color to give the new slice (auto-generated if null)
label: "Other" // label to give the new slice
},
highlight: {
//color: "#fff", // will add this functionality once parseColor is available
opacity: 0.5
}
}
}
};
$.plot.plugins.push({
init: init,
options: options,
name: "pie",
version: "1.1"
});
})(jQuery);

View file

@ -1,59 +0,0 @@
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
It works by listening for changes on the placeholder div (through the jQuery
resize event plugin) - if the size changes, it will redraw the plot.
There are no options. If you need to disable the plugin for some plots, you
can just fix the size of their placeholders.
*/
/* Inline dependency:
* jQuery resize event - v1.1 - 3/14/2010
* http://benalman.com/projects/jquery-resize-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
*/
(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
(function ($) {
var options = { }; // no options
function init(plot) {
function onResize() {
var placeholder = plot.getPlaceholder();
// somebody might have hidden us and we can't plot
// when we don't have the dimensions
if (placeholder.width() == 0 || placeholder.height() == 0)
return;
plot.resize();
plot.setupGrid();
plot.draw();
}
function bindEvents(plot, eventHolder) {
plot.getPlaceholder().resize(onResize);
}
function shutdown(plot, eventHolder) {
plot.getPlaceholder().unbind("resize", onResize);
}
plot.hooks.bindEvents.push(bindEvents);
plot.hooks.shutdown.push(shutdown);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'resize',
version: '1.0'
});
})(jQuery);

View file

@ -1,360 +0,0 @@
/* Flot plugin for selecting regions of a plot.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
selection: {
mode: null or "x" or "y" or "xy",
color: color,
shape: "round" or "miter" or "bevel",
minSize: number of pixels
}
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
In "x" mode, the user will only be able to specify the x range, similarly for
"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
specified. "color" is color of the selection (if you need to change the color
later on, you can get to it with plot.getOptions().selection.color). "shape"
is the shape of the corners of the selection.
"minSize" is the minimum size a selection can be in pixels. This value can
be customized to determine the smallest size a selection can be and still
have the selection rectangle be displayed. When customizing this value, the
fact that it refers to pixels, not axis units must be taken into account.
Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
minute, setting "minSize" to 1 will not make the minimum selection size 1
minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
"plotunselected" events from being fired when the user clicks the mouse without
dragging.
When selection support is enabled, a "plotselected" event will be emitted on
the DOM element you passed into the plot function. The event handler gets a
parameter with the ranges selected on the axes, like this:
placeholder.bind( "plotselected", function( event, ranges ) {
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
// similar for yaxis - with multiple axes, the extra ones are in
// x2axis, x3axis, ...
});
The "plotselected" event is only fired when the user has finished making the
selection. A "plotselecting" event is fired during the process with the same
parameters as the "plotselected" event, in case you want to know what's
happening while it's happening,
A "plotunselected" event with no arguments is emitted when the user clicks the
mouse to remove the selection. As stated above, setting "minSize" to 0 will
destroy this behavior.
The plugin allso adds the following methods to the plot object:
- setSelection( ranges, preventEvent )
Set the selection rectangle. The passed in ranges is on the same form as
returned in the "plotselected" event. If the selection mode is "x", you
should put in either an xaxis range, if the mode is "y" you need to put in
an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
this:
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
setSelection will trigger the "plotselected" event when called. If you don't
want that to happen, e.g. if you're inside a "plotselected" handler, pass
true as the second parameter. If you are using multiple axes, you can
specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
xaxis, the plugin picks the first one it sees.
- clearSelection( preventEvent )
Clear the selection rectangle. Pass in true to avoid getting a
"plotunselected" event.
- getSelection()
Returns the current selection in the same format as the "plotselected"
event. If there's currently no selection, the function returns null.
*/
(function ($) {
function init(plot) {
var selection = {
first: { x: -1, y: -1}, second: { x: -1, y: -1},
show: false,
active: false
};
// FIXME: The drag handling implemented here should be
// abstracted out, there's some similar code from a library in
// the navigation plugin, this should be massaged a bit to fit
// the Flot cases here better and reused. Doing this would
// make this plugin much slimmer.
var savedhandlers = {};
var mouseUpHandler = null;
function onMouseMove(e) {
if (selection.active) {
updateSelection(e);
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
}
}
function onMouseDown(e) {
if (e.which != 1) // only accept left-click
return;
// cancel out any text selections
document.body.focus();
// prevent text selection and drag in old-school browsers
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
savedhandlers.onselectstart = document.onselectstart;
document.onselectstart = function () { return false; };
}
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
savedhandlers.ondrag = document.ondrag;
document.ondrag = function () { return false; };
}
setSelectionPos(selection.first, e);
selection.active = true;
// this is a bit silly, but we have to use a closure to be
// able to whack the same handler again
mouseUpHandler = function (e) { onMouseUp(e); };
$(document).one("mouseup", mouseUpHandler);
}
function onMouseUp(e) {
mouseUpHandler = null;
// revert drag stuff for old-school browsers
if (document.onselectstart !== undefined)
document.onselectstart = savedhandlers.onselectstart;
if (document.ondrag !== undefined)
document.ondrag = savedhandlers.ondrag;
// no more dragging
selection.active = false;
updateSelection(e);
if (selectionIsSane())
triggerSelectedEvent();
else {
// this counts as a clear
plot.getPlaceholder().trigger("plotunselected", [ ]);
plot.getPlaceholder().trigger("plotselecting", [ null ]);
}
return false;
}
function getSelection() {
if (!selectionIsSane())
return null;
if (!selection.show) return null;
var r = {}, c1 = selection.first, c2 = selection.second;
$.each(plot.getAxes(), function (name, axis) {
if (axis.used) {
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
}
});
return r;
}
function triggerSelectedEvent() {
var r = getSelection();
plot.getPlaceholder().trigger("plotselected", [ r ]);
// backwards-compat stuff, to be removed in future
if (r.xaxis && r.yaxis)
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
}
function clamp(min, value, max) {
return value < min ? min: (value > max ? max: value);
}
function setSelectionPos(pos, e) {
var o = plot.getOptions();
var offset = plot.getPlaceholder().offset();
var plotOffset = plot.getPlotOffset();
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
if (o.selection.mode == "y")
pos.x = pos == selection.first ? 0 : plot.width();
if (o.selection.mode == "x")
pos.y = pos == selection.first ? 0 : plot.height();
}
function updateSelection(pos) {
if (pos.pageX == null)
return;
setSelectionPos(selection.second, pos);
if (selectionIsSane()) {
selection.show = true;
plot.triggerRedrawOverlay();
}
else
clearSelection(true);
}
function clearSelection(preventEvent) {
if (selection.show) {
selection.show = false;
plot.triggerRedrawOverlay();
if (!preventEvent)
plot.getPlaceholder().trigger("plotunselected", [ ]);
}
}
// function taken from markings support in Flot
function extractRange(ranges, coord) {
var axis, from, to, key, axes = plot.getAxes();
for (var k in axes) {
axis = axes[k];
if (axis.direction == coord) {
key = coord + axis.n + "axis";
if (!ranges[key] && axis.n == 1)
key = coord + "axis"; // support x1axis as xaxis
if (ranges[key]) {
from = ranges[key].from;
to = ranges[key].to;
break;
}
}
}
// backwards-compat stuff - to be removed in future
if (!ranges[key]) {
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
from = ranges[coord + "1"];
to = ranges[coord + "2"];
}
// auto-reverse as an added bonus
if (from != null && to != null && from > to) {
var tmp = from;
from = to;
to = tmp;
}
return { from: from, to: to, axis: axis };
}
function setSelection(ranges, preventEvent) {
var axis, range, o = plot.getOptions();
if (o.selection.mode == "y") {
selection.first.x = 0;
selection.second.x = plot.width();
}
else {
range = extractRange(ranges, "x");
selection.first.x = range.axis.p2c(range.from);
selection.second.x = range.axis.p2c(range.to);
}
if (o.selection.mode == "x") {
selection.first.y = 0;
selection.second.y = plot.height();
}
else {
range = extractRange(ranges, "y");
selection.first.y = range.axis.p2c(range.from);
selection.second.y = range.axis.p2c(range.to);
}
selection.show = true;
plot.triggerRedrawOverlay();
if (!preventEvent && selectionIsSane())
triggerSelectedEvent();
}
function selectionIsSane() {
var minSize = plot.getOptions().selection.minSize;
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
Math.abs(selection.second.y - selection.first.y) >= minSize;
}
plot.clearSelection = clearSelection;
plot.setSelection = setSelection;
plot.getSelection = getSelection;
plot.hooks.bindEvents.push(function(plot, eventHolder) {
var o = plot.getOptions();
if (o.selection.mode != null) {
eventHolder.mousemove(onMouseMove);
eventHolder.mousedown(onMouseDown);
}
});
plot.hooks.drawOverlay.push(function (plot, ctx) {
// draw selection
if (selection.show && selectionIsSane()) {
var plotOffset = plot.getPlotOffset();
var o = plot.getOptions();
ctx.save();
ctx.translate(plotOffset.left, plotOffset.top);
var c = $.color.parse(o.selection.color);
ctx.strokeStyle = c.scale('a', 0.8).toString();
ctx.lineWidth = 1;
ctx.lineJoin = o.selection.shape;
ctx.fillStyle = c.scale('a', 0.4).toString();
var x = Math.min(selection.first.x, selection.second.x) + 0.5,
y = Math.min(selection.first.y, selection.second.y) + 0.5,
w = Math.abs(selection.second.x - selection.first.x) - 1,
h = Math.abs(selection.second.y - selection.first.y) - 1;
ctx.fillRect(x, y, w, h);
ctx.strokeRect(x, y, w, h);
ctx.restore();
}
});
plot.hooks.shutdown.push(function (plot, eventHolder) {
eventHolder.unbind("mousemove", onMouseMove);
eventHolder.unbind("mousedown", onMouseDown);
if (mouseUpHandler)
$(document).unbind("mouseup", mouseUpHandler);
});
}
$.plot.plugins.push({
init: init,
options: {
selection: {
mode: null, // one of null, "x", "y" or "xy"
color: "#e8cfac",
shape: "round", // one of "round", "miter", or "bevel"
minSize: 5 // minimum number of pixels
}
},
name: 'selection',
version: '1.1'
});
})(jQuery);

View file

@ -1,188 +0,0 @@
/* Flot plugin for stacking data sets rather than overlyaing them.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin assumes the data is sorted on x (or y if stacking horizontally).
For line charts, it is assumed that if a line has an undefined gap (from a
null point), then the line above it should have the same gap - insert zeros
instead of "null" if you want another behaviour. This also holds for the start
and end of the chart. Note that stacking a mix of positive and negative values
in most instances doesn't make sense (so it looks weird).
Two or more series are stacked when their "stack" attribute is set to the same
key (which can be any number or string or just "true"). To specify the default
stack, you can set the stack option like this:
series: {
stack: null/false, true, or a key (number/string)
}
You can also specify it for a single series, like this:
$.plot( $("#placeholder"), [{
data: [ ... ],
stack: true
}])
The stacking order is determined by the order of the data series in the array
(later series end up on top of the previous).
Internally, the plugin modifies the datapoints in each series, adding an
offset to the y value. For line series, extra data points are inserted through
interpolation. If there's a second y value, it's also adjusted (e.g for bar
charts or filled areas).
*/
(function ($) {
var options = {
series: { stack: null } // or number/string
};
function init(plot) {
function findMatchingSeries(s, allseries) {
var res = null;
for (var i = 0; i < allseries.length; ++i) {
if (s == allseries[i])
break;
if (allseries[i].stack == s.stack)
res = allseries[i];
}
return res;
}
function stackData(plot, s, datapoints) {
if (s.stack == null || s.stack === false)
return;
var other = findMatchingSeries(s, plot.getData());
if (!other)
return;
var ps = datapoints.pointsize,
points = datapoints.points,
otherps = other.datapoints.pointsize,
otherpoints = other.datapoints.points,
newpoints = [],
px, py, intery, qx, qy, bottom,
withlines = s.lines.show,
horizontal = s.bars.horizontal,
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
withsteps = withlines && s.lines.steps,
fromgap = true,
keyOffset = horizontal ? 1 : 0,
accumulateOffset = horizontal ? 0 : 1,
i = 0, j = 0, l, m;
while (true) {
if (i >= points.length)
break;
l = newpoints.length;
if (points[i] == null) {
// copy gaps
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
i += ps;
}
else if (j >= otherpoints.length) {
// for lines, we can't use the rest of the points
if (!withlines) {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
}
i += ps;
}
else if (otherpoints[j] == null) {
// oops, got a gap
for (m = 0; m < ps; ++m)
newpoints.push(null);
fromgap = true;
j += otherps;
}
else {
// cases where we actually got two points
px = points[i + keyOffset];
py = points[i + accumulateOffset];
qx = otherpoints[j + keyOffset];
qy = otherpoints[j + accumulateOffset];
bottom = 0;
if (px == qx) {
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
newpoints[l + accumulateOffset] += qy;
bottom = qy;
i += ps;
j += otherps;
}
else if (px > qx) {
// we got past point below, might need to
// insert interpolated extra point
if (withlines && i > 0 && points[i - ps] != null) {
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
newpoints.push(qx);
newpoints.push(intery + qy);
for (m = 2; m < ps; ++m)
newpoints.push(points[i + m]);
bottom = qy;
}
j += otherps;
}
else { // px < qx
if (fromgap && withlines) {
// if we come from a gap, we just skip this point
i += ps;
continue;
}
for (m = 0; m < ps; ++m)
newpoints.push(points[i + m]);
// we might be able to interpolate a point below,
// this can give us a better y
if (withlines && j > 0 && otherpoints[j - otherps] != null)
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
newpoints[l + accumulateOffset] += bottom;
i += ps;
}
fromgap = false;
if (l != newpoints.length && withbottom)
newpoints[l + 2] += bottom;
}
// maintain the line steps invariant
if (withsteps && l != newpoints.length && l > 0
&& newpoints[l] != null
&& newpoints[l] != newpoints[l - ps]
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
for (m = 0; m < ps; ++m)
newpoints[l + ps + m] = newpoints[l + m];
newpoints[l + 1] = newpoints[l - ps + 1];
}
}
datapoints.points = newpoints;
}
plot.hooks.processDatapoints.push(stackData);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'stack',
version: '1.2'
});
})(jQuery);

View file

@ -1,71 +0,0 @@
/* Flot plugin that adds some extra symbols for plotting points.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The symbols are accessed as strings through the standard symbol options:
series: {
points: {
symbol: "square" // or "diamond", "triangle", "cross"
}
}
*/
(function ($) {
function processRawData(plot, series, datapoints) {
// we normalize the area of each symbol so it is approximately the
// same as a circle of the given radius
var handlers = {
square: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.rect(x - size, y - size, size + size, size + size);
},
diamond: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
var size = radius * Math.sqrt(Math.PI / 2);
ctx.moveTo(x - size, y);
ctx.lineTo(x, y - size);
ctx.lineTo(x + size, y);
ctx.lineTo(x, y + size);
ctx.lineTo(x - size, y);
},
triangle: function (ctx, x, y, radius, shadow) {
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
var height = size * Math.sin(Math.PI / 3);
ctx.moveTo(x - size/2, y + height/2);
ctx.lineTo(x + size/2, y + height/2);
if (!shadow) {
ctx.lineTo(x, y - height/2);
ctx.lineTo(x - size/2, y + height/2);
}
},
cross: function (ctx, x, y, radius, shadow) {
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
var size = radius * Math.sqrt(Math.PI) / 2;
ctx.moveTo(x - size, y - size);
ctx.lineTo(x + size, y + size);
ctx.moveTo(x - size, y + size);
ctx.lineTo(x + size, y - size);
}
};
var s = series.points.symbol;
if (handlers[s])
series.points.symbol = handlers[s];
}
function init(plot) {
plot.hooks.processDatapoints.push(processRawData);
}
$.plot.plugins.push({
init: init,
name: 'symbols',
version: '1.0'
});
})(jQuery);

View file

@ -1,142 +0,0 @@
/* Flot plugin for thresholding data.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
The plugin supports these options:
series: {
threshold: {
below: number
color: colorspec
}
}
It can also be applied to a single series, like this:
$.plot( $("#placeholder"), [{
data: [ ... ],
threshold: { ... }
}])
An array can be passed for multiple thresholding, like this:
threshold: [{
below: number1
color: color1
},{
below: number2
color: color2
}]
These multiple threshold objects can be passed in any order since they are
sorted by the processing function.
The data points below "below" are drawn with the specified color. This makes
it easy to mark points below 0, e.g. for budget data.
Internally, the plugin works by splitting the data into two series, above and
below the threshold. The extra series below the threshold will have its label
cleared and the special "originSeries" attribute set to the original series.
You may need to check for this in hover events.
*/
(function ($) {
var options = {
series: { threshold: null } // or { below: number, color: color spec}
};
function init(plot) {
function thresholdData(plot, s, datapoints, below, color) {
var ps = datapoints.pointsize, i, x, y, p, prevp,
thresholded = $.extend({}, s); // note: shallow copy
thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
thresholded.label = null;
thresholded.color = color;
thresholded.threshold = null;
thresholded.originSeries = s;
thresholded.data = [];
var origpoints = datapoints.points,
addCrossingPoints = s.lines.show;
var threspoints = [];
var newpoints = [];
var m;
for (i = 0; i < origpoints.length; i += ps) {
x = origpoints[i];
y = origpoints[i + 1];
prevp = p;
if (y < below)
p = threspoints;
else
p = newpoints;
if (addCrossingPoints && prevp != p && x != null
&& i > 0 && origpoints[i - ps] != null) {
var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
prevp.push(interx);
prevp.push(below);
for (m = 2; m < ps; ++m)
prevp.push(origpoints[i + m]);
p.push(null); // start new segment
p.push(null);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
p.push(interx);
p.push(below);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
}
p.push(x);
p.push(y);
for (m = 2; m < ps; ++m)
p.push(origpoints[i + m]);
}
datapoints.points = newpoints;
thresholded.datapoints.points = threspoints;
if (thresholded.datapoints.points.length > 0) {
var origIndex = $.inArray(s, plot.getData());
// Insert newly-generated series right after original one (to prevent it from becoming top-most)
plot.getData().splice(origIndex + 1, 0, thresholded);
}
// FIXME: there are probably some edge cases left in bars
}
function processThresholds(plot, s, datapoints) {
if (!s.threshold)
return;
if (s.threshold instanceof Array) {
s.threshold.sort(function(a, b) {
return a.below - b.below;
});
$(s.threshold).each(function(i, th) {
thresholdData(plot, s, datapoints, th.below, th.color);
});
}
else {
thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
}
}
plot.hooks.processDatapoints.push(processThresholds);
}
$.plot.plugins.push({
init: init,
options: options,
name: 'threshold',
version: '1.2'
});
})(jQuery);

View file

@ -1,432 +0,0 @@
/* Pretty handling of time axes.
Copyright (c) 2007-2014 IOLA and Ole Laursen.
Licensed under the MIT license.
Set axis.mode to "time" to enable. See the section "Time series data" in
API.txt for details.
*/
(function($) {
var options = {
xaxis: {
timezone: null, // "browser" for local to the client or timezone for timezone-js
timeformat: null, // format string to use
twelveHourClock: false, // 12 or 24 time in time mode
monthNames: null // list of names of months
}
};
// round to nearby lower multiple of base
function floorInBase(n, base) {
return base * Math.floor(n / base);
}
// Returns a string with the date d formatted according to fmt.
// A subset of the Open Group's strftime format is supported.
function formatDate(d, fmt, monthNames, dayNames) {
if (typeof d.strftime == "function") {
return d.strftime(fmt);
}
var leftPad = function(n, pad) {
n = "" + n;
pad = "" + (pad == null ? "0" : pad);
return n.length == 1 ? pad + n : n;
};
var r = [];
var escape = false;
var hours = d.getHours();
var isAM = hours < 12;
if (monthNames == null) {
monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
}
if (dayNames == null) {
dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
}
var hours12;
if (hours > 12) {
hours12 = hours - 12;
} else if (hours == 0) {
hours12 = 12;
} else {
hours12 = hours;
}
for (var i = 0; i < fmt.length; ++i) {
var c = fmt.charAt(i);
if (escape) {
switch (c) {
case 'a': c = "" + dayNames[d.getDay()]; break;
case 'b': c = "" + monthNames[d.getMonth()]; break;
case 'd': c = leftPad(d.getDate()); break;
case 'e': c = leftPad(d.getDate(), " "); break;
case 'h': // For back-compat with 0.7; remove in 1.0
case 'H': c = leftPad(hours); break;
case 'I': c = leftPad(hours12); break;
case 'l': c = leftPad(hours12, " "); break;
case 'm': c = leftPad(d.getMonth() + 1); break;
case 'M': c = leftPad(d.getMinutes()); break;
// quarters not in Open Group's strftime specification
case 'q':
c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
case 'S': c = leftPad(d.getSeconds()); break;
case 'y': c = leftPad(d.getFullYear() % 100); break;
case 'Y': c = "" + d.getFullYear(); break;
case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
case 'w': c = "" + d.getDay(); break;
}
r.push(c);
escape = false;
} else {
if (c == "%") {
escape = true;
} else {
r.push(c);
}
}
}
return r.join("");
}
// To have a consistent view of time-based data independent of which time
// zone the client happens to be in we need a date-like object independent
// of time zones. This is done through a wrapper that only calls the UTC
// versions of the accessor methods.
function makeUtcWrapper(d) {
function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
sourceObj[sourceMethod] = function() {
return targetObj[targetMethod].apply(targetObj, arguments);
};
};
var utc = {
date: d
};
// support strftime, if found
if (d.strftime != undefined) {
addProxyMethod(utc, "strftime", d, "strftime");
}
addProxyMethod(utc, "getTime", d, "getTime");
addProxyMethod(utc, "setTime", d, "setTime");
var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
for (var p = 0; p < props.length; p++) {
addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
}
return utc;
};
// select time zone strategy. This returns a date-like object tied to the
// desired timezone
function dateGenerator(ts, opts) {
if (opts.timezone == "browser") {
return new Date(ts);
} else if (!opts.timezone || opts.timezone == "utc") {
return makeUtcWrapper(new Date(ts));
} else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
var d = new timezoneJS.Date();
// timezone-js is fickle, so be sure to set the time zone before
// setting the time.
d.setTimezone(opts.timezone);
d.setTime(ts);
return d;
} else {
return makeUtcWrapper(new Date(ts));
}
}
// map of app. size of time units in milliseconds
var timeUnitSize = {
"second": 1000,
"minute": 60 * 1000,
"hour": 60 * 60 * 1000,
"day": 24 * 60 * 60 * 1000,
"month": 30 * 24 * 60 * 60 * 1000,
"quarter": 3 * 30 * 24 * 60 * 60 * 1000,
"year": 365.2425 * 24 * 60 * 60 * 1000
};
// the allowed tick sizes, after 1 year we use
// an integer algorithm
var baseSpec = [
[1, "second"], [2, "second"], [5, "second"], [10, "second"],
[30, "second"],
[1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
[30, "minute"],
[1, "hour"], [2, "hour"], [4, "hour"],
[8, "hour"], [12, "hour"],
[1, "day"], [2, "day"], [3, "day"],
[0.25, "month"], [0.5, "month"], [1, "month"],
[2, "month"]
];
// we don't know which variant(s) we'll need yet, but generating both is
// cheap
var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
[1, "year"]]);
var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
[1, "year"]]);
function init(plot) {
plot.hooks.processOptions.push(function (plot, options) {
$.each(plot.getAxes(), function(axisName, axis) {
var opts = axis.options;
if (opts.mode == "time") {
axis.tickGenerator = function(axis) {
var ticks = [];
var d = dateGenerator(axis.min, opts);
var minSize = 0;
// make quarter use a possibility if quarters are
// mentioned in either of these options
var spec = (opts.tickSize && opts.tickSize[1] ===
"quarter") ||
(opts.minTickSize && opts.minTickSize[1] ===
"quarter") ? specQuarters : specMonths;
if (opts.minTickSize != null) {
if (typeof opts.tickSize == "number") {
minSize = opts.tickSize;
} else {
minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
}
}
for (var i = 0; i < spec.length - 1; ++i) {
if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
+ spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
break;
}
}
var size = spec[i][0];
var unit = spec[i][1];
// special-case the possibility of several years
if (unit == "year") {
// if given a minTickSize in years, just use it,
// ensuring that it's an integer
if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
size = Math.floor(opts.minTickSize[0]);
} else {
var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
var norm = (axis.delta / timeUnitSize.year) / magn;
if (norm < 1.5) {
size = 1;
} else if (norm < 3) {
size = 2;
} else if (norm < 7.5) {
size = 5;
} else {
size = 10;
}
size *= magn;
}
// minimum size for years is 1
if (size < 1) {
size = 1;
}
}
axis.tickSize = opts.tickSize || [size, unit];
var tickSize = axis.tickSize[0];
unit = axis.tickSize[1];
var step = tickSize * timeUnitSize[unit];
if (unit == "second") {
d.setSeconds(floorInBase(d.getSeconds(), tickSize));
} else if (unit == "minute") {
d.setMinutes(floorInBase(d.getMinutes(), tickSize));
} else if (unit == "hour") {
d.setHours(floorInBase(d.getHours(), tickSize));
} else if (unit == "month") {
d.setMonth(floorInBase(d.getMonth(), tickSize));
} else if (unit == "quarter") {
d.setMonth(3 * floorInBase(d.getMonth() / 3,
tickSize));
} else if (unit == "year") {
d.setFullYear(floorInBase(d.getFullYear(), tickSize));
}
// reset smaller components
d.setMilliseconds(0);
if (step >= timeUnitSize.minute) {
d.setSeconds(0);
}
if (step >= timeUnitSize.hour) {
d.setMinutes(0);
}
if (step >= timeUnitSize.day) {
d.setHours(0);
}
if (step >= timeUnitSize.day * 4) {
d.setDate(1);
}
if (step >= timeUnitSize.month * 2) {
d.setMonth(floorInBase(d.getMonth(), 3));
}
if (step >= timeUnitSize.quarter * 2) {
d.setMonth(floorInBase(d.getMonth(), 6));
}
if (step >= timeUnitSize.year) {
d.setMonth(0);
}
var carry = 0;
var v = Number.NaN;
var prev;
do {
prev = v;
v = d.getTime();
ticks.push(v);
if (unit == "month" || unit == "quarter") {
if (tickSize < 1) {
// a bit complicated - we'll divide the
// month/quarter up but we need to take
// care of fractions so we don't end up in
// the middle of a day
d.setDate(1);
var start = d.getTime();
d.setMonth(d.getMonth() +
(unit == "quarter" ? 3 : 1));
var end = d.getTime();
d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
carry = d.getHours();
d.setHours(0);
} else {
d.setMonth(d.getMonth() +
tickSize * (unit == "quarter" ? 3 : 1));
}
} else if (unit == "year") {
d.setFullYear(d.getFullYear() + tickSize);
} else {
d.setTime(v + step);
}
} while (v < axis.max && v != prev);
return ticks;
};
axis.tickFormatter = function (v, axis) {
var d = dateGenerator(v, axis.options);
// first check global format
if (opts.timeformat != null) {
return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
}
// possibly use quarters if quarters are mentioned in
// any of these places
var useQuarters = (axis.options.tickSize &&
axis.options.tickSize[1] == "quarter") ||
(axis.options.minTickSize &&
axis.options.minTickSize[1] == "quarter");
var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
var span = axis.max - axis.min;
var suffix = (opts.twelveHourClock) ? " %p" : "";
var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
var fmt;
if (t < timeUnitSize.minute) {
fmt = hourCode + ":%M:%S" + suffix;
} else if (t < timeUnitSize.day) {
if (span < 2 * timeUnitSize.day) {
fmt = hourCode + ":%M" + suffix;
} else {
fmt = "%b %d " + hourCode + ":%M" + suffix;
}
} else if (t < timeUnitSize.month) {
fmt = "%b %d";
} else if ((useQuarters && t < timeUnitSize.quarter) ||
(!useQuarters && t < timeUnitSize.year)) {
if (span < timeUnitSize.year) {
fmt = "%b";
} else {
fmt = "%b %Y";
}
} else if (useQuarters && t < timeUnitSize.year) {
if (span < timeUnitSize.year) {
fmt = "Q%q";
} else {
fmt = "Q%q %Y";
}
} else {
fmt = "%Y";
}
var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
return rt;
};
}
});
});
}
$.plot.plugins.push({
init: init,
options: options,
name: 'time',
version: '1.0'
});
// Time-axis support used to be in Flot core, which exposed the
// formatDate function on the plot object. Various plugins depend
// on the function, so we need to re-expose it here.
$.plot.formatDate = formatDate;
$.plot.dateGenerator = dateGenerator;
})(jQuery);

9472
vendors/Flot/jquery.js vendored

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,52 @@
{
"name": "Flot",
"version": "0.8.3",
"main": "jquery.flot.js",
"scripts": {
"test": "make test"
},
"devDependencies": {
"jshint": "0.9.1"
}
"name": "flot",
"version": "4.1.1",
"main": "dist/es5/jquery.flot.js",
"scripts": {
"test": "node node_modules/karma/bin/karma start --single-run --no-auto-watch --concurrency=1 --stopOnEsLintError",
"karma": "node node_modules/karma/bin/karma start --no-auto-watch",
"coverage": "node node_modules/karma/bin/karma start --single-run --coverage --no-auto-watch --concurrency=1",
"build": "node ./node_modules/gulp/bin/gulp.js build",
"dont-break": "dont-break --timeout 300",
"docs": "node ./update_docs.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/flot/flot.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/flot/flot/issues"
},
"homepage": "https://github.com/flot/flot#readme",
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.4.0",
"@babel/plugin-external-helpers": "^7.2.0",
"@babel/preset-env": "^7.2.3",
"concat": "^1.0.3",
"files-exist": "^1.1.0",
"gulp": "^4.0.0",
"gulp-babel": "^8.0.0",
"gulp-concat": "^2.6.1",
"gulp-sourcemaps": "^2.4.0",
"gulp-uglify": "^3.0.0",
"jasmine-core": "~2.7.0",
"karma": "^1.3.0",
"karma-chrome-launcher": "^2.0.0",
"karma-coverage": "^1.1.2",
"karma-coveralls": "^1.1.2",
"karma-edge-launcher": "^0.4.2",
"karma-eslint": "^2.2.0",
"karma-firefox-launcher": "^1.0.0",
"karma-jasmine": "^1.0.2",
"karma-jasmine-html-reporter": "^0.2.2",
"karma-jasmine-jquery": "^0.1.1",
"karma-safari-launcher": "^1.0.0",
"karma-spec-reporter": "0.0.32",
"ljs": "^0.3.2",
"tmp": "0.0.33",
"webcharts-development-settings": "^1.0.9"
},
"dependencies": {}
}

View file

@ -1,195 +0,0 @@
module.exports = function (grunt) {
'use strict';
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
target: {
files: {
'build/js/bootstrap-datetimepicker.min.js': 'src/js/bootstrap-datetimepicker.js'
}
},
options: {
mangle: true,
compress: {
dead_code: false // jshint ignore:line
},
output: {
ascii_only: true // jshint ignore:line
},
report: 'min',
preserveComments: 'some'
}
},
jshint: {
all: [
'Gruntfile.js', 'src/js/*.js', 'test/*.js'
],
options: {
'browser': true,
'node': true,
'jquery': true,
'boss': false,
'curly': true,
'debug': false,
'devel': false,
'eqeqeq': true,
'bitwise': true,
'eqnull': true,
'evil': false,
'forin': true,
'immed': false,
'laxbreak': false,
'newcap': true,
'noarg': true,
'noempty': false,
'nonew': false,
'onevar': true,
'plusplus': false,
'regexp': false,
'undef': true,
'sub': true,
'strict': true,
'unused': true,
'white': true,
'es3': true,
'camelcase': true,
'quotmark': 'single',
'globals': {
'define': false,
'moment': false,
// Jasmine
'jasmine': false,
'describe': false,
'xdescribe': false,
'expect': false,
'it': false,
'xit': false,
'spyOn': false,
'beforeEach': false,
'afterEach': false
}
}
},
jscs: {
all: [
'Gruntfile.js', 'src/js/*.js', 'test/*.js'
],
options: {
config: '.jscs.json'
}
},
less: {
production: {
options: {
cleancss: true,
compress: true,
paths: 'node_modules'
},
files: {
'build/css/bootstrap-datetimepicker.min.css': 'src/less/bootstrap-datetimepicker-build.less'
}
},
development: {
options: {
paths: 'node_modules'
},
files: {
'build/css/bootstrap-datetimepicker.css': 'src/less/bootstrap-datetimepicker-build.less'
}
}
},
env: {
paris: {
TZ: 'Europe/Paris' // sets env for phantomJS https://github.com/ariya/phantomjs/issues/10379#issuecomment-36058589
}
},
connect: {
server: {
options: {
port: 8099
}
}
},
jasmine: {
customTemplate: {
src: 'src/js/*.js',
options: {
specs: 'test/*Spec.js',
helpers: 'test/*Helper.js',
host: 'http://127.0.0.1:8099',
styles: [
'node_modules/bootstrap/dist/css/bootstrap.min.css',
'build/css/bootstrap-datetimepicker.min.css'
],
vendor: [
'node_modules/jquery/dist/jquery.min.js',
'node_modules/moment/min/moment-with-locales.min.js',
'node_modules/moment-timezone/moment-timezone.js',
'node_modules/bootstrap/dist/js/bootstrap.min.js'
],
display: 'none',
summary: 'true'
}
}
},
nugetpack: {
less: {
src: 'src/nuget/Bootstrap.v3.Datetimepicker.nuspec',
dest: 'build/nuget',
options: {
version: '<%= pkg.version %>'
}
},
css: {
src: 'src/nuget/Bootstrap.v3.Datetimepicker.CSS.nuspec',
dest: 'build/nuget',
options: {
version: '<%= pkg.version %>'
}
}
}
});
grunt.loadTasks('tasks');
grunt.loadNpmTasks('grunt-env');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-jasmine');
grunt.loadNpmTasks('grunt-nuget');
require('load-grunt-tasks')(grunt);
grunt.registerTask('default', ['jshint', 'jscs', 'less', 'env:paris', 'connect', 'jasmine']);
grunt.registerTask('build:travis', [
// code style
'jshint', 'jscs',
// build
'uglify', 'less',
// tests
'env:paris', 'connect', 'jasmine'
]);
// Task to be run when building
grunt.registerTask('build', ['jshint', 'jscs', 'uglify', 'less']);
grunt.registerTask('test', ['jshint', 'jscs', 'uglify', 'less', 'env:paris', 'connect', 'jasmine']);
grunt.registerTask('docs', 'Generate docs', function () {
grunt.util.spawn({
cmd: 'mkdocs',
args: ['build', '--clean']
});
});
grunt.registerTask('release', function (version) {
if (!version || version.split('.').length !== 3) {
grunt.fail.fatal('malformed version. Use grunt release:1.2.3');
}
grunt.task.run([
'bump_version:' + version,
'build:travis',
'docs',
'nugetpack'
]);
});
};

View file

@ -1,20 +0,0 @@
# Bootstrap 3 Date/Time Picker
![GitHub version](https://badge.fury.io/gh/Eonasdan%2Fbootstrap-datetimepicker.png)&nbsp;&nbsp;&nbsp;![Travis](https://travis-ci.org/Eonasdan/bootstrap-datetimepicker.svg?branch=development)
![DateTimePicker](http://i.imgur.com/nfnvh5g.png)
## [View the manual and demos](http://eonasdan.github.io/bootstrap-datetimepicker/)
## [Installation instructions](http://eonasdan.github.io/bootstrap-datetimepicker/Installing/)
## [Change Log](http://eonasdan.github.io/bootstrap-datetimepicker/Changelog/)
### This issue tracker is no longer actively monitored.
# Version 5
Version 5 is being completely rewritten in ES6 and modularized as Tempus Dominus.
v5 is [in alpha](https://github.com/tempusdominus/bootstrap-3).

View file

@ -1,34 +0,0 @@
{
"name": "eonasdan-bootstrap-datetimepicker",
"version": "4.17.47",
"main": [
"build/css/bootstrap-datetimepicker.min.css",
"build/js/bootstrap-datetimepicker.min.js"
],
"dependencies": {
"jquery": ">=1.8.3",
"moment": ">=2.10.5"
},
"homepage": "https://github.com/Eonasdan/bootstrap-datetimepicker",
"authors": [
"Eonasdan"
],
"description": "bootstrap3 datetimepicker",
"keywords": [
"twitter-bootstrap",
"bootstrap",
"datepicker",
"datetimepicker",
"timepicker",
"moment"
],
"license": "MIT",
"private": false,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View file

@ -1,98 +0,0 @@
@font-face {
font-family: 'Glyphicons Halflings';
src: url('../fonts/glyphicons-halflings-regular.eot');
src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.glyphicon-time:before {
content: "\e023";
}
.glyphicon-chevron-left:before {
content: "\e079";
}
.glyphicon-chevron-right:before {
content: "\e080";
}
.glyphicon-chevron-up:before {
content: "\e113";
}
.glyphicon-chevron-down:before {
content: "\e114";
}
.glyphicon-calendar:before {
content: "\e109";
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.collapse {
display: none;
}
.collapse.in {
display: block;
}
.dropdown-menu {
position: absolute;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}
.list-unstyled {
padding-left: 0;
list-style: none;
}

View file

@ -1,374 +0,0 @@
/*!
* Datetimepicker for Bootstrap 3
* version : 4.17.47
* https://github.com/Eonasdan/bootstrap-datetimepicker/
*/
.bootstrap-datetimepicker-widget {
list-style: none;
}
.bootstrap-datetimepicker-widget.dropdown-menu {
display: block;
margin: 2px 0;
padding: 4px;
width: 19em;
}
@media (min-width: 768px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em;
}
}
@media (min-width: 992px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em;
}
}
@media (min-width: 1200px) {
.bootstrap-datetimepicker-widget.dropdown-menu.timepicker-sbs {
width: 38em;
}
}
.bootstrap-datetimepicker-widget.dropdown-menu:before,
.bootstrap-datetimepicker-widget.dropdown-menu:after {
content: '';
display: inline-block;
position: absolute;
}
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 7px solid #ccc;
border-bottom-color: rgba(0, 0, 0, 0.2);
top: -7px;
left: 7px;
}
.bootstrap-datetimepicker-widget.dropdown-menu.bottom:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid white;
top: -6px;
left: 8px;
}
.bootstrap-datetimepicker-widget.dropdown-menu.top:before {
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-top: 7px solid #ccc;
border-top-color: rgba(0, 0, 0, 0.2);
bottom: -7px;
left: 6px;
}
.bootstrap-datetimepicker-widget.dropdown-menu.top:after {
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 6px solid white;
bottom: -6px;
left: 7px;
}
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:before {
left: auto;
right: 6px;
}
.bootstrap-datetimepicker-widget.dropdown-menu.pull-right:after {
left: auto;
right: 7px;
}
.bootstrap-datetimepicker-widget .list-unstyled {
margin: 0;
}
.bootstrap-datetimepicker-widget a[data-action] {
padding: 6px 0;
}
.bootstrap-datetimepicker-widget a[data-action]:active {
box-shadow: none;
}
.bootstrap-datetimepicker-widget .timepicker-hour,
.bootstrap-datetimepicker-widget .timepicker-minute,
.bootstrap-datetimepicker-widget .timepicker-second {
width: 54px;
font-weight: bold;
font-size: 1.2em;
margin: 0;
}
.bootstrap-datetimepicker-widget button[data-action] {
padding: 6px;
}
.bootstrap-datetimepicker-widget .btn[data-action="incrementHours"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Increment Hours";
}
.bootstrap-datetimepicker-widget .btn[data-action="incrementMinutes"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Increment Minutes";
}
.bootstrap-datetimepicker-widget .btn[data-action="decrementHours"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Decrement Hours";
}
.bootstrap-datetimepicker-widget .btn[data-action="decrementMinutes"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Decrement Minutes";
}
.bootstrap-datetimepicker-widget .btn[data-action="showHours"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Show Hours";
}
.bootstrap-datetimepicker-widget .btn[data-action="showMinutes"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Show Minutes";
}
.bootstrap-datetimepicker-widget .btn[data-action="togglePeriod"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Toggle AM/PM";
}
.bootstrap-datetimepicker-widget .btn[data-action="clear"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Clear the picker";
}
.bootstrap-datetimepicker-widget .btn[data-action="today"]::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Set the date to today";
}
.bootstrap-datetimepicker-widget .picker-switch {
text-align: center;
}
.bootstrap-datetimepicker-widget .picker-switch::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Toggle Date and Time Screens";
}
.bootstrap-datetimepicker-widget .picker-switch td {
padding: 0;
margin: 0;
height: auto;
width: auto;
line-height: inherit;
}
.bootstrap-datetimepicker-widget .picker-switch td span {
line-height: 2.5;
height: 2.5em;
width: 100%;
}
.bootstrap-datetimepicker-widget table {
width: 100%;
margin: 0;
}
.bootstrap-datetimepicker-widget table td,
.bootstrap-datetimepicker-widget table th {
text-align: center;
border-radius: 4px;
}
.bootstrap-datetimepicker-widget table th {
height: 20px;
line-height: 20px;
width: 20px;
}
.bootstrap-datetimepicker-widget table th.picker-switch {
width: 145px;
}
.bootstrap-datetimepicker-widget table th.disabled,
.bootstrap-datetimepicker-widget table th.disabled:hover {
background: none;
color: #777777;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget table th.prev::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Previous Month";
}
.bootstrap-datetimepicker-widget table th.next::after {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
content: "Next Month";
}
.bootstrap-datetimepicker-widget table thead tr:first-child th {
cursor: pointer;
}
.bootstrap-datetimepicker-widget table thead tr:first-child th:hover {
background: #eeeeee;
}
.bootstrap-datetimepicker-widget table td {
height: 54px;
line-height: 54px;
width: 54px;
}
.bootstrap-datetimepicker-widget table td.cw {
font-size: .8em;
height: 20px;
line-height: 20px;
color: #777777;
}
.bootstrap-datetimepicker-widget table td.day {
height: 20px;
line-height: 20px;
width: 20px;
}
.bootstrap-datetimepicker-widget table td.day:hover,
.bootstrap-datetimepicker-widget table td.hour:hover,
.bootstrap-datetimepicker-widget table td.minute:hover,
.bootstrap-datetimepicker-widget table td.second:hover {
background: #eeeeee;
cursor: pointer;
}
.bootstrap-datetimepicker-widget table td.old,
.bootstrap-datetimepicker-widget table td.new {
color: #777777;
}
.bootstrap-datetimepicker-widget table td.today {
position: relative;
}
.bootstrap-datetimepicker-widget table td.today:before {
content: '';
display: inline-block;
border: solid transparent;
border-width: 0 0 7px 7px;
border-bottom-color: #337ab7;
border-top-color: rgba(0, 0, 0, 0.2);
position: absolute;
bottom: 4px;
right: 4px;
}
.bootstrap-datetimepicker-widget table td.active,
.bootstrap-datetimepicker-widget table td.active:hover {
background-color: #337ab7;
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.bootstrap-datetimepicker-widget table td.active.today:before {
border-bottom-color: #fff;
}
.bootstrap-datetimepicker-widget table td.disabled,
.bootstrap-datetimepicker-widget table td.disabled:hover {
background: none;
color: #777777;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget table td span {
display: inline-block;
width: 54px;
height: 54px;
line-height: 54px;
margin: 2px 1.5px;
cursor: pointer;
border-radius: 4px;
}
.bootstrap-datetimepicker-widget table td span:hover {
background: #eeeeee;
}
.bootstrap-datetimepicker-widget table td span.active {
background-color: #337ab7;
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
}
.bootstrap-datetimepicker-widget table td span.old {
color: #777777;
}
.bootstrap-datetimepicker-widget table td span.disabled,
.bootstrap-datetimepicker-widget table td span.disabled:hover {
background: none;
color: #777777;
cursor: not-allowed;
}
.bootstrap-datetimepicker-widget.usetwentyfour td.hour {
height: 27px;
line-height: 27px;
}
.bootstrap-datetimepicker-widget.wider {
width: 21em;
}
.bootstrap-datetimepicker-widget .datepicker-decades .decade {
line-height: 1.8em !important;
}
.input-group.date .input-group-addon {
cursor: pointer;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,9 +0,0 @@
{
"name": "bootstrap-datetimepicker",
"version": "4.17.47",
"main": ["build/css/bootstrap-datetimepicker.min.css","build/js/bootstrap-datetimepicker.min.js"],
"dependencies": {
"jquery" : ">=1.8.3",
"moment": ">=2.10.5"
}
}

View file

@ -1,28 +0,0 @@
{
"name": "eonasdan/bootstrap-datetimepicker",
"type": "component",
"version": "4.17.47",
"description": "Date/time picker widget based on twitter bootstrap",
"keywords": [
"bootstrap",
"datetimepicker"
],
"homepage": "http://eonasdan.github.io/bootstrap-datetimepicker/",
"license": "MIT",
"require": {
"robloach/component-installer": "*",
"components/jquery": ">=1.9.1",
"moment/moment": ">=2.10.5"
},
"extra": {
"component": {
"scripts": [
"src/js/bootstrap-datetimepicker.js"
],
"files": [
"build/js/bootstrap-datetimepicker.min.js",
"build/css/bootstrap-datetimepicker.min.css"
]
}
}
}

View file

@ -1,237 +0,0 @@
# Version 4
## 4.17.42
### Bug Squashing
* fixed moment dependencies to all be the same
* defaulted `option.timeZone` to `''` instead of UTC. This way it will default to the local timezone if it's not set.
* fixed #959
* fixed #1311 internal `getMoment` function no longer sets `startOf('d')`
* fixed #935
### Other
* moved some (will move the rest soon) inline docs to JSDoc now that ReSharper supports it.
* moved getter/setter functions to options page instead. #1313
## 4.17.37
### New Features
* Momentjs TZ intergration #1242 thanks @bodrick
* Independent CSS file, in case you don't want bootstrap for some reason
### Bug Squashing
* Slight changes decade view
* Moved all tooltip text to `tooltips`
* fixed #1212
## 4.15.35
### New Features
`tooltips` allows custom, localized text to be included for icon tooltips
### Bug Squashing
fixed #1066
fixed #1087 `sideBySide` properly supports `toolbarPlacement [top, bottom]`
fixed #1119
fixed #1069 added input.blur()
fixed #1049 fixed doc example
fixed #999 picker now looks for an element with `.input-group-addon`
## 4.14.30
### New Features
`disabledTimeIntervals` #644
`allowInputToggle` #929
`focusOnShow` #884
public `viewDate` function #872
`enabledHours` and `disabledHours`.
`dp.update` fires when `viewDate` is changed (in most cases) #937
`viewMode` now supports a decades view.
**Note**: because the year picker shows 12 years at a time, I've elected to make this view show blocks of 12 years
**Note**: when selecting a decade the `viewDate` will change to the **center** of the selected years
`parseInputDate` #1095
### Bug Squashing
fixed #815 by adding `.wider` when using both seconds and am/pm.
fixed #816 changed both min/max date to move the selected date inside.
fixed #855 #881 `fillDate`, `fillMonths`, `fillDow` uses `startOf('day')`, which will hopefully fix the DST issues.
fixed #885 `daysOfWeekDisabled` will move the date to a valid date if `useCurrent` is `true`. Today button will check if the DoW is disabled.
fixed #906
fixed #912 if `useCurrent:false` month and year view will no longer have the current month/year selected.
fixed #914 `use24hours` will ignore anything in side of `[]` in the format string.
fixed #916 added titles to all icons. At some point the text should be moved to the icon's array, but this would probably be a breaking change.
fixed #940 added -1 tab index to am/pm selector
### Other Changes
changed in/decrement behavior to check if the new date is valid at that granularity (hours, minutes, seconds). will also validate as before
## 4.7.14
Added several in new features:
`keybinds`, `inline`, `debug`, `clear()`, `showClose`, `ingoreReadOnly`, `datepickerInput` and `keepInvalid`.
Bug squashing
## 4.0.0
#### Changes for using the component
* Defined a [Public API](https://github.com/Eonasdan/bootstrap-datetimepicker/wiki/Version-4-Public-API) and hidden rest of functions, variables so that all configuration options can be changed dynamically.
* `set/getDate()` is now replaced with an overloaded `date()` function. Use it without a parameter to get the currently set date or with a parameter to set the date.
* `hide()`, `show()`, `toggle()`, `enable()`, `disable()` and the rest of setter functions now support chaining. ie `$('#id').data('DateTimePicker').format('DD-MM-YYYY').minDate(moment()).defaultDate(moment()).show()` works
* Replaced previous - next buttons in Date subviews with configurable icons
* Changed `language` option name to `locale` to be inline with moment naming
* Implemented #402 all data-date-* variables are more readable and also match with the ones in the configuration object
* `options.direction` and `options.orientation` were merged into a single object `options.widgetPositioning` with `vertical` and `horizontal` keys that take a string value of `'auto', 'top', 'bottom'` and `'auto', 'left', 'right'` respectively. Note that the `'up'` option was renamed to `'top'`
#### Added functionality
* added a second way to define options as data attributes. Instead of adding distinct `data-date-*` config options you can now also pass a `data-date-options` attribute containing an object just the same as the options object that `element.datetimepicker` constructor call takes
* also added a `options()` public api function to get/set that takes an option object and applies it to the component in one call
* Implemented [#130](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/130) by introducing a boolean `options.calendarWeeks` and `calendarWeeks()` api function
* Implemented [#328](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/328), [#426](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/426)
* Implemented [#432](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/432). Widget DOM element is now lazily added only when shown and removed from the document when hidden.
* Implemented [#141](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/141) and [#283](https://github.com/Eonasdan/bootstrap-datetimepicker/issues/283)
#### Contributors related internal code changes
* Refactor all UI click functions and put them as functions in the actions array private variable
* Refactor template building process to seperate functions according to what they do
* Remove some styles that where hardcoded in the javascript code
* Refactor all code that changes the picker.date to change it through the setValue function to allow one place for validation logic (min/max/weekdaysenabled etc) and also one place for emmiting dp.change events
* The v4beta branch code includes all fixes up to v.3.1.2
* Added `toggle()` to the public API which toggles the visibility of the DateTimePicker
* Refactored set function to be included in the setValue function
* Added a testing framework using jasmine and phantom.js
# Version 3
## 3.0.0
* Fix for #170, #179, #183: Changed event to `dp.-`. This should fix the double change event firing.
* Fix for #192: `setDate` now fires `dp.change`
* Fix for #182: Picker will **not** set the default date if the input field has a value
* Fix for #169: Seconds doesn't get reset when changing the date (Thanks to PR #174)
* Fix for #168 z-index fix for BS modal
* Fix for #155 Picker properly displays the active year and month
* Fix for #154 CSS update to fix the collapse jump
* Fix for #150 and #75 `minViewMode` and `viewMode` work properly
* Fix for #147 AM/PM won't toggle when selecting a value from the hours grid
* Fix for #44 Finally! It's here!! Thanks to @ruiwei and his code on #210 picker will adjust the positioning of the widget.
#### Manually merged PR
* PR #178 When using `minuteStepping` the minute select grid will only show available steppings
* PR #195, #197 Using the `data-OPTION` has been changed to `data-date-OPTION`. These options are expected to be on the `input-group` if you're using the `input-group` **or** the a bare input field if you're not using the `input-group`
* PR #184 The option `sideBySide` change be used to display both the d and the timepicker side by side
* PR #143 Added option `daysOfWeekDisabled: []`. For example, use `daysOfWeekDisabled: [0,6]` to disable Sunday and Saturday
#### **Other Changes**
* Changed picker width to 300px if using seconds and am/pm
* Added option `useCurrent`, thanks to @ruiwei. When true, picker will set the value to the current date/time (respects picker's format)
* Added option `showToday`, thanks to @ruiwei. When true, picker will display a small arrow to indicate today's date.
* Changed `startDate` to `minDate` and `endDate` to `maxDate` to make it more clear what these options do.
# Version 2
#### 2.1.32 (Hotfix)
* Fix for #151: When a bad date value or the picker is cleared, the plugin will not longer attempt to reset it back to the previous date
* Fix for #140: `setDate` can be given `null` to force clear the picker
#### 2.1.30
##### Important! `build.less` file name has been been changed to `bootstrap-datetimepicker-build.less` to prevent collisions
* Fix for #135: `setStartDate` and `setEndDate` should now properly set.
* Fix for #133: Typed in date now respects en/disabled dates
* Fix for #132: En/disable picker function works again
* Fix for #117, #119, #128, #121: double event `change` event issues should be fixed
* Fix for #112: `change` function no longer sets the input to a blank value if the passed in date is invalid
* Enhancement for #103: Increated the `z-index` of the widget
#### 2.1.20
* Fix for #83: Changes to the picker should fire native `change` event for knockout and the like as well as `change.dp` which contains the old date and the new date
* Fix for #78: Script has been update for breaking changes in Moment 2.4.0
* Fix for #73: IE8 should be working now
* Enhancement for #79: `minuteStepping` option takes a number (default is 1). Changing the minutes in the time picker will step by this number.
* Enhancement for #74 and #65: `useMinutes` and `useSeconds` are now options. Disabling seconds will hide the seconds spinner. Disabling minutes will display `00` and hide the arrows
* Enhancement for #67: Picker will now attempt to convert all `data-OPTION` into its appropriate option
#### 2.1.11
* Fix for #51, #60
* Fix for #52: Picker has its own `moment` object since moment 2.4.0 has removed global reference
* Fix for #57: New option for `useStrict`. When validating dates in `update` and `change`, the picker can use a stricter formatting validation
* Fix for #61: Picker should now properly take formatted date. Should also have correct start of the week for locales.
* Fix for #62: Default format will properly validate time picker only.
#### 2.1.5
* Custom icons, such as Font Awesome, are now supported. (#49)
* If more then one `input-group-addon` is present use `datepickerbutton` to identify where the picker should popup from. (#48)
* New Event: `error.dp`. Fires when Moment cannot parse the date or when the timepicker cannot change because of a `disabledDates` setting. Returns a Moment date object. The specific error can be found be using `invalidAt()`. For more information see [Moment's docs](http://momentjs.com/docs/#/parsing/is-valid/)
* Fix for #42, plugin will now check for `A` or `a` in the format string to determine if the AM/PM selector should display.
* Fix for #45, fixed null/empty and invalid dates
* Fix for #46, fixed active date highlighting
* Fix for #47, `change.dp` event to also include the previous date.
####2.0.1
* New event `error.dp` fires when plugin cannot parse date or when increase/descreasing hours/minutes to a disabled date.
* Minor fixes
####2.0.0
* `disabledDates` is now an option to set the disabled dates. It accepts date objects like `new Date("November 12, 2013 00:00:00")` and `12/25/2013' and `moment` date objects
* Events are easier to use

View file

@ -1,161 +0,0 @@
# Minimal Requirements
1. jQuery
2. Moment.js
3. Bootstrap.js (transition and collapse are required if you're not using the full Bootstrap)
4. Bootstrap Datepicker script
5. Bootstrap CSS
6. Bootstrap Datepicker CSS
7. Locales: Moment's locale files are [here](https://github.com/moment/moment/tree/master/locale)
# Installation Guides
* [Bower](#bower-)
* [Nuget](#nuget)
* [Rails](#rails-)
* [Angular](#angular-wrapper)
* [Meteor.js](#meteorjs)
* [Manual](#manual)
## [bower](http://bower.io) ![Bower version](https://badge.fury.io/bo/eonasdan-bootstrap-datetimepicker.png)
Run the following command:
```
bower install eonasdan-bootstrap-datetimepicker#latest --save
```
Include necessary scripts and styles:
```html
<head>
<!-- ... -->
<script type="text/javascript" src="/bower_components/jquery/jquery.min.js"></script>
<script type="text/javascript" src="/bower_components/moment/min/moment.min.js"></script>
<script type="text/javascript" src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script type="text/javascript" src="/bower_components/eonasdan-bootstrap-datetimepicker/build/js/bootstrap-datetimepicker.min.js"></script>
<link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/bower_components/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css" />
</head>
```
## Nuget
### [LESS](https://www.nuget.org/packages/Bootstrap.v3.Datetimepicker/): ![NuGet version](https://badge.fury.io/nu/Bootstrap.v3.Datetimepicker.png)
```
PM> Install-Package Bootstrap.v3.Datetimepicker
```
### [CSS](https://www.nuget.org/packages/Bootstrap.v3.Datetimepicker.CSS/): ![NuGet version](https://badge.fury.io/nu/Bootstrap.v3.Datetimepicker.CSS.png)
```
PM> Install-Package Bootstrap.v3.Datetimepicker.CSS
```
```html
<head>
<script type="text/javascript" src="/scripts/jquery.min.js"></script>
<script type="text/javascript" src="/scripts/moment.min.js"></script>
<script type="text/javascript" src="/scripts/bootstrap.min.js"></script>
<script type="text/javascript" src="/scripts/bootstrap-datetimepicker.*js"></script>
<!-- include your less or built css files -->
<!--
bootstrap-datetimepicker-build.less will pull in "../bootstrap/variables.less" and "bootstrap-datetimepicker.less";
or
<link rel="stylesheet" href="/Content/bootstrap-datetimepicker.css" />
-->
</head>
```
## [Rails](http://rubygems.org/gems/bootstrap3-datetimepicker-rails) ![Gem Version](https://badge.fury.io/rb/bootstrap3-datetimepicker-rails.png)
Add the following to your `Gemfile`:
```ruby
gem 'momentjs-rails', '>= 2.9.0'
gem 'bootstrap3-datetimepicker-rails', '~> 4.14.30'
```
Note: You may need to change the version number above to the version number on the badge above.
Read the rest of the install instructions @
[TrevorS/bootstrap3-datetimepicker-rails](https://github.com/TrevorS/bootstrap3-datetimepicker-rails)
## Angular Wrapper
Follow the link [here](https://gist.github.com/eugenekgn/f00c4d764430642dca4b)
## Meteor.js
This widget has been package for the [Meteor.js](http://www.meteor.com/) platform, to install it use meteorite as follows:
`$ mrt add tsega:bootstrap3-datetimepicker`
For more detail see the package page on [Atmosphere](http://atmospherejs.com/package/bootstrap3-datetimepicker)
## Manual
### Acquire [jQuery](http://jquery.com)
### Acquire [Moment.js](https://github.com/moment/moment)
### Bootstrap 3 collapse and transition plugins
Make sure to include *.JS files for plugins [collapse](http://getbootstrap.com/javascript/#collapse) and [transitions](http://getbootstrap.com/javascript/#transitions). They are included with [bootstrap in js/ directory](https://github.com/twbs/bootstrap/tree/master/js)
Alternatively you could include the whole bundle of bootstrap plugins from [bootstrap.js](https://github.com/twbs/bootstrap/tree/master/dist/js)
```html
<script type="text/javascript" src="/path/to/jquery.js"></script>
<script type="text/javascript" src="/path/to/moment.js"></script>
<script type="text/javascript" src="/path/to/bootstrap/js/transition.js"></script>
<script type="text/javascript" src="/path/to/bootstrap/js/collapse.js"></script>
<script type="text/javascript" src="/path/to/bootstrap/dist/bootstrap.min.js"></script>
<script type="text/javascript" src="/path/to/bootstrap-datetimepicker.min.js"></script>
```
## Knockout
```
ko.bindingHandlers.dateTimePicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().dateTimePickerOptions || {};
$(element).datetimepicker(options);
//when a user changes the date, update the view model
ko.utils.registerEventHandler(element, "dp.change", function (event) {
var value = valueAccessor();
if (ko.isObservable(value)) {
if (event.date != null && !(event.date instanceof Date)) {
value(event.date.toDate());
} else {
value(event.date);
}
}
});
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
var picker = $(element).data("DateTimePicker");
if (picker) {
picker.destroy();
}
});
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var picker = $(element).data("DateTimePicker");
//when the view model is updated, update the widget
if (picker) {
var koDate = ko.utils.unwrapObservable(valueAccessor());
//in case return from server datetime i am get in this form for example /Date(93989393)/ then fomat this
koDate = (typeof (koDate) !== 'object') ? new Date(parseFloat(koDate.replace(/[^0-9]/g, ''))) : koDate;
picker.date(koDate);
}
}
};
```
### CSS styles
#### Using LESS
```css
@import "/path/to/bootstrap/less/variables";
@import "/path/to/bootstrap-datetimepicker/src/less/bootstrap-datetimepicker-build.less";
// [...] your custom styles and variables
```
Using CSS (default color palette)
```html
<link rel="stylesheet" href="/path/to/bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css" />
```

View file

@ -1,6 +0,0 @@
<meta http-equiv="refresh" content="1; url=/Changelog/"/>
<meta http-equiv="refresh" content="0; url=/Changelog/"/>
<link rel="canonical" href="/Changelog/">
<p>The page has moved to:
<a href="/Changelog/">this page</a></p>

View file

@ -1,6 +0,0 @@
<meta http-equiv="refresh" content="1; url=/Changelog/"/>
<meta http-equiv="refresh" content="0; url=/ContributorsGuide/"/>
<link rel="canonical" href="/ContributorsGuide/">
<p>The page has moved to:
<a href="/ContributorsGuide/">this page</a></p>

View file

@ -1,644 +0,0 @@
#Bootstrap 3 Datepicker v4 Docs
<div class="alert alert-info">
<strong>Note</strong>
All functions are accessed via the <code>data</code> attribute e.g. <code>$('#datetimepicker').data("DateTimePicker").FUNCTION()</code>
</div>
### Minimum Setup
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker();
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker1').datetimepicker();
});
</script>
</div>
</div>
```
----------------------
### Using Locales
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker2'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker2').datetimepicker({
locale: 'ru'
});
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker2'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker2').datetimepicker({
locale: 'ru'
});
});
</script>
</div>
</div>
```
----------------------
### Time Only
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'LT'
});
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'LT'
});
});
</script>
</div>
</div>
```
----------------------
### Date Only
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'L'
});
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker3'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-time"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker3').datetimepicker({
format: 'LT'
});
});
</script>
</div>
</div>
```
----------------------
### No Icon (input field only):
<div class="container">
<div class="row">
<div class='col-sm-6'>
<input type='text' class="form-control" id='datetimepicker4' />
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker4').datetimepicker();
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<input type='text' class="form-control" id='datetimepicker4' />
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker4').datetimepicker();
});
</script>
</div>
</div>
```
----------------------
### Enabled/Disabled Dates
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker5'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker5').datetimepicker({
defaultDate: "11/1/2013",
disabledDates: [
moment("12/25/2013"),
new Date(2013, 11 - 1, 21),
"11/22/2013 00:53"
]
});
});
</script>
</div>
</div>
#### Code
```
<div class="container">
<div class="row">
<div class='col-sm-6'>
<div class="form-group">
<div class='input-group date' id='datetimepicker5'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker5').datetimepicker({
defaultDate: "11/1/2013",
disabledDates: [
moment("12/25/2013"),
new Date(2013, 11 - 1, 21),
"11/22/2013 00:53"
]
});
});
</script>
</div>
</div>
```
----------------------
### Linked Pickers
<div class="container">
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker6'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker7'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker6').datetimepicker();
$('#datetimepicker7').datetimepicker({
useCurrent: false
});
$("#datetimepicker6").on("dp.change", function (e) {
$('#datetimepicker7').data("DateTimePicker").minDate(e.date);
});
$("#datetimepicker7").on("dp.change", function (e) {
$('#datetimepicker6').data("DateTimePicker").maxDate(e.date);
});
});
</script>
#### Code
```
<div class="container">
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker6'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
<div class='col-md-5'>
<div class="form-group">
<div class='input-group date' id='datetimepicker7'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker6').datetimepicker();
$('#datetimepicker7').datetimepicker({
useCurrent: false //Important! See issue #1075
});
$("#datetimepicker6").on("dp.change", function (e) {
$('#datetimepicker7').data("DateTimePicker").minDate(e.date);
});
$("#datetimepicker7").on("dp.change", function (e) {
$('#datetimepicker6').data("DateTimePicker").maxDate(e.date);
});
});
</script>
```
----------------------
### Custom Icons
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker8'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="fa fa-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker8').datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-arrow-up",
down: "fa fa-arrow-down"
}
});
});
</script>
</div>
#### Code
```
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker8'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="fa fa-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker8').datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-arrow-up",
down: "fa fa-arrow-down"
}
});
});
</script>
</div>
```
----------------------
### View Mode
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker9'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker9').datetimepicker({
viewMode: 'years'
});
});
</script>
</div>
#### Code
```
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker9'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker9').datetimepicker({
viewMode: 'years'
});
});
</script>
</div>
```
----------------------
### Min View Mode
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker10'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker10').datetimepicker({
viewMode: 'years',
format: 'MM/YYYY'
});
});
</script>
</div>
#### Code
```
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker10'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker10').datetimepicker({
viewMode: 'years',
format: 'MM/YYYY'
});
});
</script>
</div>
```
----------------------
### Disabled Days of the Week
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker11'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker11').datetimepicker({
daysOfWeekDisabled: [0, 6]
});
});
</script>
</div>
#### Code
```
<div class="container">
<div class="col-sm-6" style="height:130px;">
<div class="form-group">
<div class='input-group date' id='datetimepicker11'>
<input type='text' class="form-control" />
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar">
</span>
</span>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker11').datetimepicker({
daysOfWeekDisabled: [0, 6]
});
});
</script>
</div>
```
----------------------
### Inline
<div style="overflow:hidden;">
<div class="form-group">
<div class="row">
<div class="col-md-8">
<div id="datetimepicker12"></div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker12').datetimepicker({
inline: true,
sideBySide: true
});
});
</script>
</div>
#### Code
```
<div style="overflow:hidden;">
<div class="form-group">
<div class="row">
<div class="col-md-8">
<div id="datetimepicker12"></div>
</div>
</div>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker12').datetimepicker({
inline: true,
sideBySide: true
});
});
</script>
</div>
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Some files were not shown because too many files have changed in this diff Show more