diff --git a/dist/LICENSE b/dist/LICENSE new file mode 100644 index 0000000..4644c8c --- /dev/null +++ b/dist/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Grafana + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dist/MANIFEST.txt b/dist/MANIFEST.txt new file mode 100644 index 0000000..feac7d9 --- /dev/null +++ b/dist/MANIFEST.txt @@ -0,0 +1,36 @@ + +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +{ + "plugin": "grafana-piechart-panel", + "version": "1.6.1", + "files": { + "LICENSE": "b46400c1ab5630edeb4e43b240a027d203375ebe5a9efb7de88c604c5c5cace0", + "README.md": "549e456ba86b2677fbb55f21dac137452d1fa10b8f73534f2c9be06dfe0ed21c", + "dark.js": "1e1732392f8c733433d5078f62c181732b2e9cf801915a7cac1db1b29777d22e", + "dark.js.map": "9f9a08e0c7c69f92a7bab8690faadc8ec2f65379834362cdb45fb8d6679a7336", + "editor.html": "aa4a490a2a93c1c6fdcbfc2cf7351afd1af213205ce74ab1f3f4f08bac9db24c", + "light.js": "eb1808113eafd870881e57b3a28f4229a3710981670b0dc7409742a01b041259", + "light.js.map": "80ee11ec21f071cf8988b3b049e8159cbcdb6153b5ca9a5523fe7dbf96083323", + "module.html": "10d8f62fdc7359e904e04b34400d8770098d4973e7796b54f007e6a8fa284a3b", + "module.js": "20da74222a8af656376bbd77558c936df722db5a295cea460f58e0a1dc0a5a96", + "module.js.LICENSE.txt": "30f143a8e05630b1ab2ff90e572b97708701d7fc5f8e8fd2e44bbe9787723aea", + "module.js.map": "932bbcc50abe443aca25323f05ce53baef20363ffb6fa803ff7434d86a44a01b", + "plugin.json": "51692acde552a569ec2716465586ea64bddead48aa279a35cda43b6722e78d17", + "styles/dark.css": "e0c2663c2c7dabf97ffaebc740a3b5f7fb69aefaaf89351d9fa8762f77ec5cf6", + "styles/light.css": "6430d7d73d05e50adedf3d0ec9fa6f26970ca362f24be63b3b8f506405f8a921" + }, + "time": 1600286584192, + "keyId": "7e4d0c6a708866e7" +} +-----BEGIN PGP SIGNATURE----- +Version: OpenPGP.js v4.10.1 +Comment: https://openpgpjs.org + +wqIEARMKAAYFAl9ib3gACgkQfk0ManCIZucMEAIJAdAVb6pOOaYvNDBWDXmr +u7fsPS4qr96g+WHpMfQf9TSuEqAWMbKBHJQIyYLR2Q5ZvL+h+aQpfb6gsCqZ +SKFRobEeAgkB5wsDfPMof5lwJf8IP1t293xURrVKWadtpp0mV5N+Fxrf6YQ0 +GiTNk5Y+zmmf7lmhQ7efGf/vW04ePgsvJGjz6pE= +=IlbY +-----END PGP SIGNATURE----- diff --git a/dist/README.md b/dist/README.md new file mode 100644 index 0000000..d8553c8 --- /dev/null +++ b/dist/README.md @@ -0,0 +1,53 @@ +[![CircleCI](https://circleci.com/gh/grafana/piechart-panel.svg?style=svg)](https://circleci.com/gh/grafana/piechart-panel) +[![David Dependancy Status](https://david-dm.org/grafana/piechart-panel.svg)](https://david-dm.org/grafana/piechart-panel) +[![David Dev Dependency Status](https://david-dm.org/grafana/piechart-panel/dev-status.svg)](https://david-dm.org/grafana/piechart-panel/?type=dev) + +Use the new grafana-cli tool to install piechart-panel from the commandline: + +``` +grafana-cli plugins install grafana-piechart-panel +``` + +The plugin will be installed into your grafana plugins directory; the default is /var/lib/grafana/plugins if you installed the grafana package. + +More instructions on the cli tool can be found [here](https://grafana.com/docs/grafana/latest/plugins/installation/). + +You need the lastest grafana build for Grafana 3.0 to enable plugin support. You can get it here : http://grafana.org/download/builds.html + +## Alternative installation methods + +### Download latest zip + +```BASH +wget -nv https://grafana.com/api/plugins/grafana-piechart-panel/versions/latest/download -O /tmp/grafana-piechart-panel.zip +``` + +Extract and move into place +```BASH +unzip -q /tmp/grafana-piechart-panel.zip -d /tmp +mv /tmp/grafana-piechart-panel-* /var/lib/grafana/plugins/grafana-piechart-panel +sudo service grafana-server restart +``` + +### Git Clone +It is also possible to clone this repo directly into your plugins directory. + +Afterwards restart grafana-server and the plugin should be automatically detected and used. + +``` +git clone https://github.com/grafana/piechart-panel.git --branch release-1.3.8 +sudo service grafana-server restart +``` + +### Clone into a directory of your choice + +If the plugin is cloned to a directory that is not the default plugins directory then you need to edit your grafana.ini config file (Default location is at /etc/grafana/grafana.ini) and add this: + +```ini +[plugin.piechart] +path = /home/your/clone/dir/piechart-panel +``` + +Note that if you clone it into the grafana plugins directory you do not need to add the above config option. That is only +if you want to place the plugin in a directory outside the standard plugins directory. Be aware that grafana-server +needs read access to the directory. diff --git a/dist/dark.js b/dist/dark.js new file mode 100644 index 0000000..7600bcd --- /dev/null +++ b/dist/dark.js @@ -0,0 +1,2 @@ +define((function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=10)}({10:function(e,t,n){}})})); +//# sourceMappingURL=dark.js.map \ No newline at end of file diff --git a/dist/dark.js.map b/dist/dark.js.map new file mode 100644 index 0000000..05fe0a2 --- /dev/null +++ b/dist/dark.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"sCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,IAIjBlC,EAAoBA,EAAoBmC,EAAI,I","file":"dark.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 10);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/editor.html b/dist/editor.html similarity index 100% rename from src/editor.html rename to dist/editor.html diff --git a/src/img/piechart-donut.png b/dist/img/piechart-donut.png similarity index 100% rename from src/img/piechart-donut.png rename to dist/img/piechart-donut.png diff --git a/src/img/piechart-legend-on-graph.png b/dist/img/piechart-legend-on-graph.png similarity index 100% rename from src/img/piechart-legend-on-graph.png rename to dist/img/piechart-legend-on-graph.png diff --git a/src/img/piechart-legend-rhs.png b/dist/img/piechart-legend-rhs.png similarity index 100% rename from src/img/piechart-legend-rhs.png rename to dist/img/piechart-legend-rhs.png diff --git a/src/img/piechart-legend-under.png b/dist/img/piechart-legend-under.png similarity index 100% rename from src/img/piechart-legend-under.png rename to dist/img/piechart-legend-under.png diff --git a/src/img/piechart-options.png b/dist/img/piechart-options.png similarity index 100% rename from src/img/piechart-options.png rename to dist/img/piechart-options.png diff --git a/src/img/piechart_logo_large.png b/dist/img/piechart_logo_large.png similarity index 100% rename from src/img/piechart_logo_large.png rename to dist/img/piechart_logo_large.png diff --git a/src/img/piechart_logo_large.svg b/dist/img/piechart_logo_large.svg similarity index 100% rename from src/img/piechart_logo_large.svg rename to dist/img/piechart_logo_large.svg diff --git a/src/img/piechart_logo_small.png b/dist/img/piechart_logo_small.png similarity index 100% rename from src/img/piechart_logo_small.png rename to dist/img/piechart_logo_small.png diff --git a/src/img/piechart_logo_small.svg b/dist/img/piechart_logo_small.svg similarity index 100% rename from src/img/piechart_logo_small.svg rename to dist/img/piechart_logo_small.svg diff --git a/dist/light.js b/dist/light.js new file mode 100644 index 0000000..470e7cd --- /dev/null +++ b/dist/light.js @@ -0,0 +1,2 @@ +define((function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=9)}({9:function(e,t,n){}})})); +//# sourceMappingURL=light.js.map \ No newline at end of file diff --git a/dist/light.js.map b/dist/light.js.map new file mode 100644 index 0000000..23ffa6e --- /dev/null +++ b/dist/light.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s"],"mappings":"sCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,IAIjBlC,EAAoBA,EAAoBmC,EAAI,G","file":"light.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 9);\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/module.html b/dist/module.html similarity index 100% rename from src/module.html rename to dist/module.html diff --git a/dist/module.js b/dist/module.js new file mode 100644 index 0000000..b6689ac --- /dev/null +++ b/dist/module.js @@ -0,0 +1,3 @@ +/*! For license information please see module.js.LICENSE.txt */ +define(["jquery","lodash","app/plugins/sdk","app/core/utils/kbn","app/core/time_series","angular"],(function(e,t,n,i,r,o){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var r=t[i]={i:i,l:!1,exports:{}};return e[i].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(i,r,function(t){return e[t]}.bind(null,r));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=11)}([function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t){e.exports=n},function(e,t){e.exports=i},function(e,t){e.exports=r},function(e,t){e.exports=o},function(e,t,n){var i,r;function o(e){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(l,a){"object"==o(t)&&void 0!==e?e.exports=a():void 0===(r="function"==typeof(i=a)?i.call(t,n,t,e):i)||(e.exports=r)}(0,(function(){"use strict";function e(e){return getComputedStyle(e)}function t(e,t){for(var n in t){var i=t[n];"number"==typeof i&&(i+="px"),e.style[n]=i}return e}function n(e){var t=document.createElement("div");return t.className=e,t}function i(e,t){if(!f)throw new Error("No element matching method supported");return f.call(e,t)}function r(e){e.remove?e.remove():e.parentNode&&e.parentNode.removeChild(e)}function o(e,t){return Array.prototype.filter.call(e.children,(function(e){return i(e,t)}))}function l(e,t){var n=e.element.classList,i=v.state.scrolling(t);n.contains(i)?clearTimeout(b[t]):n.add(i)}function a(e,t){b[t]=setTimeout((function(){return e.isAlive&&e.element.classList.remove(v.state.scrolling(t))}),e.settings.scrollingThreshold)}function s(e,t){l(e,t),a(e,t)}function c(e){if("function"==typeof window.CustomEvent)return new CustomEvent(e);var t=document.createEvent("CustomEvent");return t.initCustomEvent(e,!1,!1,void 0),t}function h(e){return parseInt(e,10)||0}function d(e){return i(e,"input,[contenteditable]")||i(e,"select,[contenteditable]")||i(e,"textarea,[contenteditable]")||i(e,"button,[contenteditable]")}function u(e,t){return e.settings.minScrollbarLength&&(t=Math.max(t,e.settings.minScrollbarLength)),e.settings.maxScrollbarLength&&(t=Math.min(t,e.settings.maxScrollbarLength)),t}function p(e,n){var i={width:n.railXWidth};n.isRtl?i.left=n.negativeScrollAdjustment+e.scrollLeft+n.containerWidth-n.contentWidth:i.left=e.scrollLeft,n.isScrollbarXUsingBottom?i.bottom=n.scrollbarXBottom-e.scrollTop:i.top=n.scrollbarXTop+e.scrollTop,t(n.scrollbarXRail,i);var r={top:e.scrollTop,height:n.railYHeight};n.isScrollbarYUsingRight?n.isRtl?r.right=n.contentWidth-(n.negativeScrollAdjustment+e.scrollLeft)-n.scrollbarYRight-n.scrollbarYOuterWidth:r.right=n.scrollbarYRight-e.scrollLeft:n.isRtl?r.left=n.negativeScrollAdjustment+e.scrollLeft+2*n.containerWidth-n.contentWidth-n.scrollbarYLeft-n.scrollbarYOuterWidth:r.left=n.scrollbarYLeft+e.scrollLeft,t(n.scrollbarYRail,r),t(n.scrollbarX,{left:n.scrollbarXLeft,width:n.scrollbarXWidth-n.railBorderXWidth}),t(n.scrollbarY,{top:n.scrollbarYTop,height:n.scrollbarYHeight-n.railBorderYWidth})}function g(e,t){function n(t){g[u]=f+b*(t[s]-v),l(e,p),k(e),t.stopPropagation(),t.preventDefault()}function i(){a(e,p),e.event.unbind(e.ownerDocument,"mousemove",n)}var r=t[0],o=t[1],s=t[2],c=t[3],h=t[4],d=t[5],u=t[6],p=t[7],g=e.element,f=null,v=null,b=null;e.event.bind(e[h],"mousedown",(function(t){f=g[u],v=t[s],b=(e[o]-e[r])/(e[c]-e[d]),e.event.bind(e.ownerDocument,"mousemove",n),e.event.once(e.ownerDocument,"mouseup",i),t.stopPropagation(),t.preventDefault()}))}var f=Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.msMatchesSelector,v={main:"ps",element:{thumb:function(e){return"ps__thumb-"+e},rail:function(e){return"ps__rail-"+e},consuming:"ps__child--consume"},state:{focus:"ps--focus",active:function(e){return"ps--active-"+e},scrolling:function(e){return"ps--scrolling-"+e}}},b={x:null,y:null},m=function(e){this.element=e,this.handlers={}},y={isEmpty:{configurable:!0}};m.prototype.bind=function(e,t){void 0===this.handlers[e]&&(this.handlers[e]=[]),this.handlers[e].push(t),this.element.addEventListener(e,t,!1)},m.prototype.unbind=function(e,t){var n=this;this.handlers[e]=this.handlers[e].filter((function(i){return!(!t||i===t)||(n.element.removeEventListener(e,i,!1),!1)}))},m.prototype.unbindAll=function(){for(var e in this.handlers)this.unbind(e)},y.isEmpty.get=function(){var e=this;return Object.keys(this.handlers).every((function(t){return 0===e.handlers[t].length}))},Object.defineProperties(m.prototype,y);var w=function(){this.eventElements=[]};w.prototype.eventElement=function(e){var t=this.eventElements.filter((function(t){return t.element===e}))[0];return t||(t=new m(e),this.eventElements.push(t)),t},w.prototype.bind=function(e,t,n){this.eventElement(e).bind(t,n)},w.prototype.unbind=function(e,t,n){var i=this.eventElement(e);i.unbind(t,n),i.isEmpty&&this.eventElements.splice(this.eventElements.indexOf(i),1)},w.prototype.unbindAll=function(){this.eventElements.forEach((function(e){return e.unbindAll()})),this.eventElements=[]},w.prototype.once=function(e,t,n){var i=this.eventElement(e);i.bind(t,(function e(r){i.unbind(t,e),n(r)}))};var S=function(e,t,n,i,r){var o;if(void 0===i&&(i=!0),void 0===r&&(r=!1),"top"===t)o=["contentHeight","containerHeight","scrollTop","y","up","down"];else{if("left"!==t)throw new Error("A proper axis should be provided");o=["contentWidth","containerWidth","scrollLeft","x","left","right"]}!function(e,t,n,i,r){var o=n[0],l=n[1],a=n[2],h=n[3],d=n[4],u=n[5];void 0===i&&(i=!0),void 0===r&&(r=!1);var p=e.element;e.reach[h]=null,p[a]<1&&(e.reach[h]="start"),p[a]>e[o]-e[l]-1&&(e.reach[h]="end"),t&&(p.dispatchEvent(c("ps-scroll-"+h)),t<0?p.dispatchEvent(c("ps-scroll-"+d)):t>0&&p.dispatchEvent(c("ps-scroll-"+u)),i&&s(e,h)),e.reach[h]&&(t||r)&&p.dispatchEvent(c("ps-"+h+"-reach-"+e.reach[h]))}(e,n,o,i,r)},M=document&&"WebkitAppearance"in document.documentElement.style,Y=window&&("ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),T=navigator&&navigator.msMaxTouchPoints,k=function(e){var t=e.element;e.containerWidth=t.clientWidth,e.containerHeight=t.clientHeight,e.contentWidth=t.scrollWidth,e.contentHeight=t.scrollHeight,t.contains(e.scrollbarXRail)||(o(t,v.element.rail("x")).forEach((function(e){return r(e)})),t.appendChild(e.scrollbarXRail)),t.contains(e.scrollbarYRail)||(o(t,v.element.rail("y")).forEach((function(e){return r(e)})),t.appendChild(e.scrollbarYRail)),!e.settings.suppressScrollX&&e.containerWidth+e.settings.scrollXMarginOffset=e.railXWidth-e.scrollbarXWidth&&(e.scrollbarXLeft=e.railXWidth-e.scrollbarXWidth),e.scrollbarYTop>=e.railYHeight-e.scrollbarYHeight&&(e.scrollbarYTop=e.railYHeight-e.scrollbarYHeight),p(t,e),e.scrollbarXActive?t.classList.add(v.state.active("x")):(t.classList.remove(v.state.active("x")),e.scrollbarXWidth=0,e.scrollbarXLeft=0,t.scrollLeft=0),e.scrollbarYActive?t.classList.add(v.state.active("y")):(t.classList.remove(v.state.active("y")),e.scrollbarYHeight=0,e.scrollbarYTop=0,t.scrollTop=0)},X={"click-rail":function(e){e.event.bind(e.scrollbarY,"mousedown",(function(e){return e.stopPropagation()})),e.event.bind(e.scrollbarYRail,"mousedown",(function(t){var n=t.pageY-window.pageYOffset-e.scrollbarYRail.getBoundingClientRect().top>e.scrollbarYTop?1:-1;e.element.scrollTop+=n*e.containerHeight,k(e),t.stopPropagation()})),e.event.bind(e.scrollbarX,"mousedown",(function(e){return e.stopPropagation()})),e.event.bind(e.scrollbarXRail,"mousedown",(function(t){var n=t.pageX-window.pageXOffset-e.scrollbarXRail.getBoundingClientRect().left>e.scrollbarXLeft?1:-1;e.element.scrollLeft+=n*e.containerWidth,k(e),t.stopPropagation()}))},"drag-thumb":function(e){g(e,["containerWidth","contentWidth","pageX","railXWidth","scrollbarX","scrollbarXWidth","scrollLeft","x"]),g(e,["containerHeight","contentHeight","pageY","railYHeight","scrollbarY","scrollbarYHeight","scrollTop","y"])},keyboard:function(e){var t=e.element,n=function(){return i(t,":hover")},r=function(){return i(e.scrollbarX,":focus")||i(e.scrollbarY,":focus")};e.event.bind(e.ownerDocument,"keydown",(function(i){if(!(i.isDefaultPrevented&&i.isDefaultPrevented()||i.defaultPrevented)&&(n()||r())){var o=document.activeElement?document.activeElement:e.ownerDocument.activeElement;if(o){if("IFRAME"===o.tagName)o=o.contentDocument.activeElement;else for(;o.shadowRoot;)o=o.shadowRoot.activeElement;if(d(o))return}var l=0,a=0;switch(i.which){case 37:l=i.metaKey?-e.contentWidth:i.altKey?-e.containerWidth:-30;break;case 38:a=i.metaKey?e.contentHeight:i.altKey?e.containerHeight:30;break;case 39:l=i.metaKey?e.contentWidth:i.altKey?e.containerWidth:30;break;case 40:a=i.metaKey?-e.contentHeight:i.altKey?-e.containerHeight:-30;break;case 32:a=i.shiftKey?e.containerHeight:-e.containerHeight;break;case 33:a=e.containerHeight;break;case 34:a=-e.containerHeight;break;case 36:a=e.contentHeight;break;case 35:a=-e.contentHeight;break;default:return}e.settings.suppressScrollX&&0!==l||e.settings.suppressScrollY&&0!==a||(t.scrollTop-=a,t.scrollLeft+=l,k(e),function(n,i){var r=t.scrollTop;if(0===n){if(!e.scrollbarYActive)return!1;if(0===r&&i>0||r>=e.contentHeight-e.containerHeight&&i<0)return!e.settings.wheelPropagation}var o=t.scrollLeft;if(0===i){if(!e.scrollbarXActive)return!1;if(0===o&&n<0||o>=e.contentWidth-e.containerWidth&&n>0)return!e.settings.wheelPropagation}return!0}(l,a)&&i.preventDefault())}}))},wheel:function(t){function n(t,n,i){if(!M&&r.querySelector("select:focus"))return!0;if(!r.contains(t))return!1;for(var o=t;o&&o!==r;){if(o.classList.contains(v.element.consuming))return!0;var l=e(o);if([l.overflow,l.overflowX,l.overflowY].join("").match(/(scroll|auto)/)){var a=o.scrollHeight-o.clientHeight;if(a>0&&!(0===o.scrollTop&&i>0||o.scrollTop===a&&i<0))return!0;var s=o.scrollLeft-o.clientWidth;if(s>0&&!(0===o.scrollLeft&&n<0||o.scrollLeft===s&&n>0))return!0}o=o.parentNode}return!1}function i(e){var i=function(e){var t=e.deltaX,n=-1*e.deltaY;return void 0!==t&&void 0!==n||(t=-1*e.wheelDeltaX/6,n=e.wheelDeltaY/6),e.deltaMode&&1===e.deltaMode&&(t*=10,n*=10),t!=t&&n!=n&&(t=0,n=e.wheelDelta),e.shiftKey?[-n,-t]:[t,n]}(e),o=i[0],l=i[1];if(!n(e.target,o,l)){var a=!1;t.settings.useBothWheelAxes?t.scrollbarYActive&&!t.scrollbarXActive?(l?r.scrollTop-=l*t.settings.wheelSpeed:r.scrollTop+=o*t.settings.wheelSpeed,a=!0):t.scrollbarXActive&&!t.scrollbarYActive&&(o?r.scrollLeft+=o*t.settings.wheelSpeed:r.scrollLeft-=l*t.settings.wheelSpeed,a=!0):(r.scrollTop-=l*t.settings.wheelSpeed,r.scrollLeft+=o*t.settings.wheelSpeed),k(t),(a=a||function(e,n){var i=r.scrollTop;if(0===e){if(!t.scrollbarYActive)return!1;if(0===i&&n>0||i>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var o=r.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===o&&e<0||o>=t.contentWidth-t.containerWidth&&e>0)return!t.settings.wheelPropagation}return!0}(o,l))&&!e.ctrlKey&&(e.stopPropagation(),e.preventDefault())}}var r=t.element;void 0!==window.onwheel?t.event.bind(r,"wheel",i):void 0!==window.onmousewheel&&t.event.bind(r,"mousewheel",i)},touch:function(e){function t(t,n){var i=h.scrollTop,r=h.scrollLeft,o=Math.abs(t),l=Math.abs(n);if(l>o){if(n<0&&i===e.contentHeight-e.containerHeight||n>0&&0===i)return{stop:!e.settings.swipePropagation,prevent:0===window.scrollY}}else if(o>l&&(t<0&&r===e.contentWidth-e.containerWidth||t>0&&0===r))return{stop:!e.settings.swipePropagation,prevent:!0};return{stop:!0,prevent:!0}}function n(t,n){h.scrollTop-=n,h.scrollLeft-=t,k(e)}function i(){f=!0}function r(){f=!1}function o(e){return e.targetTouches?e.targetTouches[0]:e}function l(e){return!(e.pointerType&&"pen"===e.pointerType&&0===e.buttons||(!e.targetTouches||1!==e.targetTouches.length)&&(!e.pointerType||"mouse"===e.pointerType||e.pointerType===e.MSPOINTER_TYPE_MOUSE))}function a(e){if(l(e)){v=!0;var t=o(e);d.pageX=t.pageX,d.pageY=t.pageY,u=(new Date).getTime(),null!==g&&clearInterval(g),e.stopPropagation()}}function s(i){if(!v&&e.settings.swipePropagation&&a(i),!f&&v&&l(i)){var r=o(i),s={pageX:r.pageX,pageY:r.pageY},c=s.pageX-d.pageX,h=s.pageY-d.pageY;n(c,h),d=s;var g=(new Date).getTime(),b=g-u;b>0&&(p.x=c/b,p.y=h/b,u=g);var m=t(c,h),y=m.stop,w=m.prevent;y&&i.stopPropagation(),w&&i.preventDefault()}}function c(){!f&&v&&(v=!1,e.settings.swipeEasing&&(clearInterval(g),g=setInterval((function(){e.isInitialized?clearInterval(g):p.x||p.y?Math.abs(p.x)<.01&&Math.abs(p.y)<.01?clearInterval(g):(n(30*p.x,30*p.y),p.x*=.8,p.y*=.8):clearInterval(g)}),10)))}if(Y||T){var h=e.element,d={},u=0,p={},g=null,f=!1,v=!1;Y?(e.event.bind(window,"touchstart",i),e.event.bind(window,"touchend",r),e.event.bind(h,"touchstart",a),e.event.bind(h,"touchmove",s),e.event.bind(h,"touchend",c)):T&&(window.PointerEvent?(e.event.bind(window,"pointerdown",i),e.event.bind(window,"pointerup",r),e.event.bind(h,"pointerdown",a),e.event.bind(h,"pointermove",s),e.event.bind(h,"pointerup",c)):window.MSPointerEvent&&(e.event.bind(window,"MSPointerDown",i),e.event.bind(window,"MSPointerUp",r),e.event.bind(h,"MSPointerDown",a),e.event.bind(h,"MSPointerMove",s),e.event.bind(h,"MSPointerUp",c)))}}},W=function(i,r){var o=this;if(void 0===r&&(r={}),"string"==typeof i&&(i=document.querySelector(i)),!i||!i.nodeName)throw new Error("no element is specified to initialize PerfectScrollbar");for(var l in this.element=i,i.classList.add(v.main),this.settings={handlers:["click-rail","drag-thumb","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollingThreshold:1e3,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,swipeEasing:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1},r)o.settings[l]=r[l];this.containerWidth=null,this.containerHeight=null,this.contentWidth=null,this.contentHeight=null;var a=function(){return i.classList.add(v.state.focus)},s=function(){return i.classList.remove(v.state.focus)};this.isRtl="rtl"===e(i).direction,this.isNegativeScroll=function(){var e,t=i.scrollLeft;return i.scrollLeft=-1,e=i.scrollLeft<0,i.scrollLeft=t,e}(),this.negativeScrollAdjustment=this.isNegativeScroll?i.scrollWidth-i.clientWidth:0,this.event=new w,this.ownerDocument=i.ownerDocument||document,this.scrollbarXRail=n(v.element.rail("x")),i.appendChild(this.scrollbarXRail),this.scrollbarX=n(v.element.thumb("x")),this.scrollbarXRail.appendChild(this.scrollbarX),this.scrollbarX.setAttribute("tabindex",0),this.event.bind(this.scrollbarX,"focus",a),this.event.bind(this.scrollbarX,"blur",s),this.scrollbarXActive=null,this.scrollbarXWidth=null,this.scrollbarXLeft=null;var c=e(this.scrollbarXRail);this.scrollbarXBottom=parseInt(c.bottom,10),isNaN(this.scrollbarXBottom)?(this.isScrollbarXUsingBottom=!1,this.scrollbarXTop=h(c.top)):this.isScrollbarXUsingBottom=!0,this.railBorderXWidth=h(c.borderLeftWidth)+h(c.borderRightWidth),t(this.scrollbarXRail,{display:"block"}),this.railXMarginWidth=h(c.marginLeft)+h(c.marginRight),t(this.scrollbarXRail,{display:""}),this.railXWidth=null,this.railXRatio=null,this.scrollbarYRail=n(v.element.rail("y")),i.appendChild(this.scrollbarYRail),this.scrollbarY=n(v.element.thumb("y")),this.scrollbarYRail.appendChild(this.scrollbarY),this.scrollbarY.setAttribute("tabindex",0),this.event.bind(this.scrollbarY,"focus",a),this.event.bind(this.scrollbarY,"blur",s),this.scrollbarYActive=null,this.scrollbarYHeight=null,this.scrollbarYTop=null;var d=e(this.scrollbarYRail);this.scrollbarYRight=parseInt(d.right,10),isNaN(this.scrollbarYRight)?(this.isScrollbarYUsingRight=!1,this.scrollbarYLeft=h(d.left)):this.isScrollbarYUsingRight=!0,this.scrollbarYOuterWidth=this.isRtl?function(t){var n=e(t);return h(n.width)+h(n.paddingLeft)+h(n.paddingRight)+h(n.borderLeftWidth)+h(n.borderRightWidth)}(this.scrollbarY):null,this.railBorderYWidth=h(d.borderTopWidth)+h(d.borderBottomWidth),t(this.scrollbarYRail,{display:"block"}),this.railYMarginHeight=h(d.marginTop)+h(d.marginBottom),t(this.scrollbarYRail,{display:""}),this.railYHeight=null,this.railYRatio=null,this.reach={x:i.scrollLeft<=0?"start":i.scrollLeft>=this.contentWidth-this.containerWidth?"end":null,y:i.scrollTop<=0?"start":i.scrollTop>=this.contentHeight-this.containerHeight?"end":null},this.isAlive=!0,this.settings.handlers.forEach((function(e){return X[e](o)})),this.lastScrollTop=i.scrollTop,this.lastScrollLeft=i.scrollLeft,this.event.bind(this.element,"scroll",(function(e){return o.onScroll(e)})),k(this)};return W.prototype.update=function(){this.isAlive&&(this.negativeScrollAdjustment=this.isNegativeScroll?this.element.scrollWidth-this.element.clientWidth:0,t(this.scrollbarXRail,{display:"block"}),t(this.scrollbarYRail,{display:"block"}),this.railXMarginWidth=h(e(this.scrollbarXRail).marginLeft)+h(e(this.scrollbarXRail).marginRight),this.railYMarginHeight=h(e(this.scrollbarYRail).marginTop)+h(e(this.scrollbarYRail).marginBottom),t(this.scrollbarXRail,{display:"none"}),t(this.scrollbarYRail,{display:"none"}),k(this),S(this,"top",0,!1,!0),S(this,"left",0,!1,!0),t(this.scrollbarXRail,{display:""}),t(this.scrollbarYRail,{display:""}))},W.prototype.onScroll=function(e){this.isAlive&&(k(this),S(this,"top",this.element.scrollTop-this.lastScrollTop),S(this,"left",this.element.scrollLeft-this.lastScrollLeft),this.lastScrollTop=this.element.scrollTop,this.lastScrollLeft=this.element.scrollLeft)},W.prototype.destroy=function(){this.isAlive&&(this.event.unbindAll(),r(this.scrollbarX),r(this.scrollbarY),r(this.scrollbarXRail),r(this.scrollbarYRail),this.removePsClasses(),this.element=null,this.scrollbarX=null,this.scrollbarY=null,this.scrollbarXRail=null,this.scrollbarYRail=null,this.isAlive=!1)},W.prototype.removePsClasses=function(){this.element.className=this.element.className.split(" ").filter((function(e){return!e.match(/^ps([-_].+|)$/)})).join(" ")},W}))},function(e,t){var n,i;n=jQuery,i={series:{pie:{show:!1,radius:"auto",innerRadius:0,startAngle:1.5,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(e,t){return"
"+e+"
"+Math.round(t.percent)+"%
"},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}},n.plot.plugins.push({init:function(e){var t=null,i=null,r=null,o=null,l=null,a=null,s=!1,c=null,h=[];function d(e,o,l){s||(s=!0,t=e.getCanvas(),i=n(t).parent(),r=e.getOptions(),e.setData(function(e){for(var t=0,i=0,o=0,l=r.series.pie.combine.color,a=[],s=0;sr.series.pie.combine.threshold)&&a.push(n.extend(e[s],{data:[[1,c]],color:e[s].color,label:e[s].label,angle:c*Math.PI*2/t,percent:c/(t/100)}));return o>1&&a.push({data:[[1,i]],color:l,label:r.series.pie.combine.label,angle:i*Math.PI*2/t,percent:i/(t/100)}),a}(e.getData())))}function u(e,t){if(i){var h=e.getPlaceholder().width(),d=e.getPlaceholder().height(),u=i.children().filter(".legend").children().width()||0;c=t,s=!1,o=Math.min(h,d/r.series.pie.tilt)/2,a=d/2+r.series.pie.offset.top,l=h/2,"auto"==r.series.pie.offset.left?(r.legend.position.match("w")?l+=u/2:l-=u/2,lh-o&&(l=h-o)):l+=r.series.pie.offset.left;var g=e.getData(),f=0;do{f>0&&(o*=.95),f+=1,v(),r.series.pie.tilt<=.8&&b()}while(!m()&&f<10);f>=10&&(v(),i.prepend("
Could not draw pie with labels contained inside canvas
")),e.setSeries&&e.insertLegend&&(e.setSeries(g),e.insertLegend())}function v(){c.clearRect(0,0,h,d),i.children().filter(".pieLabel, .pieLabelBackground").remove()}function b(){var e=r.series.pie.shadow.left,t=r.series.pie.shadow.top,n=r.series.pie.shadow.alpha,i=r.series.pie.radius>1?r.series.pie.radius:o*r.series.pie.radius;if(!(i>=h/2-e||i*r.series.pie.tilt>=d/2-t||i<=10)){c.save(),c.translate(e,t),c.globalAlpha=n,c.fillStyle="#000",c.translate(l,a),c.scale(1,r.series.pie.tilt);for(var s=1;s<=10;s++)c.beginPath(),c.arc(0,0,i,0,2*Math.PI,!1),c.fill(),i-=s;c.restore()}}function m(){var e=Math.PI*r.series.pie.startAngle,t=r.series.pie.radius>1?r.series.pie.radius:o*r.series.pie.radius;c.save(),c.translate(l,a),c.scale(1,r.series.pie.tilt),c.save();for(var s=e,u=0;u0){for(c.save(),c.lineWidth=r.series.pie.stroke.width,s=e,u=0;u1?r.series.pie.label.radius:o*r.series.pie.label.radius,c=0;c=100*r.series.pie.label.threshold&&!u(g[c],t,c))return!1;t+=g[c].angle}return!0;function u(e,t,o){if(0==e.data[0][1])return!0;var c,u=r.legend.labelFormatter,p=r.series.pie.label.formatter;c=u?u(e.label,e):e.label,p&&(c=p(c,e));var g=(t+e.angle+t)/2,f=l+Math.round(Math.cos(g)*s),v=a+Math.round(Math.sin(g)*s)*r.series.pie.tilt,b=""+c+"";i.append(b);var m=i.children("#pieLabel"+o),y=v-m.height()/2,w=f-m.width()/2;if(m.css("top",y),m.css("left",w),0-y>0||0-w>0||d-(y+m.height())<0||h-(w+m.width())<0)return!1;if(0!=r.series.pie.label.background.opacity){var S=r.series.pie.label.background.color;null==S&&(S=e.color);var M="top:"+y+"px;left:"+w+"px;";n("
").css("opacity",r.series.pie.label.background.opacity).insertBefore(m)}return!0}}();function f(e,n,i){e<=0||isNaN(e)||(i?c.fillStyle=n:(c.strokeStyle=n,c.lineJoin="round"),c.beginPath(),Math.abs(e-2*Math.PI)>1e-9&&c.moveTo(0,0),c.arc(0,0,t,s,s+e/2,!1),c.arc(0,0,t,s+e/2,s+e,!1),c.closePath(),s+=e,i?c.fill():c.stroke())}}}function p(e){if(r.series.pie.innerRadius>0){e.save();var t=r.series.pie.innerRadius>1?r.series.pie.innerRadius:o*r.series.pie.innerRadius;e.globalCompositeOperation="destination-out",e.beginPath(),e.fillStyle=r.series.pie.stroke.color,e.arc(0,0,t,0,2*Math.PI,!1),e.fill(),e.closePath(),e.restore(),e.save(),e.beginPath(),e.strokeStyle=r.series.pie.stroke.color,e.arc(0,0,t,0,2*Math.PI,!1),e.stroke(),e.closePath(),e.restore()}}function g(e,t){for(var n=!1,i=-1,r=e.length,o=r-1;++i1?h.series.pie.radius:o*h.series.pie.radius,u=0;u1?t.series.pie.tilt=1:t.series.pie.tilt<0&&(t.series.pie.tilt=0))})),e.hooks.bindEvents.push((function(e,t){var n=e.getOptions();n.series.pie.show&&(n.grid.hoverable&&t.unbind("mousemove").mousemove(f),n.grid.clickable&&t.unbind("click").click(v))})),e.hooks.processDatapoints.push((function(e,t,n,i){e.getOptions().series.pie.show&&d(e)})),e.hooks.drawOverlay.push((function(e,t){e.getOptions().series.pie.show&&function(e,t){var n,i=e.getOptions(),r=i.series.pie.radius>1?i.series.pie.radius:o*i.series.pie.radius;t.save(),t.translate(l,a),t.scale(1,i.series.pie.tilt);for(var s=0;s1e-9&&t.moveTo(0,0),t.arc(0,0,r,n.startAngle,n.startAngle+n.angle/2,!1),t.arc(0,0,r,n.startAngle+n.angle/2,n.startAngle+n.angle,!1),t.closePath(),t.fill());p(t),t.restore()}(e,t)})),e.hooks.draw.push((function(e,t){e.getOptions().series.pie.show&&u(e,t)}))},options:i,name:"pie",version:"1.1"})},function(e,t){!function(e){function t(e,t){return t*Math.floor(e/t)}function n(e,t,n,i){if("function"==typeof e.strftime)return e.strftime(t);var r,o=function(e,t){return t=""+(null==t?"0":t),1==(e=""+e).length?t+e:e},l=[],a=!1,s=e.getHours(),c=s<12;null==n&&(n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),null==i&&(i=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]),r=s>12?s-12:0==s?12:s;for(var h=0;h=c);++d);var u=h[d][0],p=h[d][1];if("year"==p){if(null!=l.minTickSize&&"year"==l.minTickSize[1])u=Math.floor(l.minTickSize[0]);else{var g=Math.pow(10,Math.floor(Math.log(e.delta/o.year)/Math.LN10)),f=e.delta/o.year/g;u=f<1.5?1:f<3?2:f<7.5?5:10,u*=g}u<1&&(u=1)}e.tickSize=l.tickSize||[u,p];var v=e.tickSize[0];p=e.tickSize[1];var b=v*o[p];"second"==p?i.setSeconds(t(i.getSeconds(),v)):"minute"==p?i.setMinutes(t(i.getMinutes(),v)):"hour"==p?i.setHours(t(i.getHours(),v)):"month"==p?i.setMonth(t(i.getMonth(),v)):"quarter"==p?i.setMonth(3*t(i.getMonth()/3,v)):"year"==p&&i.setFullYear(t(i.getFullYear(),v)),i.setMilliseconds(0),b>=o.minute&&i.setSeconds(0),b>=o.hour&&i.setMinutes(0),b>=o.day&&i.setHours(0),b>=4*o.day&&i.setDate(1),b>=2*o.month&&i.setMonth(t(i.getMonth(),3)),b>=2*o.quarter&&i.setMonth(t(i.getMonth(),6)),b>=o.year&&i.setMonth(0);var m,y=0,w=Number.NaN;do{if(m=w,w=i.getTime(),n.push(w),"month"==p||"quarter"==p)if(v<1){i.setDate(1);var S=i.getTime();i.setMonth(i.getMonth()+("quarter"==p?3:1));var M=i.getTime();i.setTime(w+y*o.hour+(M-S)*v),y=i.getHours(),i.setHours(0)}else i.setMonth(i.getMonth()+v*("quarter"==p?3:1));else"year"==p?i.setFullYear(i.getFullYear()+v):i.setTime(w+b)}while(w');function s(e,t){var n=t.data[0][t.data[0].length-1],r=2,o='
'+e+"
";return i.panel.legend.percentageDecimals&&(r=i.panel.legend.percentageDecimals),i.panel.legend.values&&i.panel.legend.percentage?o+i.formatValue(n)+"
"+t.percent.toFixed(r)+"%
":i.panel.legend.values?o+i.formatValue(n)+"":i.panel.legend.percentage?o+t.percent.toFixed(r)+"%":o+""}function c(){var e=t.width(),n=i.height-function(e){if(!i.panel.legend.show||"Right side"===i.panel.legendType||"On graph"===i.panel.legendType)return 20;if("Under graph"===i.panel.legendType&&i.panel.legend.percentage||i.panel.legend.values){var t=parseInt(i.panel.breakPoint,10)/100,n=23+20*r.length;return Math.min(n,Math.floor(e*t))}return 0}(i.height),c=Math.min(e,n),h=u()("
"),d={margin:"auto",position:"relative",paddingBottom:"20px",height:c+"px"};h.css(d);var p={legend:{show:!1},series:{pie:{radius:1,innerRadius:0,show:!0,stroke:{color:u()("body").css("background-color"),width:parseFloat(i.panel.strokeWidth).toFixed(1)},label:{show:i.panel.legend.show&&"On graph"===i.panel.legendType,formatter:s},highlight:{opacity:0},combine:{threshold:i.panel.combine.threshold,label:i.panel.combine.label}}},grid:{hoverable:!0,clickable:!1}};"donut"===o.pieType&&(p.series.pie.innerRadius=.5),r=i.data;for(var g=0;g
',r+='
'+l.a.escape(n.series.label)+": "+s,r+=" ("+o+"%)
",r+="
",a.html(r).place_tt(t.pageX+20,t.pageY)}else a.detach()}))}function h(e){i.data&&(r=i.data,0===i.data.length?t.html('
No data points
'):c(),e&&i.renderingCompleted())}i.events.on("render",(function(){"Right side"===o.legendType?(h(!1),setTimeout((function(){h(!0)}),50)):h(!0)}))}var g=n(5),f=n.n(g),v=(n(8),n(6)),b=n.n(v);f.a.module("grafana.directives").directive("piechartLegend",["popoverSrv","$timeout",function(e,t){return{link:function(n,i){var r,o,a,s,c,h=u()('
'),d=!0,p=n.ctrl,g=p.panel;function f(e){return e.parents("[data-series-index]").data("series-index")}function v(e){var t=u()(e.currentTarget);if(t&&t.text()!==g.combine.label){var n=f(t),i=a[n],r=u()(h.children("tbody")).scrollTop();p.toggleSeries(i),void 0!==r&&u()(h.children("tbody")).scrollTop(r)}}function m(e){var t=u()(e.currentTarget).data("stat");if(t!==g.legend.sort&&(g.legend.sortDesc=null),!1===g.legend.sortDesc)return g.legend.sort=null,g.legend.sortDesc=null,void p.render();g.legend.sortDesc=!g.legend.sortDesc,g.legend.sort=t,p.render()}function y(n){if(!u()(n.target).parents(".popover").length){var i=u()(n.currentTarget).find(".fa-minus"),r=f(i),l=o[r];t((function(){e.show({element:i[0],position:"right center",template:'',openOn:"hover",classNames:"drop-popover drop-popover--transparent",model:{autoClose:!0,series:l,toggleAxis:function(){},colorSelected:function(e){p.changeSeriesColor(l,e)}}})}))}}function w(e,t,n,i,r){var o='
',o+='',o+='',o+="",o+=''+l.a.escape(e.label)+"";var a=0;if(p.panel.legend.percentageDecimals&&(a=p.panel.legend.percentageDecimals),i&&r){var s=e.legendData;if(g.legend.values&&(o+='
'+p.formatValue(s)+"
"),n)o+='
'+((s/n*100).toFixed(a)+"%")+"
"}return o+="
"}n.$on("$destroy",(function(){c&&c.destroy()})),p.events.on("render",(function(){if(r=p.series){for(var e in r)r[e].color=p.data[e].color;!function(){if("On graph"===g.legendType||!g.legend.show)return h.empty(),void i.find(".piechart-legend").css("padding-top",0);i.find(".piechart-legend").css("padding-top",6);d&&(i.append(h),h.on("click",".piechart-legend-icon",y),h.on("click",".piechart-legend-alias",v),h.on("click","th",m),d=!1);o=r,a=p.data,h.empty();var e="Right side"===g.legendType&&g.legend.sideWidth?g.legend.sideWidth+"px":"",t="Right side"===g.legendType&&g.legend.sideWidth?g.legend.sideWidth-1+"px":"";i.css("min-width",e),i.css("width",t);var n,f=g.legend.values||g.legend.percentage,S=("Under graph"===g.legendType||"Right side"===g.legendType)&&f;if(h.toggleClass("piechart-legend-table",S),S){var M='';g.legend.values&&(M+=function(e){var t=e;g.legend.header&&(t=g.legend.header);var n=''+l.a.escape(t);if(g.legend.sort===e){var i=g.legend.sortDesc?"fa fa-caret-down":"fa fa-caret-up";n+=' '}return n+""}(p.panel.valueName)),g.legend.percentage&&(M+=function(e){var t='percentage';if(g.legend.sort===e){var n=g.legend.sortDesc?"fa fa-caret-down":"fa fa-caret-up";t+=' '}return t+""}(p.panel.valueName)),M+="",n=u()(M)}var Y=0;if(g.legend.percentage)for(s=0;s0){if(void 0===g.legend.sortDesc||null===g.legend.sortDesc||g.legend.sortDesc)if(Object.keys(p.hiddenSeries).length>0){var R=void 0,x=void 0,D=function(e){R=a.find((function(t){return t.label===e})),(void 0===x||R.legendData>x)&&(x=R.legendData,k.color=R.color)};for(var P in p.hiddenSeries)D(P)}else k.color=o[o.length-T].color;else k.color=o[0].color;X.push(u()(w(k,a.length-T,Y,f,S)))}if(S){var H=u()("");void 0!==n&&H.append(n),H.append(X),h.append(H)}else h.append(X);"Under graph"===g.legendType?c?c.update():c=new b.a(i[0],{scrollYMarginOffset:2,suppressScrollX:!0}):c&&(c.destroy(),c=null)}()}}))}}}]);var m=function(e){function t(t,n,i){var r=e.call(this,t,n)||this;r.$rootScope=i,r.hiddenSeries={};var o={pieType:"pie",legend:{show:!0,values:!0},links:[],datasource:null,interval:null,targets:[{}],cacheTimeout:null,nullPointMode:"connected",legendType:"Under graph",breakPoint:"50%",aliasColors:{},format:"short",valueName:"current",strokeWidth:1,fontSize:"80%",combine:{threshold:0,label:"Others"}};return l.a.defaults(r.panel,o),l.a.defaults(r.panel.legend,o.legend),r.events.on("render",r.onRender.bind(r)),r.events.on("data-received",r.onDataReceived.bind(r)),r.events.on("data-error",r.onDataError.bind(r)),r.events.on("data-snapshot-load",r.onDataReceived.bind(r)),r.events.on("init-edit-mode",r.onInitEditMode.bind(r)),r.setLegendWidthForLegacyBrowser(),r}return t.$inject=["$scope","$injector","$rootScope"],function(e,t){function n(){this.constructor=e}i(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}(t,e),t.prototype.onInitEditMode=function(){this.addEditorTab("Options","public/plugins/grafana-piechart-panel/editor.html",2),this.unitFormats=s.a.getUnitFormats()},t.prototype.setUnitFormat=function(e){this.panel.format=e.value,this.render()},t.prototype.onDataError=function(){this.series=[],this.render()},t.prototype.changeSeriesColor=function(e,t){e.color=t,this.panel.aliasColors[e.alias]=e.color,this.render()},t.prototype.onRender=function(){this.data=this.parseSeries(this.series)},t.prototype.parseSeries=function(e){var t=this;return l.a.map(this.series,(function(e,n){return{label:e.alias,data:e.stats[t.panel.valueName],color:t.panel.aliasColors[e.alias]||t.$rootScope.colors[n],legendData:e.stats[t.panel.valueName]}}))},t.prototype.onDataReceived=function(e){this.series=e.map(this.seriesHandler.bind(this)),this.data=this.parseSeries(this.series),this.render(this.data)},t.prototype.seriesHandler=function(e){var t=new h.a({datapoints:e.datapoints,alias:e.target});return t.flotpairs=t.getFlotPairs(this.panel.nullPointMode),t},t.prototype.getDecimalsForValue=function(e){if(l.a.isNumber(this.panel.decimals))return{decimals:this.panel.decimals,scaledDecimals:null};var t,n=e/2,i=-Math.floor(Math.log(n)/Math.LN10),r=Math.pow(10,-i),o=n/r;o<1.5?t=1:o<3?(t=2,o>2.25&&(t=2.5,++i)):t=o<7.5?5:10,t*=r,Math.floor(e)===e&&(i=0);var a={decimals:0,scaledDecimals:0};return a.decimals=Math.max(0,i),a.scaledDecimals=a.decimals-Math.floor(Math.log(t)/Math.LN10)+2,a},t.prototype.formatValue=function(e){var t=this.getDecimalsForValue(e),n=s.a.valueFormats[this.panel.format];return n?n(e,t.decimals,t.scaledDecimals):e},t.prototype.link=function(e,t,n,i){p(0,t,0,i)},t.prototype.toggleSeries=function(e){this.hiddenSeries[e.label]?delete this.hiddenSeries[e.label]:this.hiddenSeries[e.label]=!0,this.render()},t.prototype.onLegendTypeChanged=function(){this.setLegendWidthForLegacyBrowser(),this.render()},t.prototype.setLegendWidthForLegacyBrowser=function(){!!window.MSInputMethodContext&&!!document.documentMode&&"Right side"===this.panel.legendType&&!this.panel.legend.sideWidth&&(this.panel.legend.sideWidth=150)},t.templateUrl="module.html",t}(r.MetricsPanelCtrl);n.d(t,"PanelCtrl",(function(){return m})),Object(r.loadPluginCss)({dark:"plugins/grafana-piechart-panel/styles/dark.css",light:"plugins/grafana-piechart-panel/styles/light.css"})}])})); +//# sourceMappingURL=module.js.map \ No newline at end of file diff --git a/dist/module.js.LICENSE.txt b/dist/module.js.LICENSE.txt new file mode 100644 index 0000000..f3f36ee --- /dev/null +++ b/dist/module.js.LICENSE.txt @@ -0,0 +1,20 @@ +/*! + * perfect-scrollbar v1.2.0 + * (c) 2017 Hyunje Jun + * @license MIT + */ + +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ diff --git a/dist/module.js.map b/dist/module.js.map new file mode 100644 index 0000000..3b17bd6 --- /dev/null +++ b/dist/module.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///external \"jquery\"","webpack:///external \"lodash\"","webpack:///external \"app/plugins/sdk\"","webpack:///external \"app/core/utils/kbn\"","webpack:///external \"app/core/time_series\"","webpack:///external \"angular\"","webpack:///./lib/perfect-scrollbar.min.js","webpack:///./lib/jquery.flot.pie.js","webpack:///./lib/jquery.flot.time.js","webpack:///../node_modules/tslib/tslib.es6.js","webpack:///./rendering.ts","webpack:///./legend.ts","webpack:///./piechart_ctrl.ts","webpack:///./module.ts"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","__WEBPACK_EXTERNAL_MODULE__0__","__WEBPACK_EXTERNAL_MODULE__1__","__WEBPACK_EXTERNAL_MODULE__2__","__WEBPACK_EXTERNAL_MODULE__3__","__WEBPACK_EXTERNAL_MODULE__4__","__WEBPACK_EXTERNAL_MODULE__5__","e","define","this","getComputedStyle","style","document","createElement","className","v","Error","remove","parentNode","removeChild","Array","filter","children","element","classList","state","scrolling","contains","clearTimeout","w","add","setTimeout","isAlive","settings","scrollingThreshold","a","window","CustomEvent","createEvent","initCustomEvent","u","parseInt","f","minScrollbarLength","Math","max","maxScrollbarLength","min","b","width","railXWidth","isRtl","left","negativeScrollAdjustment","scrollLeft","containerWidth","contentWidth","isScrollbarXUsingBottom","bottom","scrollbarXBottom","scrollTop","top","scrollbarXTop","scrollbarXRail","height","railYHeight","isScrollbarYUsingRight","right","scrollbarYRight","scrollbarYOuterWidth","scrollbarYLeft","scrollbarYRail","scrollbarX","scrollbarXLeft","scrollbarXWidth","railBorderXWidth","scrollbarY","scrollbarYTop","scrollbarYHeight","railBorderYWidth","g","R","stopPropagation","preventDefault","event","unbind","ownerDocument","h","once","Element","matches","webkitMatchesSelector","msMatchesSelector","main","thumb","rail","consuming","focus","active","x","y","Y","handlers","X","isEmpty","configurable","push","addEventListener","removeEventListener","unbindAll","keys","every","length","defineProperties","W","eventElements","eventElement","splice","indexOf","forEach","reach","dispatchEvent","L","documentElement","DocumentTouch","navigator","msMaxTouchPoints","clientWidth","containerHeight","clientHeight","scrollWidth","contentHeight","scrollHeight","appendChild","suppressScrollX","scrollXMarginOffset","scrollbarXActive","railXMarginWidth","railXRatio","suppressScrollY","scrollYMarginOffset","scrollbarYActive","railYMarginHeight","railYRatio","T","pageY","pageYOffset","getBoundingClientRect","pageX","pageXOffset","keyboard","isDefaultPrevented","defaultPrevented","activeElement","tagName","contentDocument","shadowRoot","which","metaKey","altKey","shiftKey","wheelPropagation","wheel","querySelector","overflow","overflowX","overflowY","join","match","deltaX","deltaY","wheelDeltaX","wheelDeltaY","deltaMode","wheelDelta","target","useBothWheelAxes","wheelSpeed","ctrlKey","onwheel","onmousewheel","touch","abs","stop","swipePropagation","prevent","scrollY","targetTouches","pointerType","buttons","MSPOINTER_TYPE_MOUSE","Date","getTime","clearInterval","swipeEasing","setInterval","isInitialized","PointerEvent","MSPointerEvent","H","nodeName","direction","isNegativeScroll","setAttribute","isNaN","borderLeftWidth","borderRightWidth","display","marginLeft","marginRight","paddingLeft","paddingRight","borderTopWidth","borderBottomWidth","marginTop","marginBottom","lastScrollTop","lastScrollLeft","onScroll","update","destroy","removePsClasses","split","$","options","jQuery","series","pie","show","radius","innerRadius","startAngle","tilt","shadow","alpha","offset","stroke","color","label","formatter","slice","round","percent","background","opacity","threshold","combine","highlight","plot","plugins","init","canvas","maxRadius","centerLeft","centerTop","processed","ctx","highlights","processDatapoints","datapoints","getCanvas","parent","getOptions","setData","data","total","combined","numCombined","newdata","isArray","parseFloat","isFinite","extend","angle","PI","getData","draw","newCtx","canvasWidth","getPlaceholder","canvasHeight","legendWidth","legend","position","slices","attempts","clear","drawShadow","drawPie","prepend","setSeries","insertLegend","clearRect","shadowLeft","shadowTop","save","translate","globalAlpha","fillStyle","scale","beginPath","arc","fill","restore","currentAngle","drawSlice","lineWidth","drawDonutHole","drawLabel","index","text","lf","labelFormatter","plf","halfAngle","cos","sin","html","append","labelTop","labelLeft","css","pos","insertBefore","drawLabels","strokeStyle","lineJoin","moveTo","closePath","layer","globalCompositeOperation","isPointInPoly","poly","pt","j","onMouseMove","triggerClickHoverEvent","onClick","eventname","item","mouseX","mouseY","isPointInPath","datapoint","dataIndex","seriesIndex","findNearbySlice","grid","autoHighlight","auto","unhighlight","indexOfHighlight","triggerRedrawOverlay","trigger","hooks","processOptions","bindEvents","eventHolder","hoverable","mousemove","clickable","click","drawOverlay","octx","version","floorInBase","base","floor","formatDate","fmt","monthNames","dayNames","strftime","hours12","leftPad","pad","escape","hours","getHours","isAM","charAt","getDay","getMonth","getDate","getMinutes","getSeconds","getFullYear","makeUtcWrapper","addProxyMethod","sourceObj","sourceMethod","targetObj","targetMethod","apply","arguments","utc","date","undefined","props","dateGenerator","ts","opts","timezone","timezoneJS","setTimezone","setTime","timeUnitSize","baseSpec","specMonths","concat","specQuarters","each","getAxes","axisName","axis","tickGenerator","ticks","minSize","spec","tickSize","minTickSize","delta","size","unit","magn","pow","log","year","LN10","norm","step","setSeconds","setMinutes","setHours","setMonth","setFullYear","setMilliseconds","minute","hour","day","setDate","month","quarter","prev","carry","Number","NaN","start","end","tickFormatter","timeformat","useQuarters","span","suffix","twelveHourClock","hourCode","xaxis","extendStatics","setPrototypeOf","__proto__","scope","elem","attrs","ctrl","panel","find","$tooltip","sliceData","decimal","fontSize","percentageDecimals","values","percentage","formatValue","toFixed","addPieChart","panelHeight","legendType","breakPoint","getLegendHeight","plotCanvas","plotCss","margin","paddingBottom","strokeWidth","pieType","hiddenSeries","sort","valueName","sortDesc","legendData","body","formatted","place_tt","detach","render","incrementRenderCounter","renderingCompleted","events","on","directive","popoverSrv","$timeout","link","seriesList","dataList","legendScrollbar","$container","firstRender","getSeriesIndexForElement","el","parents","toggleSeries","currentTarget","seriesInfo","scrollPosition","sortLegend","stat","openColorSelector","template","openOn","classNames","model","autoClose","toggleAxis","colorSelected","changeSeriesColor","generateLegendItem","showValues","tableLayout","$on","empty","sideWidth","ieWidth","legendHeader","toggleClass","header","statName","cssClass","getLegendHeaderHtml","getLegendPercentageHtml","stats","combineNum","combineVal","seriesElements","seriesData","hideEmpty","allIsNull","_el","_max","_key","tbodyElem","$scope","$injector","$rootScope","panelDefaults","links","datasource","interval","targets","cacheTimeout","nullPointMode","aliasColors","format","defaults","onRender","onDataReceived","onDataError","onInitEditMode","setLegendWidthForLegacyBrowser","__","constructor","addEditorTab","unitFormats","getUnitFormats","setUnitFormat","subItem","alias","parseSeries","map","serie","colors","seriesHandler","flotpairs","getFlotPairs","getDecimalsForValue","isNumber","decimals","scaledDecimals","dec","result","decimalInfo","formatFunc","valueFormats","onLegendTypeChanged","MSInputMethodContext","documentMode","templateUrl","dark","light"],"mappings":"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","file":"module.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 11);\n","module.exports = __WEBPACK_EXTERNAL_MODULE__0__;","module.exports = __WEBPACK_EXTERNAL_MODULE__1__;","module.exports = __WEBPACK_EXTERNAL_MODULE__2__;","module.exports = __WEBPACK_EXTERNAL_MODULE__3__;","module.exports = __WEBPACK_EXTERNAL_MODULE__4__;","module.exports = __WEBPACK_EXTERNAL_MODULE__5__;","/*!\n * perfect-scrollbar v1.2.0\n * (c) 2017 Hyunje Jun\n * @license MIT\n */\n!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):t.PerfectScrollbar=e()}(this,function(){\"use strict\";function t(t){return getComputedStyle(t)}function e(t,e){for(var i in e){var n=e[i];\"number\"==typeof n&&(n+=\"px\"),t.style[i]=n}return t}function i(t){var e=document.createElement(\"div\");return e.className=t,e}function n(t,e){if(!v)throw new Error(\"No element matching method supported\");return v.call(t,e)}function r(t){t.remove?t.remove():t.parentNode&&t.parentNode.removeChild(t)}function l(t,e){return Array.prototype.filter.call(t.children,function(t){return n(t,e)})}function o(t,e){var i=t.element.classList,n=m.state.scrolling(e);i.contains(n)?clearTimeout(w[e]):i.add(n)}function s(t,e){w[e]=setTimeout(function(){return t.isAlive&&t.element.classList.remove(m.state.scrolling(e))},t.settings.scrollingThreshold)}function a(t,e){o(t,e),s(t,e)}function c(t){if(\"function\"==typeof window.CustomEvent)return new CustomEvent(t);var e=document.createEvent(\"CustomEvent\");return e.initCustomEvent(t,!1,!1,void 0),e}function h(t,e,i,n,r){var l=i[0],o=i[1],s=i[2],h=i[3],u=i[4],d=i[5];void 0===n&&(n=!0),void 0===r&&(r=!1);var p=t.element;t.reach[h]=null,p[s]<1&&(t.reach[h]=\"start\"),p[s]>t[l]-t[o]-1&&(t.reach[h]=\"end\"),e&&(p.dispatchEvent(c(\"ps-scroll-\"+h)),e<0?p.dispatchEvent(c(\"ps-scroll-\"+u)):e>0&&p.dispatchEvent(c(\"ps-scroll-\"+d)),n&&a(t,h)),t.reach[h]&&(e||r)&&p.dispatchEvent(c(\"ps-\"+h+\"-reach-\"+t.reach[h]))}function u(t){return parseInt(t,10)||0}function d(t){return n(t,\"input,[contenteditable]\")||n(t,\"select,[contenteditable]\")||n(t,\"textarea,[contenteditable]\")||n(t,\"button,[contenteditable]\")}function p(e){var i=t(e);return u(i.width)+u(i.paddingLeft)+u(i.paddingRight)+u(i.borderLeftWidth)+u(i.borderRightWidth)}function f(t,e){return t.settings.minScrollbarLength&&(e=Math.max(e,t.settings.minScrollbarLength)),t.settings.maxScrollbarLength&&(e=Math.min(e,t.settings.maxScrollbarLength)),e}function b(t,i){var n={width:i.railXWidth};i.isRtl?n.left=i.negativeScrollAdjustment+t.scrollLeft+i.containerWidth-i.contentWidth:n.left=t.scrollLeft,i.isScrollbarXUsingBottom?n.bottom=i.scrollbarXBottom-t.scrollTop:n.top=i.scrollbarXTop+t.scrollTop,e(i.scrollbarXRail,n);var r={top:t.scrollTop,height:i.railYHeight};i.isScrollbarYUsingRight?i.isRtl?r.right=i.contentWidth-(i.negativeScrollAdjustment+t.scrollLeft)-i.scrollbarYRight-i.scrollbarYOuterWidth:r.right=i.scrollbarYRight-t.scrollLeft:i.isRtl?r.left=i.negativeScrollAdjustment+t.scrollLeft+2*i.containerWidth-i.contentWidth-i.scrollbarYLeft-i.scrollbarYOuterWidth:r.left=i.scrollbarYLeft+t.scrollLeft,e(i.scrollbarYRail,r),e(i.scrollbarX,{left:i.scrollbarXLeft,width:i.scrollbarXWidth-i.railBorderXWidth}),e(i.scrollbarY,{top:i.scrollbarYTop,height:i.scrollbarYHeight-i.railBorderYWidth})}function g(t,e){function i(e){f[d]=b+v*(e[a]-g),o(t,p),R(t),e.stopPropagation(),e.preventDefault()}function n(){s(t,p),t.event.unbind(t.ownerDocument,\"mousemove\",i)}var r=e[0],l=e[1],a=e[2],c=e[3],h=e[4],u=e[5],d=e[6],p=e[7],f=t.element,b=null,g=null,v=null;t.event.bind(t[h],\"mousedown\",function(e){b=f[d],g=e[a],v=(t[l]-t[r])/(t[c]-t[u]),t.event.bind(t.ownerDocument,\"mousemove\",i),t.event.once(t.ownerDocument,\"mouseup\",n),e.stopPropagation(),e.preventDefault()})}var v=Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.msMatchesSelector,m={main:\"ps\",element:{thumb:function(t){return\"ps__thumb-\"+t},rail:function(t){return\"ps__rail-\"+t},consuming:\"ps__child--consume\"},state:{focus:\"ps--focus\",active:function(t){return\"ps--active-\"+t},scrolling:function(t){return\"ps--scrolling-\"+t}}},w={x:null,y:null},Y=function(t){this.element=t,this.handlers={}},X={isEmpty:{configurable:!0}};Y.prototype.bind=function(t,e){void 0===this.handlers[t]&&(this.handlers[t]=[]),this.handlers[t].push(e),this.element.addEventListener(t,e,!1)},Y.prototype.unbind=function(t,e){var i=this;this.handlers[t]=this.handlers[t].filter(function(n){return!(!e||n===e)||(i.element.removeEventListener(t,n,!1),!1)})},Y.prototype.unbindAll=function(){var t=this;for(var e in t.handlers)t.unbind(e)},X.isEmpty.get=function(){var t=this;return Object.keys(this.handlers).every(function(e){return 0===t.handlers[e].length})},Object.defineProperties(Y.prototype,X);var W=function(){this.eventElements=[]};W.prototype.eventElement=function(t){var e=this.eventElements.filter(function(e){return e.element===t})[0];return e||(e=new Y(t),this.eventElements.push(e)),e},W.prototype.bind=function(t,e,i){this.eventElement(t).bind(e,i)},W.prototype.unbind=function(t,e,i){var n=this.eventElement(t);n.unbind(e,i),n.isEmpty&&this.eventElements.splice(this.eventElements.indexOf(n),1)},W.prototype.unbindAll=function(){this.eventElements.forEach(function(t){return t.unbindAll()}),this.eventElements=[]},W.prototype.once=function(t,e,i){var n=this.eventElement(t),r=function(t){n.unbind(e,r),i(t)};n.bind(e,r)};var y=function(t,e,i,n,r){void 0===n&&(n=!0),void 0===r&&(r=!1);var l;if(\"top\"===e)l=[\"contentHeight\",\"containerHeight\",\"scrollTop\",\"y\",\"up\",\"down\"];else{if(\"left\"!==e)throw new Error(\"A proper axis should be provided\");l=[\"contentWidth\",\"containerWidth\",\"scrollLeft\",\"x\",\"left\",\"right\"]}h(t,i,l,n,r)},L={isWebKit:document&&\"WebkitAppearance\"in document.documentElement.style,supportsTouch:window&&(\"ontouchstart\"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),supportsIePointer:navigator&&navigator.msMaxTouchPoints},R=function(t){var e=t.element;t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight,e.contains(t.scrollbarXRail)||(l(e,m.element.rail(\"x\")).forEach(function(t){return r(t)}),e.appendChild(t.scrollbarXRail)),e.contains(t.scrollbarYRail)||(l(e,m.element.rail(\"y\")).forEach(function(t){return r(t)}),e.appendChild(t.scrollbarYRail)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),b(e,t),t.scrollbarXActive?e.classList.add(m.state.active(\"x\")):(e.classList.remove(m.state.active(\"x\")),t.scrollbarXWidth=0,t.scrollbarXLeft=0,e.scrollLeft=0),t.scrollbarYActive?e.classList.add(m.state.active(\"y\")):(e.classList.remove(m.state.active(\"y\")),t.scrollbarYHeight=0,t.scrollbarYTop=0,e.scrollTop=0)},T={\"click-rail\":function(t){t.event.bind(t.scrollbarY,\"mousedown\",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarYRail,\"mousedown\",function(e){var i=e.pageY-window.pageYOffset-t.scrollbarYRail.getBoundingClientRect().top>t.scrollbarYTop?1:-1;t.element.scrollTop+=i*t.containerHeight,R(t),e.stopPropagation()}),t.event.bind(t.scrollbarX,\"mousedown\",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarXRail,\"mousedown\",function(e){var i=e.pageX-window.pageXOffset-t.scrollbarXRail.getBoundingClientRect().left>t.scrollbarXLeft?1:-1;t.element.scrollLeft+=i*t.containerWidth,R(t),e.stopPropagation()})},\"drag-thumb\":function(t){g(t,[\"containerWidth\",\"contentWidth\",\"pageX\",\"railXWidth\",\"scrollbarX\",\"scrollbarXWidth\",\"scrollLeft\",\"x\"]),g(t,[\"containerHeight\",\"contentHeight\",\"pageY\",\"railYHeight\",\"scrollbarY\",\"scrollbarYHeight\",\"scrollTop\",\"y\"])},keyboard:function(t){function e(e,n){var r=i.scrollTop;if(0===e){if(!t.scrollbarYActive)return!1;if(0===r&&n>0||r>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var l=i.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===l&&e<0||l>=t.contentWidth-t.containerWidth&&e>0)return!t.settings.wheelPropagation}return!0}var i=t.element,r=function(){return n(i,\":hover\")},l=function(){return n(t.scrollbarX,\":focus\")||n(t.scrollbarY,\":focus\")};t.event.bind(t.ownerDocument,\"keydown\",function(n){if(!(n.isDefaultPrevented&&n.isDefaultPrevented()||n.defaultPrevented)&&(r()||l())){var o=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(o){if(\"IFRAME\"===o.tagName)o=o.contentDocument.activeElement;else for(;o.shadowRoot;)o=o.shadowRoot.activeElement;if(d(o))return}var s=0,a=0;switch(n.which){case 37:s=n.metaKey?-t.contentWidth:n.altKey?-t.containerWidth:-30;break;case 38:a=n.metaKey?t.contentHeight:n.altKey?t.containerHeight:30;break;case 39:s=n.metaKey?t.contentWidth:n.altKey?t.containerWidth:30;break;case 40:a=n.metaKey?-t.contentHeight:n.altKey?-t.containerHeight:-30;break;case 32:a=n.shiftKey?t.containerHeight:-t.containerHeight;break;case 33:a=t.containerHeight;break;case 34:a=-t.containerHeight;break;case 36:a=t.contentHeight;break;case 35:a=-t.contentHeight;break;default:return}t.settings.suppressScrollX&&0!==s||t.settings.suppressScrollY&&0!==a||(i.scrollTop-=a,i.scrollLeft+=s,R(t),e(s,a)&&n.preventDefault())}})},wheel:function(e){function i(t,i){var n=o.scrollTop;if(0===t){if(!e.scrollbarYActive)return!1;if(0===n&&i>0||n>=e.contentHeight-e.containerHeight&&i<0)return!e.settings.wheelPropagation}var r=o.scrollLeft;if(0===i){if(!e.scrollbarXActive)return!1;if(0===r&&t<0||r>=e.contentWidth-e.containerWidth&&t>0)return!e.settings.wheelPropagation}return!0}function n(t){var e=t.deltaX,i=-1*t.deltaY;return void 0!==e&&void 0!==i||(e=-1*t.wheelDeltaX/6,i=t.wheelDeltaY/6),t.deltaMode&&1===t.deltaMode&&(e*=10,i*=10),e!==e&&i!==i&&(e=0,i=t.wheelDelta),t.shiftKey?[-i,-e]:[e,i]}function r(e,i,n){if(!L.isWebKit&&o.querySelector(\"select:focus\"))return!0;if(!o.contains(e))return!1;for(var r=e;r&&r!==o;){if(r.classList.contains(m.element.consuming))return!0;var l=t(r);if([l.overflow,l.overflowX,l.overflowY].join(\"\").match(/(scroll|auto)/)){var s=r.scrollHeight-r.clientHeight;if(s>0&&!(0===r.scrollTop&&n>0||r.scrollTop===s&&n<0))return!0;var a=r.scrollLeft-r.clientWidth;if(a>0&&!(0===r.scrollLeft&&i<0||r.scrollLeft===a&&i>0))return!0}r=r.parentNode}return!1}function l(t){var l=n(t),s=l[0],a=l[1];if(!r(t.target,s,a)){var c=!1;e.settings.useBothWheelAxes?e.scrollbarYActive&&!e.scrollbarXActive?(a?o.scrollTop-=a*e.settings.wheelSpeed:o.scrollTop+=s*e.settings.wheelSpeed,c=!0):e.scrollbarXActive&&!e.scrollbarYActive&&(s?o.scrollLeft+=s*e.settings.wheelSpeed:o.scrollLeft-=a*e.settings.wheelSpeed,c=!0):(o.scrollTop-=a*e.settings.wheelSpeed,o.scrollLeft+=s*e.settings.wheelSpeed),R(e),(c=c||i(s,a))&&!t.ctrlKey&&(t.stopPropagation(),t.preventDefault())}}var o=e.element;void 0!==window.onwheel?e.event.bind(o,\"wheel\",l):void 0!==window.onmousewheel&&e.event.bind(o,\"mousewheel\",l)},touch:function(t){function e(e,i){var n=h.scrollTop,r=h.scrollLeft,l=Math.abs(e),o=Math.abs(i);if(o>l){if(i<0&&n===t.contentHeight-t.containerHeight||i>0&&0===n)return{stop:!t.settings.swipePropagation,prevent:0===window.scrollY}}else if(l>o&&(e<0&&r===t.contentWidth-t.containerWidth||e>0&&0===r))return{stop:!t.settings.swipePropagation,prevent:!0};return{stop:!0,prevent:!0}}function i(e,i){h.scrollTop-=i,h.scrollLeft-=e,R(t)}function n(){b=!0}function r(){b=!1}function l(t){return t.targetTouches?t.targetTouches[0]:t}function o(t){return!(t.pointerType&&\"pen\"===t.pointerType&&0===t.buttons||(!t.targetTouches||1!==t.targetTouches.length)&&(!t.pointerType||\"mouse\"===t.pointerType||t.pointerType===t.MSPOINTER_TYPE_MOUSE))}function s(t){if(o(t)){g=!0;var e=l(t);u.pageX=e.pageX,u.pageY=e.pageY,d=(new Date).getTime(),null!==f&&clearInterval(f),t.stopPropagation()}}function a(n){if(!g&&t.settings.swipePropagation&&s(n),!b&&g&&o(n)){var r=l(n),a={pageX:r.pageX,pageY:r.pageY},c=a.pageX-u.pageX,h=a.pageY-u.pageY;i(c,h),u=a;var f=(new Date).getTime(),v=f-d;v>0&&(p.x=c/v,p.y=h/v,d=f);var m=e(c,h),w=m.stop,Y=m.prevent;w&&n.stopPropagation(),Y&&n.preventDefault()}}function c(){!b&&g&&(g=!1,t.settings.swipeEasing&&(clearInterval(f),f=setInterval(function(){t.isInitialized?clearInterval(f):p.x||p.y?Math.abs(p.x)<.01&&Math.abs(p.y)<.01?clearInterval(f):(i(30*p.x,30*p.y),p.x*=.8,p.y*=.8):clearInterval(f)},10)))}if(L.supportsTouch||L.supportsIePointer){var h=t.element,u={},d=0,p={},f=null,b=!1,g=!1;L.supportsTouch?(t.event.bind(window,\"touchstart\",n),t.event.bind(window,\"touchend\",r),t.event.bind(h,\"touchstart\",s),t.event.bind(h,\"touchmove\",a),t.event.bind(h,\"touchend\",c)):L.supportsIePointer&&(window.PointerEvent?(t.event.bind(window,\"pointerdown\",n),t.event.bind(window,\"pointerup\",r),t.event.bind(h,\"pointerdown\",s),t.event.bind(h,\"pointermove\",a),t.event.bind(h,\"pointerup\",c)):window.MSPointerEvent&&(t.event.bind(window,\"MSPointerDown\",n),t.event.bind(window,\"MSPointerUp\",r),t.event.bind(h,\"MSPointerDown\",s),t.event.bind(h,\"MSPointerMove\",a),t.event.bind(h,\"MSPointerUp\",c)))}}},H=function(n,r){var l=this;if(void 0===r&&(r={}),\"string\"==typeof n&&(n=document.querySelector(n)),!n||!n.nodeName)throw new Error(\"no element is specified to initialize PerfectScrollbar\");this.element=n,n.classList.add(m.main),this.settings={handlers:[\"click-rail\",\"drag-thumb\",\"keyboard\",\"wheel\",\"touch\"],maxScrollbarLength:null,minScrollbarLength:null,scrollingThreshold:1e3,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,swipeEasing:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1};for(var o in r)l.settings[o]=r[o];this.containerWidth=null,this.containerHeight=null,this.contentWidth=null,this.contentHeight=null;var s=function(){return n.classList.add(m.state.focus)},a=function(){return n.classList.remove(m.state.focus)};this.isRtl=\"rtl\"===t(n).direction,this.isNegativeScroll=function(){var t=n.scrollLeft,e=null;return n.scrollLeft=-1,e=n.scrollLeft<0,n.scrollLeft=t,e}(),this.negativeScrollAdjustment=this.isNegativeScroll?n.scrollWidth-n.clientWidth:0,this.event=new W,this.ownerDocument=n.ownerDocument||document,this.scrollbarXRail=i(m.element.rail(\"x\")),n.appendChild(this.scrollbarXRail),this.scrollbarX=i(m.element.thumb(\"x\")),this.scrollbarXRail.appendChild(this.scrollbarX),this.scrollbarX.setAttribute(\"tabindex\",0),this.event.bind(this.scrollbarX,\"focus\",s),this.event.bind(this.scrollbarX,\"blur\",a),this.scrollbarXActive=null,this.scrollbarXWidth=null,this.scrollbarXLeft=null;var c=t(this.scrollbarXRail);this.scrollbarXBottom=parseInt(c.bottom,10),isNaN(this.scrollbarXBottom)?(this.isScrollbarXUsingBottom=!1,this.scrollbarXTop=u(c.top)):this.isScrollbarXUsingBottom=!0,this.railBorderXWidth=u(c.borderLeftWidth)+u(c.borderRightWidth),e(this.scrollbarXRail,{display:\"block\"}),this.railXMarginWidth=u(c.marginLeft)+u(c.marginRight),e(this.scrollbarXRail,{display:\"\"}),this.railXWidth=null,this.railXRatio=null,this.scrollbarYRail=i(m.element.rail(\"y\")),n.appendChild(this.scrollbarYRail),this.scrollbarY=i(m.element.thumb(\"y\")),this.scrollbarYRail.appendChild(this.scrollbarY),this.scrollbarY.setAttribute(\"tabindex\",0),this.event.bind(this.scrollbarY,\"focus\",s),this.event.bind(this.scrollbarY,\"blur\",a),this.scrollbarYActive=null,this.scrollbarYHeight=null,this.scrollbarYTop=null;var h=t(this.scrollbarYRail);this.scrollbarYRight=parseInt(h.right,10),isNaN(this.scrollbarYRight)?(this.isScrollbarYUsingRight=!1,this.scrollbarYLeft=u(h.left)):this.isScrollbarYUsingRight=!0,this.scrollbarYOuterWidth=this.isRtl?p(this.scrollbarY):null,this.railBorderYWidth=u(h.borderTopWidth)+u(h.borderBottomWidth),e(this.scrollbarYRail,{display:\"block\"}),this.railYMarginHeight=u(h.marginTop)+u(h.marginBottom),e(this.scrollbarYRail,{display:\"\"}),this.railYHeight=null,this.railYRatio=null,this.reach={x:n.scrollLeft<=0?\"start\":n.scrollLeft>=this.contentWidth-this.containerWidth?\"end\":null,y:n.scrollTop<=0?\"start\":n.scrollTop>=this.contentHeight-this.containerHeight?\"end\":null},this.isAlive=!0,this.settings.handlers.forEach(function(t){return T[t](l)}),this.lastScrollTop=n.scrollTop,this.lastScrollLeft=n.scrollLeft,this.event.bind(this.element,\"scroll\",function(t){return l.onScroll(t)}),R(this)};return H.prototype.update=function(){this.isAlive&&(this.negativeScrollAdjustment=this.isNegativeScroll?this.element.scrollWidth-this.element.clientWidth:0,e(this.scrollbarXRail,{display:\"block\"}),e(this.scrollbarYRail,{display:\"block\"}),this.railXMarginWidth=u(t(this.scrollbarXRail).marginLeft)+u(t(this.scrollbarXRail).marginRight),this.railYMarginHeight=u(t(this.scrollbarYRail).marginTop)+u(t(this.scrollbarYRail).marginBottom),e(this.scrollbarXRail,{display:\"none\"}),e(this.scrollbarYRail,{display:\"none\"}),R(this),y(this,\"top\",0,!1,!0),y(this,\"left\",0,!1,!0),e(this.scrollbarXRail,{display:\"\"}),e(this.scrollbarYRail,{display:\"\"}))},H.prototype.onScroll=function(t){this.isAlive&&(R(this),y(this,\"top\",this.element.scrollTop-this.lastScrollTop),y(this,\"left\",this.element.scrollLeft-this.lastScrollLeft),this.lastScrollTop=this.element.scrollTop,this.lastScrollLeft=this.element.scrollLeft)},H.prototype.destroy=function(){this.isAlive&&(this.event.unbindAll(),r(this.scrollbarX),r(this.scrollbarY),r(this.scrollbarXRail),r(this.scrollbarYRail),this.removePsClasses(),this.element=null,this.scrollbarX=null,this.scrollbarY=null,this.scrollbarXRail=null,this.scrollbarYRail=null,this.isAlive=!1)},H.prototype.removePsClasses=function(){this.element.className=this.element.className.split(\" \").filter(function(t){return!t.match(/^ps([-_].+|)$/)}).join(\" \")},H});","/* Flot plugin for rendering pie charts.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes that each series has a single data value, and that each\nvalue is a positive integer or zero. Negative numbers don't make sense for a\npie chart, and have unpredictable results. The values do NOT need to be\npassed in as percentages; the plugin will calculate the total and per-slice\npercentages internally.\n\n* Created by Brian Medendorp\n\n* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpie: {\n\t\t\tshow: true/false\n\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'\n\t\t\tinnerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect\n\t\t\tstartAngle: 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\n\t\t\ttilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)\n\t\t\toffset: {\n\t\t\t\ttop: integer value to move the pie up or down\n\t\t\t\tleft: integer value to move the pie left or right, or 'auto'\n\t\t\t},\n\t\t\tstroke: {\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')\n\t\t\t\twidth: integer pixel width of the stroke\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\tshow: true/false, or 'auto'\n\t\t\t\tformatter: a user-defined function that modifies the text/style of the label text\n\t\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length\n\t\t\t\tbackground: {\n\t\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')\n\t\t\t\t\topacity: 0-1\n\t\t\t\t},\n\t\t\t\tthreshold: 0-1 for the percentage value at which to hide labels (if they're too small)\n\t\t\t},\n\t\t\tcombine: {\n\t\t\t\tthreshold: 0-1 for the percentage value at which to combine slices (if they're too small)\n\t\t\t\tcolor: 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\n\t\t\t\tlabel: any text value of what the combined slice should be labeled\n\t\t\t}\n\t\t\thighlight: {\n\t\t\t\topacity: 0-1\n\t\t\t}\n\t\t}\n\t}\n\nMore detail and specific examples can be found in the included HTML file.\n\n*/\n\n(function($) {\n\n\t// Maximum redraw attempts when fitting labels within the plot\n\n\tvar REDRAW_ATTEMPTS = 10;\n\n\t// Factor by which to shrink the pie when fitting labels within the plot\n\n\tvar REDRAW_SHRINK = 0.95;\n\n\tfunction init(plot) {\n\n\t\tvar canvas = null,\n\t\t\ttarget = null,\n\t\t\toptions = null,\n\t\t\tmaxRadius = null,\n\t\t\tcenterLeft = null,\n\t\t\tcenterTop = null,\n\t\t\tprocessed = false,\n\t\t\tctx = null;\n\n\t\t// interactive variables\n\n\t\tvar highlights = [];\n\n\t\t// add hook to determine if pie plugin in enabled, and then perform necessary operations\n\n\t\tplot.hooks.processOptions.push(function(plot, options) {\n\t\t\tif (options.series.pie.show) {\n\n\t\t\t\toptions.grid.show = false;\n\n\t\t\t\t// set labels.show\n\n\t\t\t\tif (options.series.pie.label.show == \"auto\") {\n\t\t\t\t\tif (options.legend.show) {\n\t\t\t\t\t\toptions.series.pie.label.show = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.label.show = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// set radius\n\n\t\t\t\tif (options.series.pie.radius == \"auto\") {\n\t\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\t\toptions.series.pie.radius = 3/4;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.radius = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// ensure sane tilt\n\n\t\t\t\tif (options.series.pie.tilt > 1) {\n\t\t\t\t\toptions.series.pie.tilt = 1;\n\t\t\t\t} else if (options.series.pie.tilt < 0) {\n\t\t\t\t\toptions.series.pie.tilt = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.bindEvents.push(function(plot, eventHolder) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tif (options.grid.hoverable) {\n\t\t\t\t\teventHolder.unbind(\"mousemove\").mousemove(onMouseMove);\n\t\t\t\t}\n\t\t\t\tif (options.grid.clickable) {\n\t\t\t\t\teventHolder.unbind(\"click\").click(onClick);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tprocessDatapoints(plot, series, data, datapoints);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.drawOverlay.push(function(plot, octx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdrawOverlay(plot, octx);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.draw.push(function(plot, newCtx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdraw(plot, newCtx);\n\t\t\t}\n\t\t});\n\n\t\tfunction processDatapoints(plot, series, datapoints) {\n\t\t\tif (!processed)\t{\n\t\t\t\tprocessed = true;\n\t\t\t\tcanvas = plot.getCanvas();\n\t\t\t\ttarget = $(canvas).parent();\n\t\t\t\toptions = plot.getOptions();\n\t\t\t\tplot.setData(combine(plot.getData()));\n\t\t\t}\n\t\t}\n\n\t\tfunction combine(data) {\n\n\t\t\tvar total = 0,\n\t\t\t\tcombined = 0,\n\t\t\t\tnumCombined = 0,\n\t\t\t\tcolor = options.series.pie.combine.color,\n\t\t\t\tnewdata = [];\n\n\t\t\t// Fix up the raw data from Flot, ensuring the data is numeric\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\n\t\t\t\tvar value = data[i].data;\n\n\t\t\t\t// If the data is an array, we'll assume that it's a standard\n\t\t\t\t// Flot x-y pair, and are concerned only with the second value.\n\n\t\t\t\t// Note how we use the original array, rather than creating a\n\t\t\t\t// new one; this is more efficient and preserves any extra data\n\t\t\t\t// that the user may have stored in higher indexes.\n\n\t\t\t\tif ($.isArray(value) && value.length == 1) {\n \t\t\t\tvalue = value[0];\n\t\t\t\t}\n\n\t\t\t\tif ($.isArray(value)) {\n\t\t\t\t\t// Equivalent to $.isNumeric() but compatible with jQuery < 1.7\n\t\t\t\t\tif (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {\n\t\t\t\t\t\tvalue[1] = +value[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue[1] = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (!isNaN(parseFloat(value)) && isFinite(value)) {\n\t\t\t\t\tvalue = [1, +value];\n\t\t\t\t} else {\n\t\t\t\t\tvalue = [1, 0];\n\t\t\t\t}\n\n\t\t\t\tdata[i].data = [value];\n\t\t\t}\n\n\t\t\t// Sum up all the slices, so we can calculate percentages for each\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\ttotal += data[i].data[0][1];\n\t\t\t}\n\n\t\t\t// Count the number of slices with percentages below the combine\n\t\t\t// threshold; if it turns out to be just one, we won't combine.\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (value / total <= options.series.pie.combine.threshold) {\n\t\t\t\t\tcombined += value;\n\t\t\t\t\tnumCombined++;\n\t\t\t\t\tif (!color) {\n\t\t\t\t\t\tcolor = data[i].color;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (numCombined < 2 || value / total > options.series.pie.combine.threshold) {\n\t\t\t\t\tnewdata.push(\n\t\t\t\t\t\t$.extend(data[i], { /* extend to allow keeping all other original data values\n\t\t\t\t\t\t and using them e.g. in labelFormatter. */\n\t\t\t\t\t\t\tdata: [[1, value]],\n\t\t\t\t\t\t\tcolor: data[i].color,\n\t\t\t\t\t\t\tlabel: data[i].label,\n\t\t\t\t\t\t\tangle: value * Math.PI * 2 / total,\n\t\t\t\t\t\t\tpercent: value / (total / 100)\n\t\t\t\t\t\t})\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (numCombined > 1) {\n\t\t\t\tnewdata.push({\n\t\t\t\t\tdata: [[1, combined]],\n\t\t\t\t\tcolor: color,\n\t\t\t\t\tlabel: options.series.pie.combine.label,\n\t\t\t\t\tangle: combined * Math.PI * 2 / total,\n\t\t\t\t\tpercent: combined / (total / 100)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn newdata;\n\t\t}\n\n\t\tfunction draw(plot, newCtx) {\n\n\t\t\tif (!target) {\n\t\t\t\treturn; // if no series were passed\n\t\t\t}\n\n\t\t\tvar canvasWidth = plot.getPlaceholder().width(),\n\t\t\t\tcanvasHeight = plot.getPlaceholder().height(),\n\t\t\t\tlegendWidth = target.children().filter(\".legend\").children().width() || 0;\n\n\t\t\tctx = newCtx;\n\n\t\t\t// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!\n\n\t\t\t// When combining smaller slices into an 'other' slice, we need to\n\t\t\t// add a new series. Since Flot gives plugins no way to modify the\n\t\t\t// list of series, the pie plugin uses a hack where the first call\n\t\t\t// to processDatapoints results in a call to setData with the new\n\t\t\t// list of series, then subsequent processDatapoints do nothing.\n\n\t\t\t// The plugin-global 'processed' flag is used to control this hack;\n\t\t\t// it starts out false, and is set to true after the first call to\n\t\t\t// processDatapoints.\n\n\t\t\t// Unfortunately this turns future setData calls into no-ops; they\n\t\t\t// call processDatapoints, the flag is true, and nothing happens.\n\n\t\t\t// To fix this we'll set the flag back to false here in draw, when\n\t\t\t// all series have been processed, so the next sequence of calls to\n\t\t\t// processDatapoints once again starts out with a slice-combine.\n\t\t\t// This is really a hack; in 0.9 we need to give plugins a proper\n\t\t\t// way to modify series before any processing begins.\n\n\t\t\tprocessed = false;\n\n\t\t\t// calculate maximum radius and center point\n\n\t\t\tmaxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;\n\t\t\tcenterTop = canvasHeight / 2 + options.series.pie.offset.top;\n\t\t\tcenterLeft = canvasWidth / 2;\n\n\t\t\tif (options.series.pie.offset.left == \"auto\") {\n\t\t\t\tif (options.legend.position.match(\"w\")) {\n\t\t\t\t\tcenterLeft += legendWidth / 2;\n\t\t\t\t} else {\n\t\t\t\t\tcenterLeft -= legendWidth / 2;\n\t\t\t\t}\n\t\t\t\tif (centerLeft < maxRadius) {\n\t\t\t\t\tcenterLeft = maxRadius;\n\t\t\t\t} else if (centerLeft > canvasWidth - maxRadius) {\n\t\t\t\t\tcenterLeft = canvasWidth - maxRadius;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcenterLeft += options.series.pie.offset.left;\n\t\t\t}\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\tattempts = 0;\n\n\t\t\t// Keep shrinking the pie's radius until drawPie returns true,\n\t\t\t// indicating that all the labels fit, or we try too many times.\n\n\t\t\tdo {\n\t\t\t\tif (attempts > 0) {\n\t\t\t\t\tmaxRadius *= REDRAW_SHRINK;\n\t\t\t\t}\n\t\t\t\tattempts += 1;\n\t\t\t\tclear();\n\t\t\t\tif (options.series.pie.tilt <= 0.8) {\n\t\t\t\t\tdrawShadow();\n\t\t\t\t}\n\t\t\t} while (!drawPie() && attempts < REDRAW_ATTEMPTS)\n\n\t\t\tif (attempts >= REDRAW_ATTEMPTS) {\n\t\t\t\tclear();\n\t\t\t\ttarget.prepend(\"
Could not draw pie with labels contained inside canvas
\");\n\t\t\t}\n\n\t\t\tif (plot.setSeries && plot.insertLegend) {\n\t\t\t\tplot.setSeries(slices);\n\t\t\t\tplot.insertLegend();\n\t\t\t}\n\n\t\t\t// we're actually done at this point, just defining internal functions at this point\n\n\t\t\tfunction clear() {\n\t\t\t\tctx.clearRect(0, 0, canvasWidth, canvasHeight);\n\t\t\t\ttarget.children().filter(\".pieLabel, .pieLabelBackground\").remove();\n\t\t\t}\n\n\t\t\tfunction drawShadow() {\n\n\t\t\t\tvar shadowLeft = options.series.pie.shadow.left;\n\t\t\t\tvar shadowTop = options.series.pie.shadow.top;\n\t\t\t\tvar edge = 10;\n\t\t\t\tvar alpha = options.series.pie.shadow.alpha;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\tif (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {\n\t\t\t\t\treturn;\t// shadow would be outside canvas, so don't draw it\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(shadowLeft,shadowTop);\n\t\t\t\tctx.globalAlpha = alpha;\n\t\t\t\tctx.fillStyle = \"#000\";\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\n\t\t\t\t//radius -= edge;\n\n\t\t\t\tfor (var i = 1; i <= edge; i++) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2, false);\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tradius -= i;\n\t\t\t\t}\n\n\t\t\t\tctx.restore();\n\t\t\t}\n\n\t\t\tfunction drawPie() {\n\n\t\t\t\tvar startAngle = Math.PI * options.series.pie.startAngle;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\t\t\t\t//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera\n\n\t\t\t\t// draw slices\n\n\t\t\t\tctx.save();\n\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\tslices[i].startAngle = currentAngle;\n\t\t\t\t\tdrawSlice(slices[i].angle, slices[i].color, true);\n\t\t\t\t}\n\t\t\t\tctx.restore();\n\n\t\t\t\t// draw slice outlines\n\n\t\t\t\tif (options.series.pie.stroke.width > 0) {\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.lineWidth = options.series.pie.stroke.width;\n\t\t\t\t\tcurrentAngle = startAngle;\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tdrawSlice(slices[i].angle, options.series.pie.stroke.color, false);\n\t\t\t\t\t}\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\n\t\t\t\t// draw donut hole\n\n\t\t\t\tdrawDonutHole(ctx);\n\n\t\t\t\tctx.restore();\n\n\t\t\t\t// Draw the labels, returning true if they fit within the plot\n\n\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\treturn drawLabels();\n\t\t\t\t} else return true;\n\n\t\t\t\tfunction drawSlice(angle, color, fill) {\n\n\t\t\t\t\tif (angle <= 0 || isNaN(angle)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fillStyle = color;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.strokeStyle = color;\n\t\t\t\t\t\tctx.lineJoin = \"round\";\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tif (Math.abs(angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t}\n\n\t\t\t\t\t//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\t//ctx.rotate(angle); // This doesn't work properly in Opera\n\t\t\t\t\tcurrentAngle += angle;\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fill();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction drawLabels() {\n\n\t\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\t\tvar radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;\n\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tif (slices[i].percent >= options.series.pie.label.threshold * 100) {\n\t\t\t\t\t\t\tif (!drawLabel(slices[i], currentAngle, i)) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAngle += slices[i].angle;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t\tfunction drawLabel(slice, startAngle, index) {\n\n\t\t\t\t\t\tif (slice.data[0][1] == 0) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// format label text\n\n\t\t\t\t\t\tvar lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;\n\n\t\t\t\t\t\tif (lf) {\n\t\t\t\t\t\t\ttext = lf(slice.label, slice);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = slice.label;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (plf) {\n\t\t\t\t\t\t\ttext = plf(text, slice);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar halfAngle = ((startAngle + slice.angle) + startAngle) / 2;\n\t\t\t\t\t\tvar x = centerLeft + Math.round(Math.cos(halfAngle) * radius);\n\t\t\t\t\t\tvar y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;\n\n\t\t\t\t\t\tvar html = \"\" + text + \"\";\n\t\t\t\t\t\ttarget.append(html);\n\n\t\t\t\t\t\tvar label = target.children(\"#pieLabel\" + index);\n\t\t\t\t\t\tvar labelTop = (y - label.height() / 2);\n\t\t\t\t\t\tvar labelLeft = (x - label.width() / 2);\n\n\t\t\t\t\t\tlabel.css(\"top\", labelTop);\n\t\t\t\t\t\tlabel.css(\"left\", labelLeft);\n\n\t\t\t\t\t\t// check to make sure that the label is not outside the canvas\n\n\t\t\t\t\t\tif (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (options.series.pie.label.background.opacity != 0) {\n\n\t\t\t\t\t\t\t// put in the transparent background separately to avoid blended labels and label boxes\n\n\t\t\t\t\t\t\tvar c = options.series.pie.label.background.color;\n\n\t\t\t\t\t\t\tif (c == null) {\n\t\t\t\t\t\t\t\tc = slice.color;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar pos = \"top:\" + labelTop + \"px;left:\" + labelLeft + \"px;\";\n\t\t\t\t\t\t\t$(\"
\")\n\t\t\t\t\t\t\t\t.css(\"opacity\", options.series.pie.label.background.opacity)\n\t\t\t\t\t\t\t\t.insertBefore(label);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} // end individual label function\n\t\t\t\t} // end drawLabels function\n\t\t\t} // end drawPie function\n\t\t} // end draw function\n\n\t\t// Placed here because it needs to be accessed from multiple locations\n\n\t\tfunction drawDonutHole(layer) {\n\t\t\tif (options.series.pie.innerRadius > 0) {\n\n\t\t\t\t// subtract the center\n\n\t\t\t\tlayer.save();\n\t\t\t\tvar innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;\n\t\t\t\tlayer.globalCompositeOperation = \"destination-out\"; // this does not work with excanvas, but it will fall back to using the stroke color\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.fillStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.fill();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// add inner stroke\n\n\t\t\t\tlayer.save();\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.strokeStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.stroke();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.\n\t\t\t}\n\t\t}\n\n\t\t//-- Additional Interactive related functions --\n\n\t\tfunction isPointInPoly(poly, pt) {\n\t\t\tfor(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)\n\t\t\t\t((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))\n\t\t\t\t&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])\n\t\t\t\t&& (c = !c);\n\t\t\treturn c;\n\t\t}\n\n\t\tfunction findNearbySlice(mouseX, mouseY) {\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\toptions = plot.getOptions(),\n\t\t\t\tradius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,\n\t\t\t\tx, y;\n\n\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\n\t\t\t\tvar s = slices[i];\n\n\t\t\t\tif (s.pie.show) {\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t//ctx.scale(1, options.series.pie.tilt);\t// this actually seems to break everything when here.\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tx = mouseX - centerLeft;\n\t\t\t\t\ty = mouseY - centerTop;\n\n\t\t\t\t\tif (ctx.isPointInPath) {\n\t\t\t\t\t\tif (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// excanvas for IE doesn;t support isPointInPath, this is a workaround.\n\n\t\t\t\t\t\tvar p1X = radius * Math.cos(s.startAngle),\n\t\t\t\t\t\t\tp1Y = radius * Math.sin(s.startAngle),\n\t\t\t\t\t\t\tp2X = radius * Math.cos(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp2Y = radius * Math.sin(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp3X = radius * Math.cos(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp3Y = radius * Math.sin(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp4X = radius * Math.cos(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp5X = radius * Math.cos(s.startAngle + s.angle),\n\t\t\t\t\t\t\tp5Y = radius * Math.sin(s.startAngle + s.angle),\n\t\t\t\t\t\t\tarrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],\n\t\t\t\t\t\t\tarrPoint = [x, y];\n\n\t\t\t\t\t\t// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?\n\n\t\t\t\t\t\tif (isPointInPoly(arrPoly, arrPoint)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction onMouseMove(e) {\n\t\t\ttriggerClickHoverEvent(\"plothover\", e);\n\t\t}\n\n\t\tfunction onClick(e) {\n\t\t\ttriggerClickHoverEvent(\"plotclick\", e);\n\t\t}\n\n\t\t// trigger click or hover event (they send the same parameters so we share their code)\n\n\t\tfunction triggerClickHoverEvent(eventname, e) {\n\n\t\t\tvar offset = plot.offset();\n\t\t\tvar canvasX = parseInt(e.pageX - offset.left);\n\t\t\tvar canvasY = parseInt(e.pageY - offset.top);\n\t\t\tvar item = findNearbySlice(canvasX, canvasY);\n\n\t\t\tif (options.grid.autoHighlight) {\n\n\t\t\t\t// clear auto-highlights\n\n\t\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\t\tvar h = highlights[i];\n\t\t\t\t\tif (h.auto == eventname && !(item && h.series == item.series)) {\n\t\t\t\t\t\tunhighlight(h.series);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// highlight the slice\n\n\t\t\tif (item) {\n\t\t\t\thighlight(item.series, eventname);\n\t\t\t}\n\n\t\t\t// trigger any hover bind events\n\n\t\t\tvar pos = { pageX: e.pageX, pageY: e.pageY };\n\t\t\ttarget.trigger(eventname, [pos, item]);\n\t\t}\n\n\t\tfunction highlight(s, auto) {\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i == -1) {\n\t\t\t\thighlights.push({ series: s, auto: auto });\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t} else if (!auto) {\n\t\t\t\thighlights[i].auto = false;\n\t\t\t}\n\t\t}\n\n\t\tfunction unhighlight(s) {\n\t\t\tif (s == null) {\n\t\t\t\thighlights = [];\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i != -1) {\n\t\t\t\thighlights.splice(i, 1);\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\t\t}\n\n\t\tfunction indexOfHighlight(s) {\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tvar h = highlights[i];\n\t\t\t\tif (h.series == s)\n\t\t\t\t\treturn i;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tfunction drawOverlay(plot, octx) {\n\n\t\t\tvar options = plot.getOptions();\n\n\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\toctx.save();\n\t\t\toctx.translate(centerLeft, centerTop);\n\t\t\toctx.scale(1, options.series.pie.tilt);\n\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tdrawHighlight(highlights[i].series);\n\t\t\t}\n\n\t\t\tdrawDonutHole(octx);\n\n\t\t\toctx.restore();\n\n\t\t\tfunction drawHighlight(series) {\n\n\t\t\t\tif (series.angle <= 0 || isNaN(series.angle)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();\n\t\t\t\toctx.fillStyle = \"rgba(255, 255, 255, \" + options.series.pie.highlight.opacity + \")\"; // this is temporary until we have access to parseColor\n\t\t\t\toctx.beginPath();\n\t\t\t\tif (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\toctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t}\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);\n\t\t\t\toctx.closePath();\n\t\t\t\toctx.fill();\n\t\t\t}\n\t\t}\n\t} // end init (plugin body)\n\n\t// define pie specific options and their default values\n\n\tvar options = {\n\t\tseries: {\n\t\t\tpie: {\n\t\t\t\tshow: false,\n\t\t\t\tradius: \"auto\",\t// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\tinnerRadius: 0, /* for donut */\n\t\t\t\tstartAngle: 3/2,\n\t\t\t\ttilt: 1,\n\t\t\t\tshadow: {\n\t\t\t\t\tleft: 5,\t// shadow left offset\n\t\t\t\t\ttop: 15,\t// shadow top offset\n\t\t\t\t\talpha: 0.02\t// shadow alpha\n\t\t\t\t},\n\t\t\t\toffset: {\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: \"auto\"\n\t\t\t\t},\n\t\t\t\tstroke: {\n\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\twidth: 1\n\t\t\t\t},\n\t\t\t\tlabel: {\n\t\t\t\t\tshow: \"auto\",\n\t\t\t\t\tformatter: function(label, slice) {\n\t\t\t\t\t\treturn \"
\" + label + \"
\" + Math.round(slice.percent) + \"%
\";\n\t\t\t\t\t},\t// formatter function\n\t\t\t\t\tradius: 1,\t// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\t\tbackground: {\n\t\t\t\t\t\tcolor: null,\n\t\t\t\t\t\topacity: 0\n\t\t\t\t\t},\n\t\t\t\t\tthreshold: 0\t// percentage at which to hide the label (i.e. the slice is too narrow)\n\t\t\t\t},\n\t\t\t\tcombine: {\n\t\t\t\t\tthreshold: -1,\t// percentage at which to combine little slices into one larger slice\n\t\t\t\t\tcolor: null,\t// color to give the new slice (auto-generated if null)\n\t\t\t\t\tlabel: \"Other\"\t// label to give the new slice\n\t\t\t\t},\n\t\t\t\thighlight: {\n\t\t\t\t\t//color: \"#fff\",\t\t// will add this functionality once parseColor is available\n\t\t\t\t\topacity: 0.5\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"pie\",\n\t\tversion: \"1.1\"\n\t});\n\n})(jQuery);\n","/* Pretty handling of time axes.\n\nCopyright (c) 2007-2014 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nSet axis.mode to \"time\" to enable. See the section \"Time series data\" in\nAPI.txt for details.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\txaxis: {\n\t\t\ttimezone: null,\t\t// \"browser\" for local to the client or timezone for timezone-js\n\t\t\ttimeformat: null,\t// format string to use\n\t\t\ttwelveHourClock: false,\t// 12 or 24 time in time mode\n\t\t\tmonthNames: null\t// list of names of months\n\t\t}\n\t};\n\n\t// round to nearby lower multiple of base\n\n\tfunction floorInBase(n, base) {\n\t\treturn base * Math.floor(n / base);\n\t}\n\n\t// Returns a string with the date d formatted according to fmt.\n\t// A subset of the Open Group's strftime format is supported.\n\n\tfunction formatDate(d, fmt, monthNames, dayNames) {\n\n\t\tif (typeof d.strftime == \"function\") {\n\t\t\treturn d.strftime(fmt);\n\t\t}\n\n\t\tvar leftPad = function(n, pad) {\n\t\t\tn = \"\" + n;\n\t\t\tpad = \"\" + (pad == null ? \"0\" : pad);\n\t\t\treturn n.length == 1 ? pad + n : n;\n\t\t};\n\n\t\tvar r = [];\n\t\tvar escape = false;\n\t\tvar hours = d.getHours();\n\t\tvar isAM = hours < 12;\n\n\t\tif (monthNames == null) {\n\t\t\tmonthNames = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t}\n\n\t\tif (dayNames == null) {\n\t\t\tdayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\t\t}\n\n\t\tvar hours12;\n\n\t\tif (hours > 12) {\n\t\t\thours12 = hours - 12;\n\t\t} else if (hours == 0) {\n\t\t\thours12 = 12;\n\t\t} else {\n\t\t\thours12 = hours;\n\t\t}\n\n\t\tfor (var i = 0; i < fmt.length; ++i) {\n\n\t\t\tvar c = fmt.charAt(i);\n\n\t\t\tif (escape) {\n\t\t\t\tswitch (c) {\n\t\t\t\t\tcase 'a': c = \"\" + dayNames[d.getDay()]; break;\n\t\t\t\t\tcase 'b': c = \"\" + monthNames[d.getMonth()]; break;\n\t\t\t\t\tcase 'd': c = leftPad(d.getDate()); break;\n\t\t\t\t\tcase 'e': c = leftPad(d.getDate(), \" \"); break;\n\t\t\t\t\tcase 'h':\t// For back-compat with 0.7; remove in 1.0\n\t\t\t\t\tcase 'H': c = leftPad(hours); break;\n\t\t\t\t\tcase 'I': c = leftPad(hours12); break;\n\t\t\t\t\tcase 'l': c = leftPad(hours12, \" \"); break;\n\t\t\t\t\tcase 'm': c = leftPad(d.getMonth() + 1); break;\n\t\t\t\t\tcase 'M': c = leftPad(d.getMinutes()); break;\n\t\t\t\t\t// quarters not in Open Group's strftime specification\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tc = \"\" + (Math.floor(d.getMonth() / 3) + 1); break;\n\t\t\t\t\tcase 'S': c = leftPad(d.getSeconds()); break;\n\t\t\t\t\tcase 'y': c = leftPad(d.getFullYear() % 100); break;\n\t\t\t\t\tcase 'Y': c = \"\" + d.getFullYear(); break;\n\t\t\t\t\tcase 'p': c = (isAM) ? (\"\" + \"am\") : (\"\" + \"pm\"); break;\n\t\t\t\t\tcase 'P': c = (isAM) ? (\"\" + \"AM\") : (\"\" + \"PM\"); break;\n\t\t\t\t\tcase 'w': c = \"\" + d.getDay(); break;\n\t\t\t\t}\n\t\t\t\tr.push(c);\n\t\t\t\tescape = false;\n\t\t\t} else {\n\t\t\t\tif (c == \"%\") {\n\t\t\t\t\tescape = true;\n\t\t\t\t} else {\n\t\t\t\t\tr.push(c);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn r.join(\"\");\n\t}\n\n\t// To have a consistent view of time-based data independent of which time\n\t// zone the client happens to be in we need a date-like object independent\n\t// of time zones. This is done through a wrapper that only calls the UTC\n\t// versions of the accessor methods.\n\n\tfunction makeUtcWrapper(d) {\n\n\t\tfunction addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {\n\t\t\tsourceObj[sourceMethod] = function() {\n\t\t\t\treturn targetObj[targetMethod].apply(targetObj, arguments);\n\t\t\t};\n\t\t};\n\n\t\tvar utc = {\n\t\t\tdate: d\n\t\t};\n\n\t\t// support strftime, if found\n\n\t\tif (d.strftime != undefined) {\n\t\t\taddProxyMethod(utc, \"strftime\", d, \"strftime\");\n\t\t}\n\n\t\taddProxyMethod(utc, \"getTime\", d, \"getTime\");\n\t\taddProxyMethod(utc, \"setTime\", d, \"setTime\");\n\n\t\tvar props = [\"Date\", \"Day\", \"FullYear\", \"Hours\", \"Milliseconds\", \"Minutes\", \"Month\", \"Seconds\"];\n\n\t\tfor (var p = 0; p < props.length; p++) {\n\t\t\taddProxyMethod(utc, \"get\" + props[p], d, \"getUTC\" + props[p]);\n\t\t\taddProxyMethod(utc, \"set\" + props[p], d, \"setUTC\" + props[p]);\n\t\t}\n\n\t\treturn utc;\n\t};\n\n\t// select time zone strategy. This returns a date-like object tied to the\n\t// desired timezone\n\n\tfunction dateGenerator(ts, opts) {\n\t\tif (opts.timezone == \"browser\") {\n\t\t\treturn new Date(ts);\n\t\t} else if (!opts.timezone || opts.timezone == \"utc\") {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t} else if (typeof timezoneJS != \"undefined\" && typeof timezoneJS.Date != \"undefined\") {\n\t\t\tvar d = new timezoneJS.Date();\n\t\t\t// timezone-js is fickle, so be sure to set the time zone before\n\t\t\t// setting the time.\n\t\t\td.setTimezone(opts.timezone);\n\t\t\td.setTime(ts);\n\t\t\treturn d;\n\t\t} else {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t}\n\t}\n\t\n\t// map of app. size of time units in milliseconds\n\n\tvar timeUnitSize = {\n\t\t\"second\": 1000,\n\t\t\"minute\": 60 * 1000,\n\t\t\"hour\": 60 * 60 * 1000,\n\t\t\"day\": 24 * 60 * 60 * 1000,\n\t\t\"month\": 30 * 24 * 60 * 60 * 1000,\n\t\t\"quarter\": 3 * 30 * 24 * 60 * 60 * 1000,\n\t\t\"year\": 365.2425 * 24 * 60 * 60 * 1000\n\t};\n\n\t// the allowed tick sizes, after 1 year we use\n\t// an integer algorithm\n\n\tvar baseSpec = [\n\t\t[1, \"second\"], [2, \"second\"], [5, \"second\"], [10, \"second\"],\n\t\t[30, \"second\"], \n\t\t[1, \"minute\"], [2, \"minute\"], [5, \"minute\"], [10, \"minute\"],\n\t\t[30, \"minute\"], \n\t\t[1, \"hour\"], [2, \"hour\"], [4, \"hour\"],\n\t\t[8, \"hour\"], [12, \"hour\"],\n\t\t[1, \"day\"], [2, \"day\"], [3, \"day\"],\n\t\t[0.25, \"month\"], [0.5, \"month\"], [1, \"month\"],\n\t\t[2, \"month\"]\n\t];\n\n\t// we don't know which variant(s) we'll need yet, but generating both is\n\t// cheap\n\n\tvar specMonths = baseSpec.concat([[3, \"month\"], [6, \"month\"],\n\t\t[1, \"year\"]]);\n\tvar specQuarters = baseSpec.concat([[1, \"quarter\"], [2, \"quarter\"],\n\t\t[1, \"year\"]]);\n\n\tfunction init(plot) {\n\t\tplot.hooks.processOptions.push(function (plot, options) {\n\t\t\t$.each(plot.getAxes(), function(axisName, axis) {\n\n\t\t\t\tvar opts = axis.options;\n\n\t\t\t\tif (opts.mode == \"time\") {\n\t\t\t\t\taxis.tickGenerator = function(axis) {\n\n\t\t\t\t\t\tvar ticks = [];\n\t\t\t\t\t\tvar d = dateGenerator(axis.min, opts);\n\t\t\t\t\t\tvar minSize = 0;\n\n\t\t\t\t\t\t// make quarter use a possibility if quarters are\n\t\t\t\t\t\t// mentioned in either of these options\n\n\t\t\t\t\t\tvar spec = (opts.tickSize && opts.tickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ||\n\t\t\t\t\t\t\t(opts.minTickSize && opts.minTickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ? specQuarters : specMonths;\n\n\t\t\t\t\t\tif (opts.minTickSize != null) {\n\t\t\t\t\t\t\tif (typeof opts.tickSize == \"number\") {\n\t\t\t\t\t\t\t\tminSize = opts.tickSize;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tminSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (var i = 0; i < spec.length - 1; ++i) {\n\t\t\t\t\t\t\tif (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]\n\t\t\t\t\t\t\t\t\t\t\t + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2\n\t\t\t\t\t\t\t\t&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = spec[i][0];\n\t\t\t\t\t\tvar unit = spec[i][1];\n\n\t\t\t\t\t\t// special-case the possibility of several years\n\n\t\t\t\t\t\tif (unit == \"year\") {\n\n\t\t\t\t\t\t\t// if given a minTickSize in years, just use it,\n\t\t\t\t\t\t\t// ensuring that it's an integer\n\n\t\t\t\t\t\t\tif (opts.minTickSize != null && opts.minTickSize[1] == \"year\") {\n\t\t\t\t\t\t\t\tsize = Math.floor(opts.minTickSize[0]);\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tvar magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));\n\t\t\t\t\t\t\t\tvar norm = (axis.delta / timeUnitSize.year) / magn;\n\n\t\t\t\t\t\t\t\tif (norm < 1.5) {\n\t\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t\t} else if (norm < 3) {\n\t\t\t\t\t\t\t\t\tsize = 2;\n\t\t\t\t\t\t\t\t} else if (norm < 7.5) {\n\t\t\t\t\t\t\t\t\tsize = 5;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsize = 10;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsize *= magn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// minimum size for years is 1\n\n\t\t\t\t\t\t\tif (size < 1) {\n\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\taxis.tickSize = opts.tickSize || [size, unit];\n\t\t\t\t\t\tvar tickSize = axis.tickSize[0];\n\t\t\t\t\t\tunit = axis.tickSize[1];\n\n\t\t\t\t\t\tvar step = tickSize * timeUnitSize[unit];\n\n\t\t\t\t\t\tif (unit == \"second\") {\n\t\t\t\t\t\t\td.setSeconds(floorInBase(d.getSeconds(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"minute\") {\n\t\t\t\t\t\t\td.setMinutes(floorInBase(d.getMinutes(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"hour\") {\n\t\t\t\t\t\t\td.setHours(floorInBase(d.getHours(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"month\") {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"quarter\") {\n\t\t\t\t\t\t\td.setMonth(3 * floorInBase(d.getMonth() / 3,\n\t\t\t\t\t\t\t\ttickSize));\n\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\td.setFullYear(floorInBase(d.getFullYear(), tickSize));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// reset smaller components\n\n\t\t\t\t\t\td.setMilliseconds(0);\n\n\t\t\t\t\t\tif (step >= timeUnitSize.minute) {\n\t\t\t\t\t\t\td.setSeconds(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.hour) {\n\t\t\t\t\t\t\td.setMinutes(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day) {\n\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day * 4) {\n\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.month * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 3));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.quarter * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.year) {\n\t\t\t\t\t\t\td.setMonth(0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar carry = 0;\n\t\t\t\t\t\tvar v = Number.NaN;\n\t\t\t\t\t\tvar prev;\n\n\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\tprev = v;\n\t\t\t\t\t\t\tv = d.getTime();\n\t\t\t\t\t\t\tticks.push(v);\n\n\t\t\t\t\t\t\tif (unit == \"month\" || unit == \"quarter\") {\n\t\t\t\t\t\t\t\tif (tickSize < 1) {\n\n\t\t\t\t\t\t\t\t\t// a bit complicated - we'll divide the\n\t\t\t\t\t\t\t\t\t// month/quarter up but we need to take\n\t\t\t\t\t\t\t\t\t// care of fractions so we don't end up in\n\t\t\t\t\t\t\t\t\t// the middle of a day\n\n\t\t\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t\t\t\tvar start = d.getTime();\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\t(unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t\tvar end = d.getTime();\n\t\t\t\t\t\t\t\t\td.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);\n\t\t\t\t\t\t\t\t\tcarry = d.getHours();\n\t\t\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\ttickSize * (unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\t\td.setFullYear(d.getFullYear() + tickSize);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\td.setTime(v + step);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (v < axis.max && v != prev);\n\n\t\t\t\t\t\treturn ticks;\n\t\t\t\t\t};\n\n\t\t\t\t\taxis.tickFormatter = function (v, axis) {\n\n\t\t\t\t\t\tvar d = dateGenerator(v, axis.options);\n\n\t\t\t\t\t\t// first check global format\n\n\t\t\t\t\t\tif (opts.timeformat != null) {\n\t\t\t\t\t\t\treturn formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// possibly use quarters if quarters are mentioned in\n\t\t\t\t\t\t// any of these places\n\n\t\t\t\t\t\tvar useQuarters = (axis.options.tickSize &&\n\t\t\t\t\t\t\t\taxis.options.tickSize[1] == \"quarter\") ||\n\t\t\t\t\t\t\t(axis.options.minTickSize &&\n\t\t\t\t\t\t\t\taxis.options.minTickSize[1] == \"quarter\");\n\n\t\t\t\t\t\tvar t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];\n\t\t\t\t\t\tvar span = axis.max - axis.min;\n\t\t\t\t\t\tvar suffix = (opts.twelveHourClock) ? \" %p\" : \"\";\n\t\t\t\t\t\tvar hourCode = (opts.twelveHourClock) ? \"%I\" : \"%H\";\n\t\t\t\t\t\tvar fmt;\n\n\t\t\t\t\t\tif (t < timeUnitSize.minute) {\n\t\t\t\t\t\t\tfmt = hourCode + \":%M:%S\" + suffix;\n\t\t\t\t\t\t} else if (t < timeUnitSize.day) {\n\t\t\t\t\t\t\tif (span < 2 * timeUnitSize.day) {\n\t\t\t\t\t\t\t\tfmt = hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %d \" + hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t < timeUnitSize.month) {\n\t\t\t\t\t\t\tfmt = \"%b %d\";\n\t\t\t\t\t\t} else if ((useQuarters && t < timeUnitSize.quarter) ||\n\t\t\t\t\t\t\t(!useQuarters && t < timeUnitSize.year)) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"%b\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (useQuarters && t < timeUnitSize.year) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"Q%q\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"Q%q %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt = \"%Y\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);\n\n\t\t\t\t\t\treturn rt;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: 'time',\n\t\tversion: '1.0'\n\t});\n\n\t// Time-axis support used to be in Flot core, which exposed the\n\t// formatDate function on the plot object. Various plugins depend\n\t// on the function, so we need to re-expose it here.\n\n\t$.plot.formatDate = formatDate;\n\t$.plot.dateGenerator = dateGenerator;\n\n})(jQuery);\n","/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __createBinding(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (p !== \"default\" && !exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, privateMap) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to get private field on non-instance\");\r\n }\r\n return privateMap.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, privateMap, value) {\r\n if (!privateMap.has(receiver)) {\r\n throw new TypeError(\"attempted to set private field on non-instance\");\r\n }\r\n privateMap.set(receiver, value);\r\n return value;\r\n}\r\n","import _ from 'lodash';\nimport './lib/jquery.flot.pie';\nimport $ from 'jquery';\n//import './lib/jquery.flot';\n\nexport default function link(scope: any, elem: any, attrs: any, ctrl: any) {\n let data;\n const panel = ctrl.panel;\n elem = elem.find('.piechart-panel__chart');\n const $tooltip = $('
') as any;\n\n ctrl.events.on('render', () => {\n if (panel.legendType === 'Right side') {\n render(false);\n setTimeout(() => {\n render(true);\n }, 50);\n } else {\n render(true);\n }\n });\n\n function getLegendHeight(panelHeight: any) {\n if (!ctrl.panel.legend.show || ctrl.panel.legendType === 'Right side' || ctrl.panel.legendType === 'On graph') {\n return 20;\n }\n\n if ((ctrl.panel.legendType === 'Under graph' && ctrl.panel.legend.percentage) || ctrl.panel.legend.values) {\n const breakPoint = parseInt(ctrl.panel.breakPoint, 10) / 100;\n const total = 23 + 20 * data.length;\n return Math.min(total, Math.floor(panelHeight * breakPoint));\n }\n\n return 0;\n }\n\n function formatter(label: any, slice: any) {\n const sliceData = slice.data[0][slice.data[0].length - 1];\n let decimal = 2;\n const start = `
${label}
`;\n\n if (ctrl.panel.legend.percentageDecimals) {\n decimal = ctrl.panel.legend.percentageDecimals;\n }\n if (ctrl.panel.legend.values && ctrl.panel.legend.percentage) {\n return start + ctrl.formatValue(sliceData) + '
' + slice.percent.toFixed(decimal) + '%
';\n } else if (ctrl.panel.legend.values) {\n return start + ctrl.formatValue(sliceData) + '
';\n } else if (ctrl.panel.legend.percentage) {\n return start + slice.percent.toFixed(decimal) + '%';\n } else {\n return start + '';\n }\n }\n\n function noDataPoints() {\n const html = '
No data points
';\n elem.html(html);\n }\n\n function addPieChart() {\n const width = elem.width();\n const height = ctrl.height - getLegendHeight(ctrl.height);\n\n const size = Math.min(width, height);\n\n const plotCanvas = $('
');\n const plotCss = {\n margin: 'auto',\n position: 'relative',\n paddingBottom: 20 + 'px',\n height: size + 'px',\n };\n\n plotCanvas.css(plotCss);\n\n const backgroundColor = $('body').css('background-color');\n\n const options = {\n legend: {\n show: false,\n },\n series: {\n pie: {\n radius: 1,\n innerRadius: 0,\n show: true,\n stroke: {\n color: backgroundColor,\n width: parseFloat(ctrl.panel.strokeWidth).toFixed(1),\n },\n label: {\n show: ctrl.panel.legend.show && ctrl.panel.legendType === 'On graph',\n formatter: formatter,\n },\n highlight: {\n opacity: 0.0,\n },\n combine: {\n threshold: ctrl.panel.combine.threshold,\n label: ctrl.panel.combine.label,\n },\n },\n },\n grid: {\n hoverable: true,\n clickable: false,\n },\n };\n\n if (panel.pieType === 'donut') {\n options.series.pie.innerRadius = 0.5;\n }\n\n data = ctrl.data;\n\n for (let i = 0; i < data.length; i++) {\n const series = data[i];\n\n // if hidden remove points\n if (ctrl.hiddenSeries[series.label]) {\n series.data = {};\n }\n }\n\n if (panel.legend.sort) {\n if (ctrl.panel.valueName !== panel.legend.sort) {\n panel.legend.sort = ctrl.panel.valueName;\n }\n if (panel.legend.sortDesc === true) {\n data.sort((a: any, b: any) => {\n return b.legendData - a.legendData;\n });\n } else {\n data.sort((a: any, b: any) => {\n return a.legendData - b.legendData;\n });\n }\n }\n\n elem.html(plotCanvas);\n\n // @ts-ignore\n $.plot(plotCanvas, data, options);\n plotCanvas.bind('plothover', (event: any, pos: any, item: any) => {\n if (!item) {\n $tooltip.detach();\n return;\n }\n\n let body;\n const percent = parseFloat(item.series.percent).toFixed(2);\n const formatted = ctrl.formatValue(item.series.data[0][1]);\n\n body = '
';\n body += '
' + _.escape(item.series.label) + ': ' + formatted;\n body += ' (' + percent + '%)' + '
';\n body += '
';\n\n $tooltip.html(body).place_tt(pos.pageX + 20, pos.pageY);\n });\n }\n\n function render(incrementRenderCounter: any) {\n if (!ctrl.data) {\n return;\n }\n\n data = ctrl.data;\n\n if (0 === ctrl.data.length) {\n noDataPoints();\n } else {\n addPieChart();\n }\n\n if (incrementRenderCounter) {\n ctrl.renderingCompleted();\n }\n }\n}\n","import angular from 'angular';\n// @ts-ignore\nimport $ from 'jquery';\n//import './lib/jquery.flot.pie';\n\n//import 'jquery.flot';\n\nimport './lib/jquery.flot.time';\n\nimport _ from 'lodash';\n\n// @ts-ignore\nimport PerfectScrollbar from './lib/perfect-scrollbar.min';\n\nangular.module('grafana.directives').directive('piechartLegend', (popoverSrv: any, $timeout: any) => {\n return {\n link: (scope: any, elem: any) => {\n const $container = $('
');\n let firstRender = true;\n const ctrl = scope.ctrl;\n const panel = ctrl.panel;\n let data: any;\n let seriesList: any;\n let dataList: any;\n let i;\n let legendScrollbar: any;\n\n scope.$on('$destroy', () => {\n if (legendScrollbar) {\n legendScrollbar.destroy();\n }\n });\n\n ctrl.events.on('render', () => {\n data = ctrl.series;\n if (data) {\n for (const i in data) {\n data[i].color = ctrl.data[i].color;\n }\n render();\n }\n });\n\n function getSeriesIndexForElement(el: any) {\n return el.parents('[data-series-index]').data('series-index');\n }\n\n function toggleSeries(e: any) {\n const el = $(e.currentTarget);\n // Consider Combine entry as special case (not clickable)\n if (el && el.text() !== panel.combine.label) {\n const index = getSeriesIndexForElement(el);\n const seriesInfo = dataList[index];\n const scrollPosition = $($container.children('tbody')).scrollTop();\n ctrl.toggleSeries(seriesInfo);\n if (typeof scrollPosition !== 'undefined') {\n $($container.children('tbody')).scrollTop(scrollPosition);\n }\n }\n }\n\n function sortLegend(e: any) {\n const el = $(e.currentTarget);\n const stat = el.data('stat');\n\n if (stat !== panel.legend.sort) {\n panel.legend.sortDesc = null;\n }\n\n // if already sort ascending, disable sorting\n if (panel.legend.sortDesc === false) {\n panel.legend.sort = null;\n panel.legend.sortDesc = null;\n ctrl.render();\n return;\n }\n\n panel.legend.sortDesc = !panel.legend.sortDesc;\n panel.legend.sort = stat;\n ctrl.render();\n }\n\n function getLegendHeaderHtml(statName: any) {\n let name = statName;\n\n if (panel.legend.header) {\n name = panel.legend.header;\n }\n\n let html = '' + _.escape(name);\n\n if (panel.legend.sort === statName) {\n const cssClass = panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up';\n html += ' ';\n }\n\n return html + '';\n }\n\n function getLegendPercentageHtml(statName: any) {\n const name = 'percentage';\n let html = '' + name;\n\n if (panel.legend.sort === statName) {\n const cssClass = panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up';\n html += ' ';\n }\n\n return html + '';\n }\n\n function openColorSelector(e: any) {\n // if we clicked inside poup container ignore click\n if ($(e.target).parents('.popover').length) {\n return;\n }\n\n const el = $(e.currentTarget).find('.fa-minus');\n const index = getSeriesIndexForElement(el);\n const series = seriesList[index];\n\n $timeout(() => {\n popoverSrv.show({\n element: el[0],\n position: 'right center',\n template:\n '' +\n '',\n openOn: 'hover',\n classNames: 'drop-popover drop-popover--transparent',\n model: {\n autoClose: true,\n series: series,\n toggleAxis: () => {},\n colorSelected: (color: any) => {\n ctrl.changeSeriesColor(series, color);\n },\n },\n });\n });\n }\n\n function render() {\n if (panel.legendType === 'On graph' || !panel.legend.show) {\n $container.empty();\n elem.find('.piechart-legend').css('padding-top', 0);\n return;\n } else {\n elem.find('.piechart-legend').css('padding-top', 6);\n }\n\n if (firstRender) {\n elem.append($container);\n $container.on('click', '.piechart-legend-icon', openColorSelector);\n $container.on('click', '.piechart-legend-alias', toggleSeries);\n $container.on('click', 'th', sortLegend);\n firstRender = false;\n }\n\n seriesList = data;\n dataList = ctrl.data;\n\n $container.empty();\n\n const width = panel.legendType === 'Right side' && panel.legend.sideWidth ? panel.legend.sideWidth + 'px' : '';\n const ieWidth =\n panel.legendType === 'Right side' && panel.legend.sideWidth ? panel.legend.sideWidth - 1 + 'px' : '';\n elem.css('min-width', width);\n elem.css('width', ieWidth);\n\n const showValues = panel.legend.values || panel.legend.percentage;\n const tableLayout = (panel.legendType === 'Under graph' || panel.legendType === 'Right side') && showValues;\n\n $container.toggleClass('piechart-legend-table', tableLayout);\n\n let legendHeader;\n if (tableLayout) {\n let header = '';\n if (panel.legend.values) {\n header += getLegendHeaderHtml(ctrl.panel.valueName);\n }\n if (panel.legend.percentage) {\n header += getLegendPercentageHtml(ctrl.panel.valueName);\n }\n header += '';\n legendHeader = $(header);\n }\n\n let total = 0;\n if (panel.legend.percentage) {\n for (i = 0; i < seriesList.length; i++) {\n if (!ctrl.hiddenSeries[seriesList[i].label]) {\n total += seriesList[i].stats[ctrl.panel.valueName];\n }\n }\n }\n\n let combineNum = 0;\n const combineVal = {\n label: panel.combine.label,\n color: '',\n legendData: 0,\n };\n const seriesElements = [];\n\n for (i = 0; i < seriesList.length; i++) {\n const series = seriesList[i];\n const seriesData = dataList[i];\n // combine lower values than threshold and not include into legent\n if (seriesData.data / total < panel.combine.threshold) {\n // Jump hidden series\n if (!ctrl.hiddenSeries[seriesData.label]) {\n combineNum++;\n combineVal.legendData += seriesData.data;\n }\n } else {\n // ignore empty series\n if (panel.legend.hideEmpty && series.allIsNull) {\n continue;\n }\n // ignore series excluded via override\n if (!series.legend) {\n continue;\n }\n\n seriesElements.push($(generateLegendItem(seriesData, i, total, showValues, tableLayout)));\n }\n }\n\n // Add combine to legend\n if (combineNum > 0) {\n // Define color according to hiddenSeries and combineNum\n if (typeof panel.legend.sortDesc === 'undefined' || panel.legend.sortDesc === null || panel.legend.sortDesc) {\n if (Object.keys(ctrl.hiddenSeries).length > 0) {\n let _el, _max;\n for (const _key in ctrl.hiddenSeries) {\n _el = dataList.find((x: any) => x.label === _key);\n if (typeof _max === 'undefined') {\n _max = _el.legendData;\n combineVal.color = _el.color;\n } else {\n if (_el.legendData > _max) {\n _max = _el.legendData;\n combineVal.color = _el.color;\n }\n }\n }\n } else {\n combineVal.color = seriesList[seriesList.length - combineNum].color;\n }\n } else {\n combineVal.color = seriesList[0].color;\n }\n\n seriesElements.push(\n $(generateLegendItem(combineVal, dataList.length - combineNum, total, showValues, tableLayout))\n );\n }\n\n if (tableLayout) {\n // const topPadding = 6;\n const tbodyElem = $('');\n // tbodyElem.css(\"max-height\", maxHeight - topPadding);\n if (typeof legendHeader !== 'undefined') {\n tbodyElem.append(legendHeader);\n }\n tbodyElem.append(seriesElements);\n $container.append(tbodyElem);\n } else {\n $container.append(seriesElements);\n }\n\n if (panel.legendType === 'Under graph') {\n addScrollbar();\n } else {\n destroyScrollbar();\n }\n }\n\n function generateLegendItem(data: any, index: any, total: any, showValues: boolean, tableLayout: boolean) {\n let html = '
';\n html += '';\n html += '';\n html += '';\n\n html += '' + _.escape(data.label) + '';\n let decimal = 0;\n if (ctrl.panel.legend.percentageDecimals) {\n decimal = ctrl.panel.legend.percentageDecimals;\n }\n\n if (showValues && tableLayout) {\n const value = data.legendData;\n if (panel.legend.values) {\n html += '
' + ctrl.formatValue(value) + '
';\n }\n if (total) {\n const pvalue = ((value / total) * 100).toFixed(decimal) + '%';\n html += '
' + pvalue + '
';\n }\n }\n html += '
';\n\n return html;\n }\n\n function addScrollbar() {\n const scrollbarOptions = {\n // Number of pixels the content height can surpass the container height without enabling the scroll bar.\n scrollYMarginOffset: 2,\n suppressScrollX: true,\n };\n\n if (!legendScrollbar) {\n legendScrollbar = new PerfectScrollbar(elem[0], scrollbarOptions);\n } else {\n legendScrollbar.update();\n }\n }\n\n function destroyScrollbar() {\n if (legendScrollbar) {\n legendScrollbar.destroy();\n legendScrollbar = null;\n }\n }\n },\n };\n});\n","import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk';\nimport _ from 'lodash';\nimport kbn from 'grafana/app/core/utils/kbn';\n// @ts-ignore\nimport TimeSeries from 'grafana/app/core/time_series';\nimport rendering from './rendering';\nimport './legend';\n\nclass PieChartCtrl extends MetricsPanelCtrl {\n static templateUrl = 'module.html';\n $rootScope: any;\n hiddenSeries: any;\n unitFormats: any;\n series: any;\n data: any;\n\n /** @ngInject */\n constructor($scope: any, $injector: any, $rootScope: any) {\n super($scope, $injector);\n this.$rootScope = $rootScope;\n this.hiddenSeries = {};\n\n const panelDefaults = {\n pieType: 'pie',\n legend: {\n show: true, // disable/enable legend\n values: true,\n },\n links: [],\n datasource: null,\n interval: null,\n targets: [{}],\n cacheTimeout: null,\n nullPointMode: 'connected',\n legendType: 'Under graph',\n breakPoint: '50%',\n aliasColors: {},\n format: 'short',\n valueName: 'current',\n strokeWidth: 1,\n fontSize: '80%',\n combine: {\n threshold: 0.0,\n label: 'Others',\n },\n };\n\n _.defaults(this.panel, panelDefaults);\n _.defaults(this.panel.legend, panelDefaults.legend);\n\n this.events.on('render', this.onRender.bind(this));\n this.events.on('data-received', this.onDataReceived.bind(this));\n this.events.on('data-error', this.onDataError.bind(this));\n this.events.on('data-snapshot-load', this.onDataReceived.bind(this));\n this.events.on('init-edit-mode', this.onInitEditMode.bind(this));\n\n this.setLegendWidthForLegacyBrowser();\n }\n\n onInitEditMode() {\n this.addEditorTab('Options', 'public/plugins/grafana-piechart-panel/editor.html', 2);\n this.unitFormats = kbn.getUnitFormats();\n }\n\n setUnitFormat(subItem: any) {\n this.panel.format = subItem.value;\n this.render();\n }\n\n onDataError() {\n this.series = [];\n this.render();\n }\n\n changeSeriesColor(series: any, color: any) {\n series.color = color;\n this.panel.aliasColors[series.alias] = series.color;\n this.render();\n }\n\n onRender() {\n this.data = this.parseSeries(this.series);\n }\n\n parseSeries(series: any) {\n return _.map(this.series, (serie, i) => {\n return {\n label: serie.alias,\n data: serie.stats[this.panel.valueName],\n color: this.panel.aliasColors[serie.alias] || this.$rootScope.colors[i],\n legendData: serie.stats[this.panel.valueName],\n };\n });\n }\n\n onDataReceived(dataList: any) {\n this.series = dataList.map(this.seriesHandler.bind(this));\n this.data = this.parseSeries(this.series);\n this.render(this.data);\n }\n\n seriesHandler(seriesData: any) {\n const series = new TimeSeries({\n datapoints: seriesData.datapoints,\n alias: seriesData.target,\n });\n\n series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);\n return series;\n }\n\n getDecimalsForValue(value: any) {\n if (_.isNumber(this.panel.decimals)) {\n return { decimals: this.panel.decimals, scaledDecimals: null };\n }\n\n const delta = value / 2;\n let dec = -Math.floor(Math.log(delta) / Math.LN10);\n\n const magn = Math.pow(10, -dec);\n const norm = delta / magn; // norm is between 1.0 and 10.0\n let size;\n\n if (norm < 1.5) {\n size = 1;\n } else if (norm < 3) {\n size = 2;\n // special case for 2.5, requires an extra decimal\n if (norm > 2.25) {\n size = 2.5;\n ++dec;\n }\n } else if (norm < 7.5) {\n size = 5;\n } else {\n size = 10;\n }\n\n size *= magn;\n\n // reduce starting decimals if not needed\n if (Math.floor(value) === value) {\n dec = 0;\n }\n\n const result = {\n decimals: 0,\n scaledDecimals: 0,\n };\n result.decimals = Math.max(0, dec);\n result.scaledDecimals = result.decimals - Math.floor(Math.log(size) / Math.LN10) + 2;\n\n return result;\n }\n\n formatValue(value: any) {\n const decimalInfo = this.getDecimalsForValue(value);\n const formatFunc = kbn.valueFormats[this.panel.format];\n if (formatFunc) {\n return formatFunc(value, decimalInfo.decimals, decimalInfo.scaledDecimals);\n }\n return value;\n }\n\n link(scope: any, elem: any, attrs: any, ctrl: any) {\n rendering(scope, elem, attrs, ctrl);\n }\n\n toggleSeries(serie: any) {\n if (this.hiddenSeries[serie.label]) {\n delete this.hiddenSeries[serie.label];\n } else {\n this.hiddenSeries[serie.label] = true;\n }\n this.render();\n }\n\n onLegendTypeChanged() {\n this.setLegendWidthForLegacyBrowser();\n this.render();\n }\n\n setLegendWidthForLegacyBrowser() {\n // @ts-ignore\n const isIE11 = !!window.MSInputMethodContext && !!document.documentMode;\n if (isIE11 && this.panel.legendType === 'Right side' && !this.panel.legend.sideWidth) {\n this.panel.legend.sideWidth = 150;\n }\n }\n}\n\nexport { PieChartCtrl, PieChartCtrl as MetricsPanelCtrl };\n","import { PieChartCtrl } from './piechart_ctrl';\nimport { loadPluginCss } from 'grafana/app/plugins/sdk';\n\nloadPluginCss({\n dark: 'plugins/grafana-piechart-panel/styles/dark.css',\n light: 'plugins/grafana-piechart-panel/styles/light.css',\n});\n\nexport { PieChartCtrl as PanelCtrl };\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/plugin.json b/dist/plugin.json new file mode 100644 index 0000000..1694d1f --- /dev/null +++ b/dist/plugin.json @@ -0,0 +1,69 @@ +{ + "type": "panel", + "name": "Pie Chart", + "id": "grafana-piechart-panel", + "info": { + "description": "Pie chart panel for grafana", + "author": { + "name": "Grafana Labs", + "url": "http://grafana.com" + }, + "keywords": [ + "piechart", + "panel" + ], + "logos": { + "small": "img/piechart_logo_small.svg", + "large": "img/piechart_logo_large.svg" + }, + "links": [ + { + "name": "Project site", + "url": "https://github.com/grafana/piechart-panel" + }, + { + "name": "Blog Post", + "url": "https://blog.raintank.io/friends-dont-let-friends-abuse-pie-charts/" + }, + { + "name": "MIT License", + "url": "https://github.com/grafana/piechart-panel/blob/master/LICENSE" + } + ], + "screenshots": [ + { + "name": "Donut!", + "path": "img/piechart-donut.png" + }, + { + "name": "Legend on the graph", + "path": "img/piechart-legend-on-graph.png" + }, + { + "name": "Legend to the right", + "path": "img/piechart-legend-rhs.png" + }, + { + "name": "Legend underneath", + "path": "img/piechart-legend-under.png" + }, + { + "name": "Piechart options", + "path": "img/piechart-options.png" + } + ], + "version": "1.6.1", + "updated": "2020-09-16", + "build": { + "time": 1600286584067, + "repo": "git@github.com:grafana/piechart-panel.git", + "branch": "v1.6.x", + "hash": "9cc257f74cbb133f6573805e372ed1d79f35896b", + "number": 241 + } + }, + "dependencies": { + "grafanaVersion": "4.6", + "plugins": [] + } +} \ No newline at end of file diff --git a/dist/styles/dark.css b/dist/styles/dark.css new file mode 100644 index 0000000..cb3af06 --- /dev/null +++ b/dist/styles/dark.css @@ -0,0 +1 @@ +.pieLabel>div{color:#fff}.piechart-panel{display:flex;flex-direction:column;height:100%}.piechart-panel--legend-right{flex-direction:row}.piechart-panel--legend-right .piechart-legend{flex:0 1 10px;height:100%}.piechart-panel--legend-right .piechart-legend-series{display:block;padding-left:0}.piechart-panel--legend-right .piechart-legend-table .piechart-legend-series{display:table-row}.piechart-legend__container{height:100%}.piechart-panel__chart{position:relative;cursor:crosshair;flex-grow:1;top:10px}.datapoints-warning{pointer:none;position:absolute;top:50%;left:50%;z-index:10;margin-top:-50px;margin-left:-100px;width:200px;text-align:center;cursor:auto;padding:10px}.piechart-legend{flex:0 1 auto;margin:0 1rem;text-align:center;padding-top:6px;position:relative}.piechart-legend .popover-content{padding:0}.piechart-legend-icon{position:relative;padding-right:4px;top:1px}.piechart-legend-alias,.piechart-legend-icon,.piechart-legend-value{cursor:pointer;float:left;white-space:nowrap;font-size:85%;text-align:left;color:#d8d9da}.piechart-legend-icon.current:before{content:"Current: "}.piechart-legend-icon.max:before{content:"Max: "}.piechart-legend-icon.min:before{content:"Min: "}.piechart-legend-icon.total:before{content:"Total: "}.piechart-legend-icon.avg:before{content:"Avg: "}.piechart-legend-alias.current:before{content:"Current: "}.piechart-legend-alias.max:before{content:"Max: "}.piechart-legend-alias.min:before{content:"Min: "}.piechart-legend-alias.total:before{content:"Total: "}.piechart-legend-alias.avg:before{content:"Avg: "}.piechart-legend-value.current:before{content:"Current: "}.piechart-legend-value.max:before{content:"Max: "}.piechart-legend-value.min:before{content:"Min: "}.piechart-legend-value.total:before{content:"Total: "}.piechart-legend-value.avg:before{content:"Avg: "}.piechart-legend-icon .fa{font-size:135%;position:relative;top:1px}.piechart-legend-series{float:left;white-space:nowrap;padding-left:10px}.piechart-legend-series--right-y{float:right}.piechart-legend-value{padding-left:6px}.piechart-legend-table tbody{display:block;overflow-y:auto;overflow-x:hidden;height:100%;padding-bottom:1px;padding-right:5px}.piechart-legend-table .piechart-legend-series{display:table-row;float:none;padding-left:0}.piechart-legend-table .piechart-legend-series--right-y{float:none}.piechart-legend-table .piechart-legend-series--right-y .piechart-legend-alias:after{content:"(right-y)";padding:0 5px;color:#8e8e8e}.piechart-legend-alias,.piechart-legend-icon,.piechart-legend-table td,.piechart-legend-value{float:none;display:table-cell;white-space:nowrap;padding:2px 10px;text-align:right}.piechart-legend-table .piechart-legend-icon{width:5px;padding:0;top:0}.piechart-legend-table .piechart-legend-icon .fa{top:4px}.piechart-legend-table .piechart-legend-value{padding-left:15px}.piechart-legend-table .piechart-legend-alias{padding-left:7px;text-align:left;width:95%;max-width:650px;text-overflow:ellipsis;overflow:hidden}.piechart-legend-table .piechart-legend-series:nth-child(odd){background:#262628}.piechart-legend-table .piechart-legend-value.avg:before,.piechart-legend-table .piechart-legend-value.current:before,.piechart-legend-table .piechart-legend-value.max:before,.piechart-legend-table .piechart-legend-value.min:before,.piechart-legend-table .piechart-legend-value.total:before{content:""}.piechart-legend-table th{text-align:right;padding:0 10px 1px 0;font-weight:700;color:#33b5e5;font-size:85%;white-space:nowrap}.piechart-legend-series-hidden .piechart-legend-alias,.piechart-legend-series-hidden .piechart-legend-value{color:#8e8e8e}.piechart-tooltip{white-space:nowrap;font-size:12px;background-color:#141414;color:#d8d9da}.piechart-tooltip .piechart-tooltip-time{text-align:center;position:relative;top:-3px;padding:.2rem;font-weight:700;color:#d8d9da}.piechart-tooltip .piechart-tooltip-value{display:table-cell;font-weight:700;padding-left:15px;text-align:right} \ No newline at end of file diff --git a/dist/styles/light.css b/dist/styles/light.css new file mode 100644 index 0000000..175a08f --- /dev/null +++ b/dist/styles/light.css @@ -0,0 +1 @@ +.pieLabel>div{color:#000}.piechart-panel{display:flex;flex-direction:column;height:100%}.piechart-panel--legend-right{flex-direction:row}.piechart-panel--legend-right .piechart-legend{flex:0 1 10px;height:100%}:root .piechart-panel--legend-right .piechart-legend,_:-ms-fullscreen{flex:0 1 200px}.piechart-panel--legend-right .piechart-legend-series{display:block;padding-left:0}.piechart-panel--legend-right .piechart-legend-table .piechart-legend-series{display:table-row}.piechart-legend__container{height:100%}.piechart-panel__chart{position:relative;cursor:crosshair;flex-grow:1;top:10px}.datapoints-warning{pointer:none;position:absolute;top:50%;left:50%;z-index:10;margin-top:-50px;margin-left:-100px;width:200px;text-align:center;cursor:auto;padding:10px}.piechart-legend{flex:0 1 auto;margin:0 1rem;text-align:center;padding-top:6px;position:relative}.piechart-legend .popover-content{padding:0}.piechart-legend-icon{position:relative;padding-right:4px;top:1px}.piechart-legend-alias,.piechart-legend-icon,.piechart-legend-value{cursor:pointer;float:left;white-space:nowrap;font-size:85%;text-align:left;color:52545c}.piechart-legend-icon.current:before{content:"Current: "}.piechart-legend-icon.max:before{content:"Max: "}.piechart-legend-icon.min:before{content:"Min: "}.piechart-legend-icon.total:before{content:"Total: "}.piechart-legend-icon.avg:before{content:"Avg: "}.piechart-legend-alias.current:before{content:"Current: "}.piechart-legend-alias.max:before{content:"Max: "}.piechart-legend-alias.min:before{content:"Min: "}.piechart-legend-alias.total:before{content:"Total: "}.piechart-legend-alias.avg:before{content:"Avg: "}.piechart-legend-value.current:before{content:"Current: "}.piechart-legend-value.max:before{content:"Max: "}.piechart-legend-value.min:before{content:"Min: "}.piechart-legend-value.total:before{content:"Total: "}.piechart-legend-value.avg:before{content:"Avg: "}.piechart-legend-icon .fa{font-size:135%;position:relative;top:1px}.piechart-legend-series{float:left;white-space:nowrap;padding-left:10px}.piechart-legend-series--right-y{float:right}.piechart-legend-value{padding-left:6px}.piechart-legend-table tbody{display:block;overflow-y:auto;overflow-x:hidden;height:100%;padding-bottom:1px;padding-right:5px}.piechart-legend-table .piechart-legend-series{display:table-row;float:none;padding-left:0}.piechart-legend-table .piechart-legend-series--right-y{float:none}.piechart-legend-table .piechart-legend-series--right-y .piechart-legend-alias:after{content:"(right-y)";padding:0 5px;color:#767980}.piechart-legend-alias,.piechart-legend-icon,.piechart-legend-table td,.piechart-legend-value{float:none;display:table-cell;white-space:nowrap;padding:2px 10px;text-align:right}.piechart-legend-table .piechart-legend-icon{width:5px;padding:0;top:0}.piechart-legend-table .piechart-legend-icon .fa{top:4px}.piechart-legend-table .piechart-legend-value{padding-left:15px}.piechart-legend-table .piechart-legend-alias{padding-left:7px;text-align:left;width:95%;max-width:650px;text-overflow:ellipsis;overflow:hidden}.piechart-legend-table .piechart-legend-series:nth-child(odd){background:#dde4ed}.piechart-legend-table .piechart-legend-value.avg:before,.piechart-legend-table .piechart-legend-value.current:before,.piechart-legend-table .piechart-legend-value.max:before,.piechart-legend-table .piechart-legend-value.min:before,.piechart-legend-table .piechart-legend-value.total:before{content:""}.piechart-legend-table th{text-align:right;padding:0 10px 1px 0;font-weight:700;color:#61c2f2;font-size:85%;white-space:nowrap}.piechart-legend-series-hidden .piechart-legend-alias,.piechart-legend-series-hidden .piechart-legend-value{color:#acb6bf}.piechart-tooltip{white-space:nowrap;font-size:12px;background-color:#dde4ed;color:#35373f}.piechart-tooltip .piechart-tooltip-time{text-align:center;position:relative;top:-3px;padding:.2rem;font-weight:700;color:#35373f}.piechart-tooltip .piechart-tooltip-value{display:table-cell;font-weight:700;padding-left:15px;text-align:right} \ No newline at end of file diff --git a/src/legend.ts b/src/legend.ts deleted file mode 100644 index 5b4518a..0000000 --- a/src/legend.ts +++ /dev/null @@ -1,333 +0,0 @@ -import angular from 'angular'; -// @ts-ignore -import $ from 'jquery'; -//import './lib/jquery.flot.pie'; - -//import 'jquery.flot'; - -import './lib/jquery.flot.time'; - -import _ from 'lodash'; - -// @ts-ignore -import PerfectScrollbar from './lib/perfect-scrollbar.min'; - -angular.module('grafana.directives').directive('piechartLegend', (popoverSrv: any, $timeout: any) => { - return { - link: (scope: any, elem: any) => { - const $container = $('
'); - let firstRender = true; - const ctrl = scope.ctrl; - const panel = ctrl.panel; - let data: any; - let seriesList: any; - let dataList: any; - let i; - let legendScrollbar: any; - - scope.$on('$destroy', () => { - if (legendScrollbar) { - legendScrollbar.destroy(); - } - }); - - ctrl.events.on('render', () => { - data = ctrl.series; - if (data) { - for (const i in data) { - data[i].color = ctrl.data[i].color; - } - render(); - } - }); - - function getSeriesIndexForElement(el: any) { - return el.parents('[data-series-index]').data('series-index'); - } - - function toggleSeries(e: any) { - const el = $(e.currentTarget); - // Consider Combine entry as special case (not clickable) - if (el && el.text() !== panel.combine.label) { - const index = getSeriesIndexForElement(el); - const seriesInfo = dataList[index]; - const scrollPosition = $($container.children('tbody')).scrollTop(); - ctrl.toggleSeries(seriesInfo); - if (typeof scrollPosition !== 'undefined') { - $($container.children('tbody')).scrollTop(scrollPosition); - } - } - } - - function sortLegend(e: any) { - const el = $(e.currentTarget); - const stat = el.data('stat'); - - if (stat !== panel.legend.sort) { - panel.legend.sortDesc = null; - } - - // if already sort ascending, disable sorting - if (panel.legend.sortDesc === false) { - panel.legend.sort = null; - panel.legend.sortDesc = null; - ctrl.render(); - return; - } - - panel.legend.sortDesc = !panel.legend.sortDesc; - panel.legend.sort = stat; - ctrl.render(); - } - - function getLegendHeaderHtml(statName: any) { - let name = statName; - - if (panel.legend.header) { - name = panel.legend.header; - } - - let html = '' + _.escape(name); - - if (panel.legend.sort === statName) { - const cssClass = panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up'; - html += ' '; - } - - return html + ''; - } - - function getLegendPercentageHtml(statName: any) { - const name = 'percentage'; - let html = '' + name; - - if (panel.legend.sort === statName) { - const cssClass = panel.legend.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up'; - html += ' '; - } - - return html + ''; - } - - function openColorSelector(e: any) { - // if we clicked inside poup container ignore click - if ($(e.target).parents('.popover').length) { - return; - } - - const el = $(e.currentTarget).find('.fa-minus'); - const index = getSeriesIndexForElement(el); - const series = seriesList[index]; - - $timeout(() => { - popoverSrv.show({ - element: el[0], - position: 'right center', - template: - '' + - '', - openOn: 'hover', - classNames: 'drop-popover drop-popover--transparent', - model: { - autoClose: true, - series: series, - toggleAxis: () => {}, - colorSelected: (color: any) => { - ctrl.changeSeriesColor(series, color); - }, - }, - }); - }); - } - - function render() { - if (panel.legendType === 'On graph' || !panel.legend.show) { - $container.empty(); - elem.find('.piechart-legend').css('padding-top', 0); - return; - } else { - elem.find('.piechart-legend').css('padding-top', 6); - } - - if (firstRender) { - elem.append($container); - $container.on('click', '.piechart-legend-icon', openColorSelector); - $container.on('click', '.piechart-legend-alias', toggleSeries); - $container.on('click', 'th', sortLegend); - firstRender = false; - } - - seriesList = data; - dataList = ctrl.data; - - $container.empty(); - - const width = panel.legendType === 'Right side' && panel.legend.sideWidth ? panel.legend.sideWidth + 'px' : ''; - const ieWidth = - panel.legendType === 'Right side' && panel.legend.sideWidth ? panel.legend.sideWidth - 1 + 'px' : ''; - elem.css('min-width', width); - elem.css('width', ieWidth); - - const showValues = panel.legend.values || panel.legend.percentage; - const tableLayout = (panel.legendType === 'Under graph' || panel.legendType === 'Right side') && showValues; - - $container.toggleClass('piechart-legend-table', tableLayout); - - let legendHeader; - if (tableLayout) { - let header = ''; - if (panel.legend.values) { - header += getLegendHeaderHtml(ctrl.panel.valueName); - } - if (panel.legend.percentage) { - header += getLegendPercentageHtml(ctrl.panel.valueName); - } - header += ''; - legendHeader = $(header); - } - - let total = 0; - if (panel.legend.percentage) { - for (i = 0; i < seriesList.length; i++) { - if (!ctrl.hiddenSeries[seriesList[i].label]) { - total += seriesList[i].stats[ctrl.panel.valueName]; - } - } - } - - let combineNum = 0; - const combineVal = { - label: panel.combine.label, - color: '', - legendData: 0, - }; - const seriesElements = []; - - for (i = 0; i < seriesList.length; i++) { - const series = seriesList[i]; - const seriesData = dataList[i]; - // combine lower values than threshold and not include into legent - if (seriesData.data / total < panel.combine.threshold) { - // Jump hidden series - if (!ctrl.hiddenSeries[seriesData.label]) { - combineNum++; - combineVal.legendData += seriesData.data; - } - } else { - // ignore empty series - if (panel.legend.hideEmpty && series.allIsNull) { - continue; - } - // ignore series excluded via override - if (!series.legend) { - continue; - } - - seriesElements.push($(generateLegendItem(seriesData, i, total, showValues, tableLayout))); - } - } - - // Add combine to legend - if (combineNum > 0) { - // Define color according to hiddenSeries and combineNum - if (typeof panel.legend.sortDesc === 'undefined' || panel.legend.sortDesc === null || panel.legend.sortDesc) { - if (Object.keys(ctrl.hiddenSeries).length > 0) { - let _el, _max; - for (const _key in ctrl.hiddenSeries) { - _el = dataList.find((x: any) => x.label === _key); - if (typeof _max === 'undefined') { - _max = _el.legendData; - combineVal.color = _el.color; - } else { - if (_el.legendData > _max) { - _max = _el.legendData; - combineVal.color = _el.color; - } - } - } - } else { - combineVal.color = seriesList[seriesList.length - combineNum].color; - } - } else { - combineVal.color = seriesList[0].color; - } - - seriesElements.push( - $(generateLegendItem(combineVal, dataList.length - combineNum, total, showValues, tableLayout)) - ); - } - - if (tableLayout) { - // const topPadding = 6; - const tbodyElem = $(''); - // tbodyElem.css("max-height", maxHeight - topPadding); - if (typeof legendHeader !== 'undefined') { - tbodyElem.append(legendHeader); - } - tbodyElem.append(seriesElements); - $container.append(tbodyElem); - } else { - $container.append(seriesElements); - } - - if (panel.legendType === 'Under graph') { - addScrollbar(); - } else { - destroyScrollbar(); - } - } - - function generateLegendItem(data: any, index: any, total: any, showValues: boolean, tableLayout: boolean) { - let html = '
'; - html += ''; - html += ''; - html += ''; - - html += '' + _.escape(data.label) + ''; - let decimal = 0; - if (ctrl.panel.legend.percentageDecimals) { - decimal = ctrl.panel.legend.percentageDecimals; - } - - if (showValues && tableLayout) { - const value = data.legendData; - if (panel.legend.values) { - html += '
' + ctrl.formatValue(value) + '
'; - } - if (total) { - const pvalue = ((value / total) * 100).toFixed(decimal) + '%'; - html += '
' + pvalue + '
'; - } - } - html += '
'; - - return html; - } - - function addScrollbar() { - const scrollbarOptions = { - // Number of pixels the content height can surpass the container height without enabling the scroll bar. - scrollYMarginOffset: 2, - suppressScrollX: true, - }; - - if (!legendScrollbar) { - legendScrollbar = new PerfectScrollbar(elem[0], scrollbarOptions); - } else { - legendScrollbar.update(); - } - } - - function destroyScrollbar() { - if (legendScrollbar) { - legendScrollbar.destroy(); - legendScrollbar = null; - } - } - }, - }; -}); diff --git a/src/lib/jquery.flot.js b/src/lib/jquery.flot.js deleted file mode 100644 index 39f3e4c..0000000 --- a/src/lib/jquery.flot.js +++ /dev/null @@ -1,3168 +0,0 @@ -/* Javascript plotting library for jQuery, version 0.8.3. - -Copyright (c) 2007-2014 IOLA and Ole Laursen. -Licensed under the MIT license. - -*/ - -// first an inline dependency, jquery.colorhelpers.js, we inline it here -// for convenience - -/* 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={};$.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=1){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 valuemax?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()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;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));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]));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);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]));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));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));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{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); - -// the actual Flot code -(function($) { - - // Cache the prototype hasOwnProperty for faster access - - var hasOwnProperty = Object.prototype.hasOwnProperty; - - // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM - // operation produces the same effect as detach, i.e. removing the element - // without touching its jQuery data. - - // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. - - if (!$.fn.detach) { - $.fn.detach = function() { - return this.each(function() { - if (this.parentNode) { - this.parentNode.removeChild( this ); - } - }); - }; - } - - /////////////////////////////////////////////////////////////////////////// - // The Canvas object is a wrapper around an HTML5 tag. - // - // @constructor - // @param {string} cls List of classes to apply to the canvas. - // @param {element} container Element onto which to append the canvas. - // - // Requiring a container is a little iffy, but unfortunately canvas - // operations don't work unless the canvas is attached to the DOM. - - function Canvas(cls, container) { - - var element = container.children("." + cls)[0]; - - if (element == null) { - - element = document.createElement("canvas"); - element.className = cls; - - $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) - .appendTo(container); - - // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas - - if (!element.getContext) { - if (window.G_vmlCanvasManager) { - element = window.G_vmlCanvasManager.initElement(element); - } else { - throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); - } - } - } - - this.element = element; - - var context = this.context = element.getContext("2d"); - - // Determine the screen's ratio of physical to device-independent - // pixels. This is the ratio between the canvas width that the browser - // advertises and the number of pixels actually present in that space. - - // The iPhone 4, for example, has a device-independent width of 320px, - // but its screen is actually 640px wide. It therefore has a pixel - // ratio of 2, while most normal devices have a ratio of 1. - - var devicePixelRatio = window.devicePixelRatio || 1, - backingStoreRatio = - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || 1; - - this.pixelRatio = devicePixelRatio / backingStoreRatio; - - // Size the canvas to match the internal dimensions of its container - - this.resize(container.width(), container.height()); - - // Collection of HTML div layers for text overlaid onto the canvas - - this.textContainer = null; - this.text = {}; - - // Cache of text fragments and metrics, so we can avoid expensively - // re-calculating them when the plot is re-rendered in a loop. - - this._textCache = {}; - } - - // Resizes the canvas to the given dimensions. - // - // @param {number} width New width of the canvas, in pixels. - // @param {number} width New height of the canvas, in pixels. - - Canvas.prototype.resize = function(width, height) { - - if (width <= 0 || height <= 0) { - throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); - } - - var element = this.element, - context = this.context, - pixelRatio = this.pixelRatio; - - // Resize the canvas, increasing its density based on the display's - // pixel ratio; basically giving it more pixels without increasing the - // size of its element, to take advantage of the fact that retina - // displays have that many more pixels in the same advertised space. - - // Resizing should reset the state (excanvas seems to be buggy though) - - if (this.width != width) { - element.width = width * pixelRatio; - element.style.width = width + "px"; - this.width = width; - } - - if (this.height != height) { - element.height = height * pixelRatio; - element.style.height = height + "px"; - this.height = height; - } - - // Save the context, so we can reset in case we get replotted. The - // restore ensure that we're really back at the initial state, and - // should be safe even if we haven't saved the initial state yet. - - context.restore(); - context.save(); - - // Scale the coordinate space to match the display density; so even though we - // may have twice as many pixels, we still want lines and other drawing to - // appear at the same size; the extra pixels will just make them crisper. - - context.scale(pixelRatio, pixelRatio); - }; - - // Clears the entire canvas area, not including any overlaid HTML text - - Canvas.prototype.clear = function() { - this.context.clearRect(0, 0, this.width, this.height); - }; - - // Finishes rendering the canvas, including managing the text overlay. - - Canvas.prototype.render = function() { - - var cache = this._textCache; - - // For each text layer, add elements marked as active that haven't - // already been rendered, and remove those that are no longer active. - - for (var layerKey in cache) { - if (hasOwnProperty.call(cache, layerKey)) { - - var layer = this.getTextLayer(layerKey), - layerCache = cache[layerKey]; - - layer.hide(); - - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - - var positions = styleCache[key].positions; - - for (var i = 0, position; position = positions[i]; i++) { - if (position.active) { - if (!position.rendered) { - layer.append(position.element); - position.rendered = true; - } - } else { - positions.splice(i--, 1); - if (position.rendered) { - position.element.detach(); - } - } - } - - if (positions.length == 0) { - delete styleCache[key]; - } - } - } - } - } - - layer.show(); - } - } - }; - - // Creates (if necessary) and returns the text overlay container. - // - // @param {string} classes String of space-separated CSS classes used to - // uniquely identify the text layer. - // @return {object} The jQuery-wrapped text-layer div. - - Canvas.prototype.getTextLayer = function(classes) { - - var layer = this.text[classes]; - - // Create the text layer if it doesn't exist - - if (layer == null) { - - // Create the text layer container, if it doesn't exist - - if (this.textContainer == null) { - this.textContainer = $("
") - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0, - 'font-size': "smaller", - color: "#545454" - }) - .insertAfter(this.element); - } - - layer = this.text[classes] = $("
") - .addClass(classes) - .css({ - position: "absolute", - top: 0, - left: 0, - bottom: 0, - right: 0 - }) - .appendTo(this.textContainer); - } - - return layer; - }; - - // Creates (if necessary) and returns a text info object. - // - // The object looks like this: - // - // { - // width: Width of the text's wrapper div. - // height: Height of the text's wrapper div. - // element: The jQuery-wrapped HTML div containing the text. - // positions: Array of positions at which this text is drawn. - // } - // - // The positions array contains objects that look like this: - // - // { - // active: Flag indicating whether the text should be visible. - // rendered: Flag indicating whether the text is currently visible. - // element: The jQuery-wrapped HTML div containing the text. - // x: X coordinate at which to draw the text. - // y: Y coordinate at which to draw the text. - // } - // - // Each position after the first receives a clone of the original element. - // - // The idea is that that the width, height, and general 'identity' of the - // text is constant no matter where it is placed; the placements are a - // secondary property. - // - // Canvas maintains a cache of recently-used text info objects; getTextInfo - // either returns the cached element or creates a new entry. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {string} text Text string to retrieve info for. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @return {object} a text info object. - - Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { - - var textStyle, layerCache, styleCache, info; - - // Cast the value to a string, in case we were given a number or such - - text = "" + text; - - // If the font is a font-spec object, generate a CSS font definition - - if (typeof font === "object") { - textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "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 we can't find a matching element in our cache, create a new one - - if (info == null) { - - var element = $("
").html(text) - .css({ - position: "absolute", - 'max-width': width, - top: -9999 - }) - .appendTo(this.getTextLayer(layer)); - - if (typeof font === "object") { - element.css({ - font: textStyle, - color: font.color - }); - } else if (typeof font === "string") { - element.addClass(font); - } - - info = styleCache[text] = { - width: element.outerWidth(true), - height: element.outerHeight(true), - element: element, - positions: [] - }; - - element.detach(); - } - - return info; - }; - - // Adds a text string to the canvas text overlay. - // - // The text isn't drawn immediately; it is marked as rendering, which will - // result in its addition to the canvas on the next render pass. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number} x X coordinate at which to draw the text. - // @param {number} y Y coordinate at which to draw the text. - // @param {string} text Text string to draw. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which to rotate the text, in degrees. - // Angle is currently unused, it will be implemented in the future. - // @param {number=} width Maximum width of the text before it wraps. - // @param {string=} halign Horizontal alignment of the text; either "left", - // "center" or "right". - // @param {string=} valign Vertical alignment of the text; either "top", - // "middle" or "bottom". - - Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { - - var info = this.getTextInfo(layer, text, font, angle, width), - positions = info.positions; - - // Tweak the div's position to match the text's alignment - - if (halign == "center") { - x -= info.width / 2; - } else if (halign == "right") { - x -= info.width; - } - - if (valign == "middle") { - y -= info.height / 2; - } else if (valign == "bottom") { - y -= info.height; - } - - // 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 - - // For the very first position we'll re-use the original element, - // while for subsequent ones we'll clone it. - - position = { - active: true, - rendered: false, - element: positions.length ? info.element.clone() : info.element, - x: x, - y: y - }; - - positions.push(position); - - // Move the element to its final position within the container - - position.element.css({ - top: Math.round(y), - left: Math.round(x), - 'text-align': halign // In case the text wraps - }); - }; - - // Removes one or more text strings from the canvas text overlay. - // - // If no parameters are given, all text within the layer is removed. - // - // Note that the text is not immediately removed; it is simply marked as - // inactive, which will result in its removal on the next render pass. - // This avoids the performance penalty for 'clear and redraw' behavior, - // where we potentially get rid of all text on a layer, but will likely - // add back most or all of it later, as when redrawing axes, for example. - // - // @param {string} layer A string of space-separated CSS classes uniquely - // identifying the layer containing this text. - // @param {number=} x X coordinate of the text. - // @param {number=} y Y coordinate of the text. - // @param {string=} text Text string to remove. - // @param {(string|object)=} font Either a string of space-separated CSS - // classes or a font-spec object, defining the text's font and style. - // @param {number=} angle Angle at which the text is rotated, in degrees. - // Angle is currently unused, it will be implemented in the future. - - Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { - if (text == null) { - var layerCache = this._textCache[layer]; - if (layerCache != null) { - for (var styleKey in layerCache) { - if (hasOwnProperty.call(layerCache, styleKey)) { - var styleCache = layerCache[styleKey]; - for (var key in styleCache) { - if (hasOwnProperty.call(styleCache, key)) { - var positions = styleCache[key].positions; - for (var i = 0, position; position = positions[i]; i++) { - position.active = false; - } - } - } - } - } - } - } else { - var positions = this.getTextInfo(layer, text, font, angle).positions; - for (var i = 0, position; position = positions[i]; i++) { - if (position.x == x && position.y == y) { - position.active = false; - } - } - } - }; - - /////////////////////////////////////////////////////////////////////////// - // The top-level container for the entire plot. - - function Plot(placeholder, data_, options_, plugins) { - // data is on the form: - // [ series1, series2 ... ] - // where series is either just the data as [ [x1, y1], [x2, y2], ... ] - // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } - - var series = [], - options = { - // the color theme used for graphs - colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], - legend: { - show: true, - noColumns: 1, // number of colums in legend table - labelFormatter: null, // fn: string -> string - labelBoxBorderColor: "#ccc", // border color for the little label boxes - container: null, // container (as jQuery object) to put legend in, null means default on top of graph - position: "ne", // position of default legend container within plot - margin: 5, // distance from grid edge to default legend container within plot - backgroundColor: null, // null means auto-detect - backgroundOpacity: 0.85, // set to 0 to avoid background - sorted: null // default to no legend sorting - }, - xaxis: { - show: null, // null = auto-detect, true = always, false = never - position: "bottom", // or "top" - mode: null, // null or "time" - font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } - color: null, // base color, labels, ticks - tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" - transform: null, // null or f: number -> number to transform axis - inverseTransform: null, // if transform is set, this should be the inverse function - min: null, // min. value to show, null means set automatically - max: null, // max. value to show, null means set automatically - autoscaleMargin: null, // margin in % to add if auto-setting min/max - ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks - tickFormatter: null, // fn: number -> string - labelWidth: null, // size of tick labels in pixels - labelHeight: null, - reserveSpace: null, // whether to reserve space even if axis isn't shown - tickLength: null, // size in pixels of ticks, or "full" for whole line - alignTicksWithAxis: null, // axis number or null for no sync - tickDecimals: null, // no. of decimals, null means auto - tickSize: null, // number or [number, "unit"] - minTickSize: null // number or [number, "unit"] - }, - yaxis: { - autoscaleMargin: 0.02, - position: "left" // or "right" - }, - xaxes: [], - yaxes: [], - series: { - points: { - show: false, - radius: 3, - lineWidth: 2, // in pixels - fill: true, - fillColor: "#ffffff", - symbol: "circle" // or callback - }, - lines: { - // we don't put in show: false so we can see - // whether lines were actively disabled - lineWidth: 2, // in pixels - fill: false, - fillColor: null, - steps: false - // Omit 'zero', so we can later default its value to - // match that of the 'fill' option. - }, - bars: { - show: false, - lineWidth: 2, // in pixels - barWidth: 1, // in units of the x axis - fill: true, - fillColor: null, - align: "left", // "left", "right", or "center" - horizontal: false, - zero: true - }, - shadowSize: 3, - highlightColor: null - }, - grid: { - show: true, - aboveData: false, - color: "#545454", // primary color used for outline and labels - backgroundColor: null, // null for transparent, else color - borderColor: null, // set if different from the grid color - tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" - margin: 0, // distance from the canvas edge to the grid - labelMargin: 5, // in pixels - axisMargin: 8, // in pixels - borderWidth: 2, // in pixels - minBorderMargin: null, // in pixels, null means taken from points radius - markings: null, // array of ranges or fn: axes -> array of ranges - markingsColor: "#f4f4f4", - markingsLineWidth: 2, - // interactive stuff - clickable: false, - hoverable: false, - autoHighlight: true, // highlight in case mouse is near - mouseActiveRadius: 10 // how far the mouse can be away to activate an item - }, - interaction: { - redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow - }, - hooks: {} - }, - surface = null, // the canvas for the plot itself - overlay = null, // canvas for interactive stuff on top of plot - eventHolder = null, // jQuery object that events should be bound to - ctx = null, octx = null, - xaxes = [], yaxes = [], - plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, - plotWidth = 0, plotHeight = 0, - hooks = { - processOptions: [], - processRawData: [], - processDatapoints: [], - processOffset: [], - drawBackground: [], - drawSeries: [], - draw: [], - bindEvents: [], - drawOverlay: [], - shutdown: [] - }, - plot = this; - - // public functions - plot.setData = setData; - plot.setupGrid = setupGrid; - plot.draw = draw; - plot.getPlaceholder = function() { return placeholder; }; - plot.getCanvas = function() { return surface.element; }; - plot.getPlotOffset = function() { return plotOffset; }; - plot.width = function () { return plotWidth; }; - plot.height = function () { return plotHeight; }; - plot.offset = function () { - var o = eventHolder.offset(); - o.left += plotOffset.left; - o.top += plotOffset.top; - return o; - }; - plot.getData = function () { return series; }; - plot.getAxes = function () { - var res = {}, i; - $.each(xaxes.concat(yaxes), function (_, axis) { - if (axis) - res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; - }); - return res; - }; - plot.getXAxes = function () { return xaxes; }; - plot.getYAxes = function () { return yaxes; }; - plot.c2p = canvasToAxisCoords; - plot.p2c = axisToCanvasCoords; - plot.getOptions = function () { return options; }; - plot.highlight = highlight; - plot.unhighlight = unhighlight; - plot.triggerRedrawOverlay = triggerRedrawOverlay; - plot.pointOffset = function(point) { - return { - left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), - top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) - }; - }; - plot.shutdown = shutdown; - plot.destroy = function () { - shutdown(); - placeholder.removeData("plot").empty(); - - series = []; - options = null; - surface = null; - overlay = null; - eventHolder = null; - ctx = null; - octx = null; - xaxes = []; - yaxes = []; - hooks = null; - highlights = []; - plot = null; - }; - plot.resize = function () { - var width = placeholder.width(), - height = placeholder.height(); - surface.resize(width, height); - overlay.resize(width, height); - }; - - // public attributes - plot.hooks = hooks; - - // initialize - initPlugins(plot); - parseOptions(options_); - setupCanvases(); - setData(data_); - setupGrid(); - draw(); - bindEvents(); - - - function executeHooks(hook, args) { - args = [plot].concat(args); - for (var i = 0; i < hook.length; ++i) - hook[i].apply(this, args); - } - - function initPlugins() { - - // References to key classes, allowing plugins to modify them - - var classes = { - Canvas: Canvas - }; - - for (var i = 0; i < plugins.length; ++i) { - var p = plugins[i]; - p.init(plot, classes); - if (p.options) - $.extend(true, options, p.options); - } - } - - function parseOptions(opts) { - - $.extend(true, options, opts); - - // $.extend merges arrays, rather than replacing them. When less - // colors are provided than the size of the default palette, we - // end up with those colors plus the remaining defaults, which is - // not expected behavior; avoid it by replacing them here. - - if (opts && opts.colors) { - options.colors = opts.colors; - } - - if (options.xaxis.color == null) - options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - if (options.yaxis.color == null) - options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility - options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; - if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility - options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; - - if (options.grid.borderColor == null) - options.grid.borderColor = options.grid.color; - if (options.grid.tickColor == null) - options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); - - // Fill in defaults for axis options, including any unspecified - // font-spec fields, if a font-spec was provided. - - // If no x/y axis options were provided, create one of each anyway, - // since the rest of the code assumes that they exist. - - var i, axisOptions, axisCount, - fontSize = placeholder.css("font-size"), - fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, - fontDefaults = { - style: placeholder.css("font-style"), - size: Math.round(0.8 * fontSizeDefault), - variant: placeholder.css("font-variant"), - weight: placeholder.css("font-weight"), - family: placeholder.css("font-family") - }; - - axisCount = options.xaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.xaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.xaxis, axisOptions); - options.xaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - if (!axisOptions.font.lineHeight) { - axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); - } - } - } - - axisCount = options.yaxes.length || 1; - for (i = 0; i < axisCount; ++i) { - - axisOptions = options.yaxes[i]; - if (axisOptions && !axisOptions.tickColor) { - axisOptions.tickColor = axisOptions.color; - } - - axisOptions = $.extend(true, {}, options.yaxis, axisOptions); - options.yaxes[i] = axisOptions; - - if (axisOptions.font) { - axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); - if (!axisOptions.font.color) { - axisOptions.font.color = axisOptions.color; - } - if (!axisOptions.font.lineHeight) { - axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); - } - } - } - - // backwards compatibility, to be removed in future - if (options.xaxis.noTicks && options.xaxis.ticks == null) - options.xaxis.ticks = options.xaxis.noTicks; - if (options.yaxis.noTicks && options.yaxis.ticks == null) - options.yaxis.ticks = options.yaxis.noTicks; - if (options.x2axis) { - options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); - options.xaxes[1].position = "top"; - // Override the inherit to allow the axis to auto-scale - if (options.x2axis.min == null) { - options.xaxes[1].min = null; - } - if (options.x2axis.max == null) { - options.xaxes[1].max = null; - } - } - if (options.y2axis) { - options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); - options.yaxes[1].position = "right"; - // Override the inherit to allow the axis to auto-scale - if (options.y2axis.min == null) { - options.yaxes[1].min = null; - } - if (options.y2axis.max == null) { - options.yaxes[1].max = null; - } - } - if (options.grid.coloredAreas) - options.grid.markings = options.grid.coloredAreas; - if (options.grid.coloredAreasColor) - options.grid.markingsColor = options.grid.coloredAreasColor; - if (options.lines) - $.extend(true, options.series.lines, options.lines); - if (options.points) - $.extend(true, options.series.points, options.points); - if (options.bars) - $.extend(true, options.series.bars, options.bars); - if (options.shadowSize != null) - options.series.shadowSize = options.shadowSize; - if (options.highlightColor != null) - options.series.highlightColor = options.highlightColor; - - // save options on axes for future reference - for (i = 0; i < options.xaxes.length; ++i) - getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; - for (i = 0; i < options.yaxes.length; ++i) - getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; - - // add hooks from options - for (var n in hooks) - if (options.hooks[n] && options.hooks[n].length) - hooks[n] = hooks[n].concat(options.hooks[n]); - - executeHooks(hooks.processOptions, [options]); - } - - function setData(d) { - series = parseData(d); - fillInSeriesOptions(); - processData(); - } - - function parseData(d) { - var res = []; - for (var i = 0; i < d.length; ++i) { - var s = $.extend(true, {}, options.series); - - if (d[i].data != null) { - s.data = d[i].data; // move the data instead of deep-copy - delete d[i].data; - - $.extend(true, s, d[i]); - - d[i].data = s.data; - } - else - s.data = d[i]; - res.push(s); - } - - return res; - } - - function axisNumber(obj, coord) { - var a = obj[coord + "axis"]; - if (typeof a == "object") // if we got a real axis, extract number - a = a.n; - if (typeof a != "number") - a = 1; // default to first axis - return a; - } - - function allAxes() { - // return flat array without annoying null entries - return $.grep(xaxes.concat(yaxes), function (a) { return a; }); - } - - function canvasToAxisCoords(pos) { - // return an object with x/y corresponding to all used axes - var res = {}, i, axis; - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) - res["x" + axis.n] = axis.c2p(pos.left); - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) - res["y" + axis.n] = axis.c2p(pos.top); - } - - if (res.x1 !== undefined) - res.x = res.x1; - if (res.y1 !== undefined) - res.y = res.y1; - - return res; - } - - function axisToCanvasCoords(pos) { - // get canvas coords from the first pair of x/y found in pos - var res = {}, i, axis, key; - - for (i = 0; i < xaxes.length; ++i) { - axis = xaxes[i]; - if (axis && axis.used) { - key = "x" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "x"; - - if (pos[key] != null) { - res.left = axis.p2c(pos[key]); - break; - } - } - } - - for (i = 0; i < yaxes.length; ++i) { - axis = yaxes[i]; - if (axis && axis.used) { - key = "y" + axis.n; - if (pos[key] == null && axis.n == 1) - key = "y"; - - if (pos[key] != null) { - res.top = axis.p2c(pos[key]); - break; - } - } - } - - return res; - } - - function getOrCreateAxis(axes, number) { - if (!axes[number - 1]) - axes[number - 1] = { - n: number, // save the number for future reference - direction: axes == xaxes ? "x" : "y", - options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) - }; - - return axes[number - 1]; - } - - function fillInSeriesOptions() { - - var neededColors = series.length, maxIndex = -1, i; - - // Subtract the number of series that already have fixed colors or - // color indexes from the number that we still need to generate. - - for (i = 0; i < series.length; ++i) { - var sc = series[i].color; - if (sc != null) { - neededColors--; - if (typeof sc == "number" && sc > maxIndex) { - maxIndex = sc; - } - } - } - - // If any of the series have fixed color indexes, then we need to - // generate at least as many colors as the highest index. - - if (neededColors <= maxIndex) { - neededColors = maxIndex + 1; - } - - // Generate all the colors, using first the option colors and then - // variations on those colors once they're exhausted. - - var c, colors = [], colorPool = options.colors, - colorPoolSize = colorPool.length, variation = 0; - - for (i = 0; i < neededColors; i++) { - - c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); - - // Each time we exhaust the colors in the pool we adjust - // a scaling factor used to produce more variations on - // those colors. The factor alternates negative/positive - // to produce lighter/darker colors. - - // Reset the variation after every few cycles, or else - // it will end up producing only white or black colors. - - if (i % colorPoolSize == 0 && i) { - if (variation >= 0) { - if (variation < 0.5) { - variation = -variation - 0.2; - } else variation = 0; - } else variation = -variation; - } - - colors[i] = c.scale('rgb', 1 + variation); - } - - // Finalize the series options, filling in their colors - - var colori = 0, s; - for (i = 0; i < series.length; ++i) { - s = series[i]; - - // assign colors - if (s.color == null) { - s.color = colors[colori].toString(); - ++colori; - } - else if (typeof s.color == "number") - s.color = colors[s.color].toString(); - - // turn on lines automatically in case nothing is set - if (s.lines.show == null) { - var v, show = true; - for (v in s) - if (s[v] && s[v].show) { - show = false; - break; - } - if (show) - s.lines.show = true; - } - - // If nothing was provided for lines.zero, default it to match - // lines.fill, since areas by default should extend to zero. - - if (s.lines.zero == null) { - s.lines.zero = !!s.lines.fill; - } - - // setup axes - s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); - s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); - } - } - - function processData() { - var topSentry = Number.POSITIVE_INFINITY, - bottomSentry = Number.NEGATIVE_INFINITY, - fakeInfinity = Number.MAX_VALUE, - i, j, k, m, length, - s, points, ps, x, y, axis, val, f, p, - data, format; - - function updateAxis(axis, min, max) { - if (min < axis.datamin && min != -fakeInfinity) - axis.datamin = min; - if (max > axis.datamax && max != fakeInfinity) - axis.datamax = max; - } - - $.each(allAxes(), function (_, axis) { - // init axis - axis.datamin = topSentry; - axis.datamax = bottomSentry; - axis.used = false; - }); - - for (i = 0; i < series.length; ++i) { - s = series[i]; - s.datapoints = { points: [] }; - - executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); - } - - // first pass: clean and copy data - for (i = 0; i < series.length; ++i) { - s = series[i]; - - data = s.data; - format = s.datapoints.format; - - if (!format) { - format = []; - // find out how to copy - 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; - } - } - - s.datapoints.format = format; - } - - if (s.datapoints.pointsize != null) - continue; // already filled in - - s.datapoints.pointsize = format.length; - - ps = s.datapoints.pointsize; - points = s.datapoints.points; - - var insertSteps = s.lines.show && s.lines.steps; - s.xaxis.used = s.yaxis.used = true; - - for (j = k = 0; j < data.length; ++j, k += ps) { - p = data[j]; - - var nullify = p == null; - if (!nullify) { - for (m = 0; m < ps; ++m) { - val = p[m]; - f = format[m]; - - if (f) { - if (f.number && val != null) { - val = +val; // convert to number - if (isNaN(val)) - val = null; - else if (val == Infinity) - val = fakeInfinity; - else if (val == -Infinity) - val = -fakeInfinity; - } - - if (val == null) { - if (f.required) - nullify = true; - - if (f.defaultValue != null) - val = f.defaultValue; - } - } - - points[k + m] = val; - } - } - - if (nullify) { - for (m = 0; m < ps; ++m) { - val = points[k + m]; - if (val != null) { - f = format[m]; - // extract min/max info - if (f.autoscale !== false) { - if (f.x) { - updateAxis(s.xaxis, val, val); - } - if (f.y) { - updateAxis(s.yaxis, val, val); - } - } - } - points[k + m] = null; - } - } - else { - // a little bit of line specific stuff that - // perhaps shouldn't be here, but lacking - // better means... - if (insertSteps && k > 0 - && points[k - ps] != null - && points[k - ps] != points[k] - && points[k - ps + 1] != points[k + 1]) { - // copy the point to make room for a middle point - for (m = 0; m < ps; ++m) - points[k + ps + m] = points[k + m]; - - // middle point has same y - points[k + 1] = points[k - ps + 1]; - - // we've added a point, better reflect that - k += ps; - } - } - } - } - - // give the hooks a chance to run - for (i = 0; i < series.length; ++i) { - s = series[i]; - - executeHooks(hooks.processDatapoints, [ s, s.datapoints]); - } - - // second pass: find datamax/datamin for auto-scaling - for (i = 0; i < series.length; ++i) { - s = series[i]; - points = s.datapoints.points; - ps = s.datapoints.pointsize; - format = s.datapoints.format; - - var xmin = topSentry, ymin = topSentry, - xmax = bottomSentry, ymax = bottomSentry; - - for (j = 0; j < points.length; j += ps) { - if (points[j] == null) - continue; - - for (m = 0; m < ps; ++m) { - val = points[j + m]; - f = format[m]; - if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) - continue; - - if (f.x) { - if (val < xmin) - xmin = val; - if (val > xmax) - xmax = val; - } - if (f.y) { - if (val < ymin) - ymin = val; - if (val > ymax) - ymax = val; - } - } - } - - if (s.bars.show) { - // make sure we got room for the bar on the dancing floor - var delta; - - switch (s.bars.align) { - case "left": - delta = 0; - break; - case "right": - delta = -s.bars.barWidth; - break; - default: - delta = -s.bars.barWidth / 2; - } - - if (s.bars.horizontal) { - ymin += delta; - ymax += delta + s.bars.barWidth; - } - else { - xmin += delta; - xmax += delta + s.bars.barWidth; - } - } - - updateAxis(s.xaxis, xmin, xmax); - updateAxis(s.yaxis, ymin, ymax); - } - - $.each(allAxes(), function (_, axis) { - if (axis.datamin == topSentry) - axis.datamin = null; - if (axis.datamax == bottomSentry) - axis.datamax = null; - }); - } - - function setupCanvases() { - - // Make sure the placeholder is clear of everything except canvases - // from a previous plot in this container that we'll try to re-use. - - placeholder.css("padding", 0) // padding messes up the positioning - .children().filter(function(){ - return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); - }).remove(); - - if (placeholder.css("position") == 'static') - placeholder.css("position", "relative"); // for positioning labels and overlay - - surface = new Canvas("flot-base", placeholder); - overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features - - ctx = surface.context; - octx = overlay.context; - - // define which element we're listening for events on - eventHolder = $(overlay.element).unbind(); - - // If we're re-using a plot object, shut down the old one - - var existing = placeholder.data("plot"); - - if (existing) { - existing.shutdown(); - overlay.clear(); - } - - // save in case we get replotted - placeholder.data("plot", plot); - } - - function bindEvents() { - // bind events - if (options.grid.hoverable) { - eventHolder.mousemove(onMouseMove); - - // Use bind, rather than .mouseleave, because we officially - // still support jQuery 1.2.6, which doesn't define a shortcut - // for mouseenter or mouseleave. This was a bug/oversight that - // was fixed somewhere around 1.3.x. We can return to using - // .mouseleave when we drop support for 1.2.6. - - eventHolder.bind("mouseleave", onMouseLeave); - } - - if (options.grid.clickable) - eventHolder.click(onClick); - - executeHooks(hooks.bindEvents, [eventHolder]); - } - - function shutdown() { - if (redrawTimeout) - clearTimeout(redrawTimeout); - - eventHolder.unbind("mousemove", onMouseMove); - eventHolder.unbind("mouseleave", onMouseLeave); - eventHolder.unbind("click", onClick); - - executeHooks(hooks.shutdown, [eventHolder]); - } - - function setTransformationHelpers(axis) { - // set helper functions on the axis, assumes plot area - // has been computed already - - function identity(x) { return x; } - - var s, m, t = axis.options.transform || identity, - it = axis.options.inverseTransform; - - // precompute how much the axis is scaling a point - // in canvas space - if (axis.direction == "x") { - s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); - m = Math.min(t(axis.max), t(axis.min)); - } - else { - s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); - s = -s; - m = Math.max(t(axis.max), t(axis.min)); - } - - // data point to canvas coordinate - if (t == identity) // slight optimization - axis.p2c = function (p) { return (p - m) * s; }; - else - axis.p2c = function (p) { return (t(p) - m) * s; }; - // canvas coordinate to data point - if (!it) - axis.c2p = function (c) { return m + c / s; }; - else - axis.c2p = function (c) { return it(m + c / s); }; - } - - function measureTickLabels(axis) { - - var opts = axis.options, - ticks = axis.ticks || [], - labelWidth = opts.labelWidth || 0, - labelHeight = opts.labelHeight || 0, - maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = opts.font || "flot-tick-label tickLabel"; - - for (var i = 0; i < ticks.length; ++i) { - - var t = ticks[i]; - - if (!t.label) - continue; - - var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); - - labelWidth = Math.max(labelWidth, info.width); - labelHeight = Math.max(labelHeight, info.height); - } - - axis.labelWidth = opts.labelWidth || labelWidth; - axis.labelHeight = opts.labelHeight || labelHeight; - } - - function allocateAxisBoxFirstPhase(axis) { - // find the bounding box of the axis by looking at label - // widths/heights and ticks, make room by diminishing the - // plotOffset; this first phase only looks at one - // dimension per axis, the other dimension depends on the - // other axes so will have to wait - - var lw = axis.labelWidth, - lh = axis.labelHeight, - pos = axis.options.position, - isXAxis = axis.direction === "x", - tickLength = axis.options.tickLength, - axisMargin = options.grid.axisMargin, - padding = options.grid.labelMargin, - innermost = true, - outermost = true, - first = true, - found = false; - - // Determine the axis's position in its direction and on its side - - $.each(isXAxis ? xaxes : yaxes, function(i, a) { - if (a && (a.show || a.reserveSpace)) { - if (a === axis) { - found = true; - } else if (a.options.position === pos) { - if (found) { - outermost = false; - } else { - innermost = false; - } - } - if (!found) { - first = false; - } - } - }); - - // The outermost axis on each side has no margin - - if (outermost) { - axisMargin = 0; - } - - // The ticks for the first axis in each direction stretch across - - if (tickLength == null) { - tickLength = first ? "full" : 5; - } - - if (!isNaN(+tickLength)) - padding += +tickLength; - - if (isXAxis) { - lh += padding; - - if (pos == "bottom") { - plotOffset.bottom += lh + axisMargin; - axis.box = { top: surface.height - plotOffset.bottom, height: lh }; - } - else { - axis.box = { top: plotOffset.top + axisMargin, height: lh }; - plotOffset.top += lh + axisMargin; - } - } - else { - lw += padding; - - if (pos == "left") { - axis.box = { left: plotOffset.left + axisMargin, width: lw }; - plotOffset.left += lw + axisMargin; - } - else { - plotOffset.right += lw + axisMargin; - axis.box = { left: surface.width - plotOffset.right, width: lw }; - } - } - - // save for future reference - axis.position = pos; - axis.tickLength = tickLength; - axis.box.padding = padding; - axis.innermost = innermost; - } - - function allocateAxisBoxSecondPhase(axis) { - // now that all axis boxes have been placed in one - // dimension, we can set the remaining dimension coordinates - if (axis.direction == "x") { - axis.box.left = plotOffset.left - axis.labelWidth / 2; - axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; - } - else { - axis.box.top = plotOffset.top - axis.labelHeight / 2; - axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; - } - } - - function adjustLayoutForThingsStickingOut() { - // possibly adjust plot offset to ensure everything stays - // inside the canvas and isn't clipped off - - var minMargin = options.grid.minBorderMargin, - axis, i; - - // check stuff from the plot (FIXME: this should just read - // a value from the series, otherwise it's impossible to - // customize) - if (minMargin == null) { - minMargin = 0; - for (i = 0; i < series.length; ++i) - minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); - } - - var margins = { - left: minMargin, - right: minMargin, - top: minMargin, - bottom: minMargin - }; - - // check axis labels, note we don't check the actual - // labels but instead use the overall width/height to not - // jump as much around with replots - $.each(allAxes(), function (_, axis) { - if (axis.reserveSpace && axis.ticks && axis.ticks.length) { - if (axis.direction === "x") { - margins.left = Math.max(margins.left, axis.labelWidth / 2); - margins.right = Math.max(margins.right, axis.labelWidth / 2); - } else { - margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); - margins.top = Math.max(margins.top, axis.labelHeight / 2); - } - } - }); - - plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); - plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); - plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); - plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); - } - - function setupGrid() { - var i, axes = allAxes(), showGrid = options.grid.show; - - // Initialize the plot's offset from the edge of the canvas - - for (var a in plotOffset) { - var margin = options.grid.margin || 0; - plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; - } - - executeHooks(hooks.processOffset, [plotOffset]); - - // If the grid is visible, add its border width to the offset - - for (var a in plotOffset) { - if(typeof(options.grid.borderWidth) == "object") { - plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; - } - else { - plotOffset[a] += showGrid ? options.grid.borderWidth : 0; - } - } - - $.each(axes, function (_, axis) { - var axisOpts = axis.options; - axis.show = axisOpts.show == null ? axis.used : axisOpts.show; - axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace; - setRange(axis); - }); - - if (showGrid) { - - var allocatedAxes = $.grep(axes, function (axis) { - return axis.show || axis.reserveSpace; - }); - - $.each(allocatedAxes, function (_, axis) { - // make the ticks - setupTickGeneration(axis); - setTicks(axis); - snapRangeToTicks(axis, axis.ticks); - // find labelWidth/Height for axis - measureTickLabels(axis); - }); - - // with all dimensions calculated, we can compute the - // axis bounding boxes, start from the outside - // (reverse order) - for (i = allocatedAxes.length - 1; i >= 0; --i) - allocateAxisBoxFirstPhase(allocatedAxes[i]); - - // make sure we've got enough space for things that - // might stick out - adjustLayoutForThingsStickingOut(); - - $.each(allocatedAxes, function (_, axis) { - allocateAxisBoxSecondPhase(axis); - }); - } - - plotWidth = surface.width - plotOffset.left - plotOffset.right; - plotHeight = surface.height - plotOffset.bottom - plotOffset.top; - - // now we got the proper plot dimensions, we can compute the scaling - $.each(axes, function (_, axis) { - setTransformationHelpers(axis); - }); - - if (showGrid) { - drawAxisLabels(); - } - - insertLegend(); - } - - function setRange(axis) { - var opts = axis.options, - min = +(opts.min != null ? opts.min : axis.datamin), - max = +(opts.max != null ? opts.max : axis.datamax), - delta = max - min; - - if (delta == 0.0) { - // degenerate case - var widen = max == 0 ? 1 : 0.01; - - if (opts.min == null) - min -= widen; - // always widen max if we couldn't widen min to ensure we - // don't fall into min == max which doesn't work - if (opts.max == null || opts.min != null) - max += widen; - } - else { - // consider autoscaling - var margin = opts.autoscaleMargin; - if (margin != null) { - if (opts.min == null) { - min -= delta * margin; - // make sure we don't go below zero if all values - // are positive - if (min < 0 && axis.datamin != null && axis.datamin >= 0) - min = 0; - } - if (opts.max == null) { - max += delta * margin; - if (max > 0 && axis.datamax != null && axis.datamax <= 0) - max = 0; - } - } - } - axis.min = min; - axis.max = max; - } - - function setupTickGeneration(axis) { - var opts = axis.options; - - // estimate number of ticks - var noTicks; - if (typeof opts.ticks == "number" && opts.ticks > 0) - noTicks = opts.ticks; - else - // heuristic based on the model a*sqrt(x) fitted to - // some data points that seemed reasonable - noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); - - var delta = (axis.max - axis.min) / noTicks, - dec = -Math.floor(Math.log(delta) / Math.LN10), - maxDec = opts.tickDecimals; - - if (maxDec != null && dec > maxDec) { - dec = maxDec; - } - - var magn = Math.pow(10, -dec), - norm = delta / magn, // norm is between 1.0 and 10.0 - size; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - // special case for 2.5, requires an extra decimal - if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { - size = 2.5; - ++dec; - } - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - - if (opts.minTickSize != null && size < opts.minTickSize) { - size = opts.minTickSize; - } - - axis.delta = delta; - axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); - axis.tickSize = opts.tickSize || size; - - // Time mode was moved to a plug-in in 0.8, and since so many people use it - // we'll add an especially friendly reminder to make sure they included it. - - if (opts.mode == "time" && !axis.tickGenerator) { - throw new Error("Time mode requires the flot.time plugin."); - } - - // Flot supports base-10 axes; any other mode else is handled by a plug-in, - // like flot.time.js. - - if (!axis.tickGenerator) { - - axis.tickGenerator = function (axis) { - - var ticks = [], - start = floorInBase(axis.min, axis.tickSize), - i = 0, - v = Number.NaN, - prev; - - do { - prev = v; - v = start + i * axis.tickSize; - ticks.push(v); - ++i; - } while (v < axis.max && v != prev); - return ticks; - }; - - axis.tickFormatter = function (value, axis) { - - var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; - var formatted = "" + Math.round(value * factor) / factor; - - // If tickDecimals was specified, ensure that we have exactly that - // much precision; otherwise default to the value's own precision. - - if (axis.tickDecimals != null) { - var decimal = formatted.indexOf("."); - var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; - if (precision < axis.tickDecimals) { - return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); - } - } - - return formatted; - }; - } - - if ($.isFunction(opts.tickFormatter)) - axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; - - if (opts.alignTicksWithAxis != null) { - var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; - if (otherAxis && otherAxis.used && otherAxis != axis) { - // consider snapping min/max to outermost nice ticks - var niceTicks = axis.tickGenerator(axis); - if (niceTicks.length > 0) { - if (opts.min == null) - axis.min = Math.min(axis.min, niceTicks[0]); - if (opts.max == null && niceTicks.length > 1) - axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); - } - - axis.tickGenerator = function (axis) { - // copy ticks, scaled to this axis - var ticks = [], v, i; - for (i = 0; i < otherAxis.ticks.length; ++i) { - v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); - v = axis.min + v * (axis.max - axis.min); - ticks.push(v); - } - return ticks; - }; - - // we might need an extra decimal since forced - // ticks don't necessarily fit naturally - if (!axis.mode && opts.tickDecimals == null) { - var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), - ts = axis.tickGenerator(axis); - - // only proceed if the tick interval rounded - // with an extra decimal doesn't give us a - // zero at end - if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) - axis.tickDecimals = extraDec; - } - } - } - } - - function setTicks(axis) { - var oticks = axis.options.ticks, ticks = []; - if (oticks == null || (typeof oticks == "number" && oticks > 0)) - ticks = axis.tickGenerator(axis); - else if (oticks) { - if ($.isFunction(oticks)) - // generate the ticks - ticks = oticks(axis); - else - ticks = oticks; - } - - // clean up/labelify the supplied ticks, copy them over - var i, v; - axis.ticks = []; - for (i = 0; i < ticks.length; ++i) { - var label = null; - var t = ticks[i]; - if (typeof t == "object") { - v = +t[0]; - if (t.length > 1) - label = t[1]; - } - else - v = +t; - if (label == null) - label = axis.tickFormatter(v, axis); - if (!isNaN(v)) - axis.ticks.push({ v: v, label: label }); - } - } - - function snapRangeToTicks(axis, ticks) { - if (axis.options.autoscaleMargin && ticks.length > 0) { - // snap to ticks - if (axis.options.min == null) - axis.min = Math.min(axis.min, ticks[0].v); - if (axis.options.max == null && ticks.length > 1) - axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); - } - } - - function draw() { - - surface.clear(); - - executeHooks(hooks.drawBackground, [ctx]); - - var grid = options.grid; - - // draw background, if any - if (grid.show && grid.backgroundColor) - drawBackground(); - - if (grid.show && !grid.aboveData) { - drawGrid(); - } - - for (var i = 0; i < series.length; ++i) { - executeHooks(hooks.drawSeries, [ctx, series[i]]); - drawSeries(series[i]); - } - - executeHooks(hooks.draw, [ctx]); - - if (grid.show && grid.aboveData) { - drawGrid(); - } - - surface.render(); - - // A draw implies that either the axes or data have changed, so we - // should probably update the overlay highlights as well. - - triggerRedrawOverlay(); - } - - function extractRange(ranges, coord) { - var axis, from, to, key, axes = allAxes(); - - for (var i = 0; i < axes.length; ++i) { - axis = axes[i]; - 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" ? xaxes[0] : yaxes[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 drawBackground() { - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); - ctx.fillRect(0, 0, plotWidth, plotHeight); - ctx.restore(); - } - - function drawGrid() { - var i, axes, bw, bc; - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // draw markings - var markings = options.grid.markings; - if (markings) { - if ($.isFunction(markings)) { - axes = plot.getAxes(); - // xmin etc. is backwards compatibility, to be - // removed in the future - axes.xmin = axes.xaxis.min; - axes.xmax = axes.xaxis.max; - axes.ymin = axes.yaxis.min; - axes.ymax = axes.yaxis.max; - - markings = markings(axes); - } - - for (i = 0; i < markings.length; ++i) { - var m = markings[i], - xrange = extractRange(m, "x"), - yrange = extractRange(m, "y"); - - // fill in missing - if (xrange.from == null) - xrange.from = xrange.axis.min; - if (xrange.to == null) - xrange.to = xrange.axis.max; - if (yrange.from == null) - yrange.from = yrange.axis.min; - if (yrange.to == null) - yrange.to = yrange.axis.max; - - // clip - if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || - yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) - continue; - - xrange.from = Math.max(xrange.from, xrange.axis.min); - xrange.to = Math.min(xrange.to, xrange.axis.max); - yrange.from = Math.max(yrange.from, yrange.axis.min); - yrange.to = Math.min(yrange.to, yrange.axis.max); - - var xequal = xrange.from === xrange.to, - yequal = yrange.from === yrange.to; - - if (xequal && yequal) { - continue; - } - - // then draw - xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); - xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); - yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); - yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); - - if (xequal || yequal) { - var lineWidth = m.lineWidth || options.grid.markingsLineWidth, - subPixel = lineWidth % 2 ? 0.5 : 0; - ctx.beginPath(); - ctx.strokeStyle = m.color || options.grid.markingsColor; - ctx.lineWidth = lineWidth; - if (xequal) { - ctx.moveTo(xrange.to + subPixel, yrange.from); - ctx.lineTo(xrange.to + subPixel, yrange.to); - } else { - ctx.moveTo(xrange.from, yrange.to + subPixel); - ctx.lineTo(xrange.to, yrange.to + subPixel); - } - ctx.stroke(); - } else { - ctx.fillStyle = m.color || options.grid.markingsColor; - ctx.fillRect(xrange.from, yrange.to, - xrange.to - xrange.from, - yrange.from - yrange.to); - } - } - } - - // draw the ticks - axes = allAxes(); - bw = options.grid.borderWidth; - - for (var j = 0; j < axes.length; ++j) { - var axis = axes[j], box = axis.box, - t = axis.tickLength, x, y, xoff, yoff; - if (!axis.show || axis.ticks.length == 0) - continue; - - ctx.lineWidth = 1; - - // find the edges - if (axis.direction == "x") { - x = 0; - if (t == "full") - y = (axis.position == "top" ? 0 : plotHeight); - else - y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); - } - else { - y = 0; - if (t == "full") - x = (axis.position == "left" ? 0 : plotWidth); - else - x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); - } - - // draw tick bar - if (!axis.innermost) { - ctx.strokeStyle = axis.options.color; - ctx.beginPath(); - xoff = yoff = 0; - if (axis.direction == "x") - xoff = plotWidth + 1; - else - yoff = plotHeight + 1; - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") { - y = Math.floor(y) + 0.5; - } else { - x = Math.floor(x) + 0.5; - } - } - - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - ctx.stroke(); - } - - // draw ticks - - ctx.strokeStyle = axis.options.tickColor; - - ctx.beginPath(); - for (i = 0; i < axis.ticks.length; ++i) { - var v = axis.ticks[i].v; - - xoff = yoff = 0; - - if (isNaN(v) || v < axis.min || v > axis.max - // skip those lying on the axes if we got a border - || (t == "full" - && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) - && (v == axis.min || v == axis.max))) - continue; - - if (axis.direction == "x") { - x = axis.p2c(v); - yoff = t == "full" ? -plotHeight : t; - - if (axis.position == "top") - yoff = -yoff; - } - else { - y = axis.p2c(v); - xoff = t == "full" ? -plotWidth : t; - - if (axis.position == "left") - xoff = -xoff; - } - - if (ctx.lineWidth == 1) { - if (axis.direction == "x") - x = Math.floor(x) + 0.5; - else - y = Math.floor(y) + 0.5; - } - - ctx.moveTo(x, y); - ctx.lineTo(x + xoff, y + yoff); - } - - ctx.stroke(); - } - - - // draw border - if (bw) { - // If either borderWidth or borderColor is an object, then draw the border - // line by line instead of as one rectangle - bc = options.grid.borderColor; - if(typeof bw == "object" || typeof bc == "object") { - if (typeof bw !== "object") { - bw = {top: bw, right: bw, bottom: bw, left: bw}; - } - if (typeof bc !== "object") { - bc = {top: bc, right: bc, bottom: bc, left: bc}; - } - - if (bw.top > 0) { - ctx.strokeStyle = bc.top; - ctx.lineWidth = bw.top; - ctx.beginPath(); - ctx.moveTo(0 - bw.left, 0 - bw.top/2); - ctx.lineTo(plotWidth, 0 - bw.top/2); - ctx.stroke(); - } - - if (bw.right > 0) { - ctx.strokeStyle = bc.right; - ctx.lineWidth = bw.right; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); - ctx.lineTo(plotWidth + bw.right / 2, plotHeight); - ctx.stroke(); - } - - if (bw.bottom > 0) { - ctx.strokeStyle = bc.bottom; - ctx.lineWidth = bw.bottom; - ctx.beginPath(); - ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); - ctx.lineTo(0, plotHeight + bw.bottom / 2); - ctx.stroke(); - } - - if (bw.left > 0) { - ctx.strokeStyle = bc.left; - ctx.lineWidth = bw.left; - ctx.beginPath(); - ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); - ctx.lineTo(0- bw.left/2, 0); - ctx.stroke(); - } - } - else { - ctx.lineWidth = bw; - ctx.strokeStyle = options.grid.borderColor; - ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); - } - } - - ctx.restore(); - } - - function drawAxisLabels() { - - $.each(allAxes(), function (_, axis) { - var box = axis.box, - legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", - layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, - font = axis.options.font || "flot-tick-label tickLabel", - tick, x, y, halign, valign; - - // Remove text before checking for axis.show and ticks.length; - // otherwise plugins, like flot-tickrotor, that draw their own - // tick labels will end up with both theirs and the defaults. - - surface.removeText(layer); - - if (!axis.show || axis.ticks.length == 0) - return; - - for (var i = 0; i < axis.ticks.length; ++i) { - - tick = axis.ticks[i]; - if (!tick.label || tick.v < axis.min || tick.v > axis.max) - continue; - - if (axis.direction == "x") { - halign = "center"; - x = plotOffset.left + axis.p2c(tick.v); - if (axis.position == "bottom") { - y = box.top + box.padding; - } else { - y = box.top + box.height - box.padding; - valign = "bottom"; - } - } else { - valign = "middle"; - y = plotOffset.top + axis.p2c(tick.v); - if (axis.position == "left") { - x = box.left + box.width - box.padding; - halign = "right"; - } else { - x = box.left + box.padding; - } - } - - surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); - } - }); - } - - function drawSeries(series) { - if (series.lines.show) - drawSeriesLines(series); - if (series.bars.show) - drawSeriesBars(series); - if (series.points.show) - drawSeriesPoints(series); - } - - function drawSeriesLines(series) { - function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { - var points = datapoints.points, - ps = datapoints.pointsize, - prevx = null, prevy = null; - - ctx.beginPath(); - for (var i = ps; i < points.length; i += ps) { - var x1 = points[i - ps], y1 = points[i - ps + 1], - x2 = points[i], y2 = points[i + 1]; - - if (x1 == null || x2 == null) - continue; - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min) { - if (y2 < axisy.min) - continue; // line segment is outside - // compute new intersection point - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min) { - if (y1 < axisy.min) - continue; - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max) { - if (y2 > axisy.max) - continue; - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max) { - if (y1 > axisy.max) - continue; - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (x1 != prevx || y1 != prevy) - ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); - - prevx = x2; - prevy = y2; - ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); - } - ctx.stroke(); - } - - function plotLineArea(datapoints, axisx, axisy) { - var points = datapoints.points, - ps = datapoints.pointsize, - bottom = Math.min(Math.max(0, axisy.min), axisy.max), - i = 0, top, areaOpen = false, - ypos = 1, segmentStart = 0, segmentEnd = 0; - - // we process each segment in two turns, first forward - // direction to sketch out top, then once we hit the - // end we go backwards to sketch the bottom - while (true) { - if (ps > 0 && i > points.length + ps) - break; - - i += ps; // ps is negative if going backwards - - var x1 = points[i - ps], - y1 = points[i - ps + ypos], - x2 = points[i], y2 = points[i + ypos]; - - if (areaOpen) { - if (ps > 0 && x1 != null && x2 == null) { - // at turning point - segmentEnd = i; - ps = -ps; - ypos = 2; - continue; - } - - if (ps < 0 && i == segmentStart + ps) { - // done with the reverse sweep - ctx.fill(); - areaOpen = false; - ps = -ps; - ypos = 1; - i = segmentStart = segmentEnd + ps; - continue; - } - } - - if (x1 == null || x2 == null) - continue; - - // clip x values - - // clip with xmin - if (x1 <= x2 && x1 < axisx.min) { - if (x2 < axisx.min) - continue; - y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.min; - } - else if (x2 <= x1 && x2 < axisx.min) { - if (x1 < axisx.min) - continue; - y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.min; - } - - // clip with xmax - if (x1 >= x2 && x1 > axisx.max) { - if (x2 > axisx.max) - continue; - y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x1 = axisx.max; - } - else if (x2 >= x1 && x2 > axisx.max) { - if (x1 > axisx.max) - continue; - y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; - x2 = axisx.max; - } - - if (!areaOpen) { - // open area - ctx.beginPath(); - ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); - areaOpen = true; - } - - // now first check the case where both is outside - if (y1 >= axisy.max && y2 >= axisy.max) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); - continue; - } - else if (y1 <= axisy.min && y2 <= axisy.min) { - ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); - continue; - } - - // else it's a bit more complicated, there might - // be a flat maxed out rectangle first, then a - // triangular cutout or reverse; to find these - // keep track of the current x values - var x1old = x1, x2old = x2; - - // clip the y values, without shortcutting, we - // go through all cases in turn - - // clip with ymin - if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { - x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.min; - } - else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { - x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.min; - } - - // clip with ymax - if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { - x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y1 = axisy.max; - } - else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { - x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; - y2 = axisy.max; - } - - // if the x value was changed we got a rectangle - // to fill - if (x1 != x1old) { - ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); - // it goes to (x1, y1), but we fill that below - } - - // fill triangular section, this sometimes result - // in redundant points if (x1, y1) hasn't changed - // from previous line to, but we just ignore that - ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - - // fill the other rectangle if it's there - if (x2 != x2old) { - ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); - ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); - } - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - ctx.lineJoin = "round"; - - var lw = series.lines.lineWidth, - sw = series.shadowSize; - // FIXME: consider another form of shadow when filling is turned on - if (lw > 0 && sw > 0) { - // draw shadow as a thick and thin line with transparency - ctx.lineWidth = sw; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - // position shadow at angle from the mid of line - var angle = Math.PI/18; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); - ctx.lineWidth = sw/2; - plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); - if (fillStyle) { - ctx.fillStyle = fillStyle; - plotLineArea(series.datapoints, series.xaxis, series.yaxis); - } - - if (lw > 0) - plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); - ctx.restore(); - } - - function drawSeriesPoints(series) { - function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - var x = points[i], y = points[i + 1]; - if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - continue; - - ctx.beginPath(); - x = axisx.p2c(x); - y = axisy.p2c(y) + offset; - if (symbol == "circle") - ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); - else - symbol(ctx, x, y, radius, shadow); - ctx.closePath(); - - if (fillStyle) { - ctx.fillStyle = fillStyle; - ctx.fill(); - } - ctx.stroke(); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - var lw = series.points.lineWidth, - sw = series.shadowSize, - radius = series.points.radius, - symbol = series.points.symbol; - - // If the user sets the line width to 0, we change it to a very - // small value. A line width of 0 seems to force the default of 1. - // Doing the conditional here allows the shadow setting to still be - // optional even with a lineWidth of 0. - - if( lw == 0 ) - lw = 0.0001; - - if (lw > 0 && sw > 0) { - // draw shadow in two steps - var w = sw / 2; - ctx.lineWidth = w; - ctx.strokeStyle = "rgba(0,0,0,0.1)"; - plotPoints(series.datapoints, radius, null, w + w/2, true, - series.xaxis, series.yaxis, symbol); - - ctx.strokeStyle = "rgba(0,0,0,0.2)"; - plotPoints(series.datapoints, radius, null, w/2, true, - series.xaxis, series.yaxis, symbol); - } - - ctx.lineWidth = lw; - ctx.strokeStyle = series.color; - plotPoints(series.datapoints, radius, - getFillStyle(series.points, series.color), 0, false, - series.xaxis, series.yaxis, symbol); - ctx.restore(); - } - - function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { - var left, right, bottom, top, - drawLeft, drawRight, drawTop, drawBottom, - tmp; - - // in horizontal mode, we start the bar from the left - // instead of from the bottom so it appears to be - // horizontal rather than vertical - if (horizontal) { - drawBottom = drawRight = drawTop = true; - drawLeft = false; - left = b; - right = x; - top = y + barLeft; - bottom = y + barRight; - - // account for negative bars - if (right < left) { - tmp = right; - right = left; - left = tmp; - drawLeft = true; - drawRight = false; - } - } - else { - drawLeft = drawRight = drawTop = true; - drawBottom = false; - left = x + barLeft; - right = x + barRight; - bottom = b; - top = y; - - // account for negative bars - if (top < bottom) { - tmp = top; - top = bottom; - bottom = tmp; - drawBottom = true; - drawTop = false; - } - } - - // clip - if (right < axisx.min || left > axisx.max || - top < axisy.min || bottom > axisy.max) - return; - - if (left < axisx.min) { - left = axisx.min; - drawLeft = false; - } - - if (right > axisx.max) { - right = axisx.max; - drawRight = false; - } - - if (bottom < axisy.min) { - bottom = axisy.min; - drawBottom = false; - } - - if (top > axisy.max) { - top = axisy.max; - drawTop = false; - } - - left = axisx.p2c(left); - bottom = axisy.p2c(bottom); - right = axisx.p2c(right); - top = axisy.p2c(top); - - // fill the bar - if (fillStyleCallback) { - c.fillStyle = fillStyleCallback(bottom, top); - c.fillRect(left, top, right - left, bottom - top) - } - - // draw outline - if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { - c.beginPath(); - - // FIXME: inline moveTo is buggy with excanvas - c.moveTo(left, bottom); - if (drawLeft) - c.lineTo(left, top); - else - c.moveTo(left, top); - if (drawTop) - c.lineTo(right, top); - else - c.moveTo(right, top); - if (drawRight) - c.lineTo(right, bottom); - else - c.moveTo(right, bottom); - if (drawBottom) - c.lineTo(left, bottom); - else - c.moveTo(left, bottom); - c.stroke(); - } - } - - function drawSeriesBars(series) { - function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { - var points = datapoints.points, ps = datapoints.pointsize; - - for (var i = 0; i < points.length; i += ps) { - if (points[i] == null) - continue; - drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); - } - } - - ctx.save(); - ctx.translate(plotOffset.left, plotOffset.top); - - // FIXME: figure out a way to add shadows (for instance along the right edge) - ctx.lineWidth = series.bars.lineWidth; - ctx.strokeStyle = series.color; - - var barLeft; - - switch (series.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -series.bars.barWidth; - break; - default: - barLeft = -series.bars.barWidth / 2; - } - - var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; - plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); - ctx.restore(); - } - - function getFillStyle(filloptions, seriesColor, bottom, top) { - var fill = filloptions.fill; - if (!fill) - return null; - - if (filloptions.fillColor) - return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); - - var c = $.color.parse(seriesColor); - c.a = typeof fill == "number" ? fill : 0.4; - c.normalize(); - return c.toString(); - } - - function insertLegend() { - - if (options.legend.container != null) { - $(options.legend.container).html(""); - } else { - placeholder.find(".legend").remove(); - } - - if (!options.legend.show) { - return; - } - - var fragments = [], entries = [], rowStarted = false, - lf = options.legend.labelFormatter, s, label; - - // Build a list of legend entries, with each having a label and a color - - for (var i = 0; i < series.length; ++i) { - s = series[i]; - if (s.label) { - label = lf ? lf(s.label, s) : s.label; - if (label) { - entries.push({ - label: label, - color: s.color - }); - } - } - } - - // Sort the legend using either the default or a custom comparator - - if (options.legend.sorted) { - if ($.isFunction(options.legend.sorted)) { - entries.sort(options.legend.sorted); - } else if (options.legend.sorted == "reverse") { - entries.reverse(); - } else { - var ascending = options.legend.sorted != "descending"; - entries.sort(function(a, b) { - return a.label == b.label ? 0 : ( - (a.label < b.label) != ascending ? 1 : -1 // Logical XOR - ); - }); - } - } - - // Generate markup for the list of entries, in their final order - - for (var i = 0; i < entries.length; ++i) { - - var entry = entries[i]; - - if (i % options.legend.noColumns == 0) { - if (rowStarted) - fragments.push(''); - fragments.push(''); - rowStarted = true; - } - - fragments.push( - '
' + - '' + entry.label + '' - ); - } - - if (rowStarted) - fragments.push(''); - - if (fragments.length == 0) - return; - - var table = '' + fragments.join("") + '
'; - if (options.legend.container != null) - $(options.legend.container).html(table); - else { - var pos = "", - p = options.legend.position, - m = options.legend.margin; - if (m[0] == null) - m = [m, m]; - if (p.charAt(0) == "n") - pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; - else if (p.charAt(0) == "s") - pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; - if (p.charAt(1) == "e") - pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; - else if (p.charAt(1) == "w") - pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; - var legend = $('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(placeholder); - if (options.legend.backgroundOpacity != 0.0) { - // put in the transparent background - // separately to avoid blended labels and - // label boxes - var c = options.legend.backgroundColor; - if (c == null) { - c = options.grid.backgroundColor; - if (c && typeof c == "string") - c = $.color.parse(c); - else - c = $.color.extract(legend, 'background-color'); - c.a = 1; - c = c.toString(); - } - var div = legend.children(); - $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity); - } - } - } - - - // interactive features - - var highlights = [], - redrawTimeout = null; - - // returns the data item the mouse is over, or null if none is found - function findNearbyItem(mouseX, mouseY, seriesFilter) { - var maxDistance = options.grid.mouseActiveRadius, - smallestDistance = maxDistance * maxDistance + 1, - item = null, foundPoint = false, i, j, ps; - - for (i = series.length - 1; i >= 0; --i) { - if (!seriesFilter(series[i])) - continue; - - var s = series[i], - axisx = s.xaxis, - axisy = s.yaxis, - points = s.datapoints.points, - mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster - my = axisy.c2p(mouseY), - maxx = maxDistance / axisx.scale, - maxy = maxDistance / axisy.scale; - - ps = s.datapoints.pointsize; - // with inverse transforms, we can't use the maxx/maxy - // optimization, sadly - if (axisx.options.inverseTransform) - maxx = Number.MAX_VALUE; - if (axisy.options.inverseTransform) - maxy = Number.MAX_VALUE; - - if (s.lines.show || s.points.show) { - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1]; - if (x == null) - continue; - - // For points and lines, the cursor must be within a - // certain distance to the data point - if (x - mx > maxx || x - mx < -maxx || - y - my > maxy || y - my < -maxy) - continue; - - // We have to calculate distances in pixels, not in - // data units, because the scales of the axes may be different - var dx = Math.abs(axisx.p2c(x) - mouseX), - dy = Math.abs(axisy.p2c(y) - mouseY), - dist = dx * dx + dy * dy; // we save the sqrt - - // use <= to ensure last point takes precedence - // (last generally means on top of) - if (dist < smallestDistance) { - smallestDistance = dist; - item = [i, j / ps]; - } - } - } - - if (s.bars.show && !item) { // no other point can be nearby - - var barLeft, barRight; - - switch (s.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -s.bars.barWidth; - break; - default: - barLeft = -s.bars.barWidth / 2; - } - - barRight = barLeft + s.bars.barWidth; - - for (j = 0; j < points.length; j += ps) { - var x = points[j], y = points[j + 1], b = points[j + 2]; - if (x == null) - continue; - - // for a bar graph, the cursor must be inside the bar - if (series[i].bars.horizontal ? - (mx <= Math.max(b, x) && mx >= Math.min(b, x) && - my >= y + barLeft && my <= y + barRight) : - (mx >= x + barLeft && mx <= x + barRight && - my >= Math.min(b, y) && my <= Math.max(b, y))) - item = [i, j / ps]; - } - } - } - - if (item) { - i = item[0]; - j = item[1]; - ps = series[i].datapoints.pointsize; - - return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), - dataIndex: j, - series: series[i], - seriesIndex: i }; - } - - return null; - } - - function onMouseMove(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return s["hoverable"] != false; }); - } - - function onMouseLeave(e) { - if (options.grid.hoverable) - triggerClickHoverEvent("plothover", e, - function (s) { return false; }); - } - - function onClick(e) { - triggerClickHoverEvent("plotclick", e, - function (s) { return s["clickable"] != false; }); - } - - // trigger click or hover event (they send the same parameters - // so we share their code) - function triggerClickHoverEvent(eventname, event, seriesFilter) { - var offset = eventHolder.offset(), - canvasX = event.pageX - offset.left - plotOffset.left, - canvasY = event.pageY - offset.top - plotOffset.top, - pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); - - pos.pageX = event.pageX; - pos.pageY = event.pageY; - - var item = findNearbyItem(canvasX, canvasY, seriesFilter); - - if (item) { - // fill in mouse pos for any listeners out there - item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); - item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); - } - - 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 && - h.point[0] == item.datapoint[0] && - h.point[1] == item.datapoint[1])) - unhighlight(h.series, h.point); - } - - if (item) - highlight(item.series, item.datapoint, eventname); - } - - placeholder.trigger(eventname, [ pos, item ]); - } - - function triggerRedrawOverlay() { - var t = options.interaction.redrawOverlayInterval; - if (t == -1) { // skip event queue - drawOverlay(); - return; - } - - if (!redrawTimeout) - redrawTimeout = setTimeout(drawOverlay, t); - } - - function drawOverlay() { - redrawTimeout = null; - - // draw highlights - octx.save(); - overlay.clear(); - octx.translate(plotOffset.left, plotOffset.top); - - var i, hi; - for (i = 0; i < highlights.length; ++i) { - hi = highlights[i]; - - if (hi.series.bars.show) - drawBarHighlight(hi.series, hi.point); - else - drawPointHighlight(hi.series, hi.point); - } - octx.restore(); - - executeHooks(hooks.drawOverlay, [octx]); - } - - function highlight(s, point, auto) { - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i == -1) { - highlights.push({ series: s, point: point, auto: auto }); - - triggerRedrawOverlay(); - } - else if (!auto) - highlights[i].auto = false; - } - - function unhighlight(s, point) { - if (s == null && point == null) { - highlights = []; - triggerRedrawOverlay(); - return; - } - - if (typeof s == "number") - s = series[s]; - - if (typeof point == "number") { - var ps = s.datapoints.pointsize; - point = s.datapoints.points.slice(ps * point, ps * (point + 1)); - } - - var i = indexOfHighlight(s, point); - if (i != -1) { - highlights.splice(i, 1); - - triggerRedrawOverlay(); - } - } - - function indexOfHighlight(s, p) { - for (var i = 0; i < highlights.length; ++i) { - var h = highlights[i]; - if (h.series == s && h.point[0] == p[0] - && h.point[1] == p[1]) - return i; - } - return -1; - } - - function drawPointHighlight(series, point) { - var x = point[0], y = point[1], - axisx = series.xaxis, axisy = series.yaxis, - highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); - - if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) - return; - - var pointRadius = series.points.radius + series.points.lineWidth / 2; - octx.lineWidth = pointRadius; - octx.strokeStyle = highlightColor; - var radius = 1.5 * pointRadius; - x = axisx.p2c(x); - y = axisy.p2c(y); - - octx.beginPath(); - if (series.points.symbol == "circle") - octx.arc(x, y, radius, 0, 2 * Math.PI, false); - else - series.points.symbol(octx, x, y, radius, false); - octx.closePath(); - octx.stroke(); - } - - function drawBarHighlight(series, point) { - var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), - fillStyle = highlightColor, - barLeft; - - switch (series.bars.align) { - case "left": - barLeft = 0; - break; - case "right": - barLeft = -series.bars.barWidth; - break; - default: - barLeft = -series.bars.barWidth / 2; - } - - octx.lineWidth = series.bars.lineWidth; - octx.strokeStyle = highlightColor; - - drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, - function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); - } - - function getColorOrGradient(spec, bottom, top, defaultColor) { - if (typeof spec == "string") - return spec; - else { - // assume this is a gradient spec; IE currently only - // supports a simple vertical gradient properly, so that's - // what we support too - var gradient = ctx.createLinearGradient(0, top, 0, bottom); - - for (var i = 0, l = spec.colors.length; i < l; ++i) { - var c = spec.colors[i]; - if (typeof c != "string") { - var co = $.color.parse(defaultColor); - if (c.brightness != null) - co = co.scale('rgb', c.brightness); - if (c.opacity != null) - co.a *= c.opacity; - c = co.toString(); - } - gradient.addColorStop(i / (l - 1), c); - } - - return gradient; - } - } - } - - // Add the plot function to the top level of the jQuery object - - $.plot = function(placeholder, data, options) { - //var t0 = new Date(); - var plot = new Plot($(placeholder), data, options, $.plot.plugins); - //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); - return plot; - }; - - $.plot.version = "0.8.3"; - - $.plot.plugins = []; - - // Also add the plot function as a chainable property - - $.fn.plot = function(data, options) { - return this.each(function() { - $.plot(this, data, options); - }); - }; - - // round to nearby lower multiple of base - function floorInBase(n, base) { - return base * Math.floor(n / base); - } - -})(jQuery); diff --git a/src/lib/jquery.flot.pie.js b/src/lib/jquery.flot.pie.js deleted file mode 100644 index 9c19db9..0000000 --- a/src/lib/jquery.flot.pie.js +++ /dev/null @@ -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("
Could not draw pie with labels contained inside canvas
"); - } - - 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 = "" + text + ""; - 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;"; - $("
") - .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 "
" + label + "
" + Math.round(slice.percent) + "%
"; - }, // 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); diff --git a/src/lib/jquery.flot.time.js b/src/lib/jquery.flot.time.js deleted file mode 100644 index 34c1d12..0000000 --- a/src/lib/jquery.flot.time.js +++ /dev/null @@ -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); diff --git a/src/lib/perfect-scrollbar.min.js b/src/lib/perfect-scrollbar.min.js deleted file mode 100644 index b5d61d2..0000000 --- a/src/lib/perfect-scrollbar.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * perfect-scrollbar v1.2.0 - * (c) 2017 Hyunje Jun - * @license MIT - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.PerfectScrollbar=e()}(this,function(){"use strict";function t(t){return getComputedStyle(t)}function e(t,e){for(var i in e){var n=e[i];"number"==typeof n&&(n+="px"),t.style[i]=n}return t}function i(t){var e=document.createElement("div");return e.className=t,e}function n(t,e){if(!v)throw new Error("No element matching method supported");return v.call(t,e)}function r(t){t.remove?t.remove():t.parentNode&&t.parentNode.removeChild(t)}function l(t,e){return Array.prototype.filter.call(t.children,function(t){return n(t,e)})}function o(t,e){var i=t.element.classList,n=m.state.scrolling(e);i.contains(n)?clearTimeout(w[e]):i.add(n)}function s(t,e){w[e]=setTimeout(function(){return t.isAlive&&t.element.classList.remove(m.state.scrolling(e))},t.settings.scrollingThreshold)}function a(t,e){o(t,e),s(t,e)}function c(t){if("function"==typeof window.CustomEvent)return new CustomEvent(t);var e=document.createEvent("CustomEvent");return e.initCustomEvent(t,!1,!1,void 0),e}function h(t,e,i,n,r){var l=i[0],o=i[1],s=i[2],h=i[3],u=i[4],d=i[5];void 0===n&&(n=!0),void 0===r&&(r=!1);var p=t.element;t.reach[h]=null,p[s]<1&&(t.reach[h]="start"),p[s]>t[l]-t[o]-1&&(t.reach[h]="end"),e&&(p.dispatchEvent(c("ps-scroll-"+h)),e<0?p.dispatchEvent(c("ps-scroll-"+u)):e>0&&p.dispatchEvent(c("ps-scroll-"+d)),n&&a(t,h)),t.reach[h]&&(e||r)&&p.dispatchEvent(c("ps-"+h+"-reach-"+t.reach[h]))}function u(t){return parseInt(t,10)||0}function d(t){return n(t,"input,[contenteditable]")||n(t,"select,[contenteditable]")||n(t,"textarea,[contenteditable]")||n(t,"button,[contenteditable]")}function p(e){var i=t(e);return u(i.width)+u(i.paddingLeft)+u(i.paddingRight)+u(i.borderLeftWidth)+u(i.borderRightWidth)}function f(t,e){return t.settings.minScrollbarLength&&(e=Math.max(e,t.settings.minScrollbarLength)),t.settings.maxScrollbarLength&&(e=Math.min(e,t.settings.maxScrollbarLength)),e}function b(t,i){var n={width:i.railXWidth};i.isRtl?n.left=i.negativeScrollAdjustment+t.scrollLeft+i.containerWidth-i.contentWidth:n.left=t.scrollLeft,i.isScrollbarXUsingBottom?n.bottom=i.scrollbarXBottom-t.scrollTop:n.top=i.scrollbarXTop+t.scrollTop,e(i.scrollbarXRail,n);var r={top:t.scrollTop,height:i.railYHeight};i.isScrollbarYUsingRight?i.isRtl?r.right=i.contentWidth-(i.negativeScrollAdjustment+t.scrollLeft)-i.scrollbarYRight-i.scrollbarYOuterWidth:r.right=i.scrollbarYRight-t.scrollLeft:i.isRtl?r.left=i.negativeScrollAdjustment+t.scrollLeft+2*i.containerWidth-i.contentWidth-i.scrollbarYLeft-i.scrollbarYOuterWidth:r.left=i.scrollbarYLeft+t.scrollLeft,e(i.scrollbarYRail,r),e(i.scrollbarX,{left:i.scrollbarXLeft,width:i.scrollbarXWidth-i.railBorderXWidth}),e(i.scrollbarY,{top:i.scrollbarYTop,height:i.scrollbarYHeight-i.railBorderYWidth})}function g(t,e){function i(e){f[d]=b+v*(e[a]-g),o(t,p),R(t),e.stopPropagation(),e.preventDefault()}function n(){s(t,p),t.event.unbind(t.ownerDocument,"mousemove",i)}var r=e[0],l=e[1],a=e[2],c=e[3],h=e[4],u=e[5],d=e[6],p=e[7],f=t.element,b=null,g=null,v=null;t.event.bind(t[h],"mousedown",function(e){b=f[d],g=e[a],v=(t[l]-t[r])/(t[c]-t[u]),t.event.bind(t.ownerDocument,"mousemove",i),t.event.once(t.ownerDocument,"mouseup",n),e.stopPropagation(),e.preventDefault()})}var v=Element.prototype.matches||Element.prototype.webkitMatchesSelector||Element.prototype.msMatchesSelector,m={main:"ps",element:{thumb:function(t){return"ps__thumb-"+t},rail:function(t){return"ps__rail-"+t},consuming:"ps__child--consume"},state:{focus:"ps--focus",active:function(t){return"ps--active-"+t},scrolling:function(t){return"ps--scrolling-"+t}}},w={x:null,y:null},Y=function(t){this.element=t,this.handlers={}},X={isEmpty:{configurable:!0}};Y.prototype.bind=function(t,e){void 0===this.handlers[t]&&(this.handlers[t]=[]),this.handlers[t].push(e),this.element.addEventListener(t,e,!1)},Y.prototype.unbind=function(t,e){var i=this;this.handlers[t]=this.handlers[t].filter(function(n){return!(!e||n===e)||(i.element.removeEventListener(t,n,!1),!1)})},Y.prototype.unbindAll=function(){var t=this;for(var e in t.handlers)t.unbind(e)},X.isEmpty.get=function(){var t=this;return Object.keys(this.handlers).every(function(e){return 0===t.handlers[e].length})},Object.defineProperties(Y.prototype,X);var W=function(){this.eventElements=[]};W.prototype.eventElement=function(t){var e=this.eventElements.filter(function(e){return e.element===t})[0];return e||(e=new Y(t),this.eventElements.push(e)),e},W.prototype.bind=function(t,e,i){this.eventElement(t).bind(e,i)},W.prototype.unbind=function(t,e,i){var n=this.eventElement(t);n.unbind(e,i),n.isEmpty&&this.eventElements.splice(this.eventElements.indexOf(n),1)},W.prototype.unbindAll=function(){this.eventElements.forEach(function(t){return t.unbindAll()}),this.eventElements=[]},W.prototype.once=function(t,e,i){var n=this.eventElement(t),r=function(t){n.unbind(e,r),i(t)};n.bind(e,r)};var y=function(t,e,i,n,r){void 0===n&&(n=!0),void 0===r&&(r=!1);var l;if("top"===e)l=["contentHeight","containerHeight","scrollTop","y","up","down"];else{if("left"!==e)throw new Error("A proper axis should be provided");l=["contentWidth","containerWidth","scrollLeft","x","left","right"]}h(t,i,l,n,r)},L={isWebKit:document&&"WebkitAppearance"in document.documentElement.style,supportsTouch:window&&("ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),supportsIePointer:navigator&&navigator.msMaxTouchPoints},R=function(t){var e=t.element;t.containerWidth=e.clientWidth,t.containerHeight=e.clientHeight,t.contentWidth=e.scrollWidth,t.contentHeight=e.scrollHeight,e.contains(t.scrollbarXRail)||(l(e,m.element.rail("x")).forEach(function(t){return r(t)}),e.appendChild(t.scrollbarXRail)),e.contains(t.scrollbarYRail)||(l(e,m.element.rail("y")).forEach(function(t){return r(t)}),e.appendChild(t.scrollbarYRail)),!t.settings.suppressScrollX&&t.containerWidth+t.settings.scrollXMarginOffset=t.railXWidth-t.scrollbarXWidth&&(t.scrollbarXLeft=t.railXWidth-t.scrollbarXWidth),t.scrollbarYTop>=t.railYHeight-t.scrollbarYHeight&&(t.scrollbarYTop=t.railYHeight-t.scrollbarYHeight),b(e,t),t.scrollbarXActive?e.classList.add(m.state.active("x")):(e.classList.remove(m.state.active("x")),t.scrollbarXWidth=0,t.scrollbarXLeft=0,e.scrollLeft=0),t.scrollbarYActive?e.classList.add(m.state.active("y")):(e.classList.remove(m.state.active("y")),t.scrollbarYHeight=0,t.scrollbarYTop=0,e.scrollTop=0)},T={"click-rail":function(t){t.event.bind(t.scrollbarY,"mousedown",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarYRail,"mousedown",function(e){var i=e.pageY-window.pageYOffset-t.scrollbarYRail.getBoundingClientRect().top>t.scrollbarYTop?1:-1;t.element.scrollTop+=i*t.containerHeight,R(t),e.stopPropagation()}),t.event.bind(t.scrollbarX,"mousedown",function(t){return t.stopPropagation()}),t.event.bind(t.scrollbarXRail,"mousedown",function(e){var i=e.pageX-window.pageXOffset-t.scrollbarXRail.getBoundingClientRect().left>t.scrollbarXLeft?1:-1;t.element.scrollLeft+=i*t.containerWidth,R(t),e.stopPropagation()})},"drag-thumb":function(t){g(t,["containerWidth","contentWidth","pageX","railXWidth","scrollbarX","scrollbarXWidth","scrollLeft","x"]),g(t,["containerHeight","contentHeight","pageY","railYHeight","scrollbarY","scrollbarYHeight","scrollTop","y"])},keyboard:function(t){function e(e,n){var r=i.scrollTop;if(0===e){if(!t.scrollbarYActive)return!1;if(0===r&&n>0||r>=t.contentHeight-t.containerHeight&&n<0)return!t.settings.wheelPropagation}var l=i.scrollLeft;if(0===n){if(!t.scrollbarXActive)return!1;if(0===l&&e<0||l>=t.contentWidth-t.containerWidth&&e>0)return!t.settings.wheelPropagation}return!0}var i=t.element,r=function(){return n(i,":hover")},l=function(){return n(t.scrollbarX,":focus")||n(t.scrollbarY,":focus")};t.event.bind(t.ownerDocument,"keydown",function(n){if(!(n.isDefaultPrevented&&n.isDefaultPrevented()||n.defaultPrevented)&&(r()||l())){var o=document.activeElement?document.activeElement:t.ownerDocument.activeElement;if(o){if("IFRAME"===o.tagName)o=o.contentDocument.activeElement;else for(;o.shadowRoot;)o=o.shadowRoot.activeElement;if(d(o))return}var s=0,a=0;switch(n.which){case 37:s=n.metaKey?-t.contentWidth:n.altKey?-t.containerWidth:-30;break;case 38:a=n.metaKey?t.contentHeight:n.altKey?t.containerHeight:30;break;case 39:s=n.metaKey?t.contentWidth:n.altKey?t.containerWidth:30;break;case 40:a=n.metaKey?-t.contentHeight:n.altKey?-t.containerHeight:-30;break;case 32:a=n.shiftKey?t.containerHeight:-t.containerHeight;break;case 33:a=t.containerHeight;break;case 34:a=-t.containerHeight;break;case 36:a=t.contentHeight;break;case 35:a=-t.contentHeight;break;default:return}t.settings.suppressScrollX&&0!==s||t.settings.suppressScrollY&&0!==a||(i.scrollTop-=a,i.scrollLeft+=s,R(t),e(s,a)&&n.preventDefault())}})},wheel:function(e){function i(t,i){var n=o.scrollTop;if(0===t){if(!e.scrollbarYActive)return!1;if(0===n&&i>0||n>=e.contentHeight-e.containerHeight&&i<0)return!e.settings.wheelPropagation}var r=o.scrollLeft;if(0===i){if(!e.scrollbarXActive)return!1;if(0===r&&t<0||r>=e.contentWidth-e.containerWidth&&t>0)return!e.settings.wheelPropagation}return!0}function n(t){var e=t.deltaX,i=-1*t.deltaY;return void 0!==e&&void 0!==i||(e=-1*t.wheelDeltaX/6,i=t.wheelDeltaY/6),t.deltaMode&&1===t.deltaMode&&(e*=10,i*=10),e!==e&&i!==i&&(e=0,i=t.wheelDelta),t.shiftKey?[-i,-e]:[e,i]}function r(e,i,n){if(!L.isWebKit&&o.querySelector("select:focus"))return!0;if(!o.contains(e))return!1;for(var r=e;r&&r!==o;){if(r.classList.contains(m.element.consuming))return!0;var l=t(r);if([l.overflow,l.overflowX,l.overflowY].join("").match(/(scroll|auto)/)){var s=r.scrollHeight-r.clientHeight;if(s>0&&!(0===r.scrollTop&&n>0||r.scrollTop===s&&n<0))return!0;var a=r.scrollLeft-r.clientWidth;if(a>0&&!(0===r.scrollLeft&&i<0||r.scrollLeft===a&&i>0))return!0}r=r.parentNode}return!1}function l(t){var l=n(t),s=l[0],a=l[1];if(!r(t.target,s,a)){var c=!1;e.settings.useBothWheelAxes?e.scrollbarYActive&&!e.scrollbarXActive?(a?o.scrollTop-=a*e.settings.wheelSpeed:o.scrollTop+=s*e.settings.wheelSpeed,c=!0):e.scrollbarXActive&&!e.scrollbarYActive&&(s?o.scrollLeft+=s*e.settings.wheelSpeed:o.scrollLeft-=a*e.settings.wheelSpeed,c=!0):(o.scrollTop-=a*e.settings.wheelSpeed,o.scrollLeft+=s*e.settings.wheelSpeed),R(e),(c=c||i(s,a))&&!t.ctrlKey&&(t.stopPropagation(),t.preventDefault())}}var o=e.element;void 0!==window.onwheel?e.event.bind(o,"wheel",l):void 0!==window.onmousewheel&&e.event.bind(o,"mousewheel",l)},touch:function(t){function e(e,i){var n=h.scrollTop,r=h.scrollLeft,l=Math.abs(e),o=Math.abs(i);if(o>l){if(i<0&&n===t.contentHeight-t.containerHeight||i>0&&0===n)return{stop:!t.settings.swipePropagation,prevent:0===window.scrollY}}else if(l>o&&(e<0&&r===t.contentWidth-t.containerWidth||e>0&&0===r))return{stop:!t.settings.swipePropagation,prevent:!0};return{stop:!0,prevent:!0}}function i(e,i){h.scrollTop-=i,h.scrollLeft-=e,R(t)}function n(){b=!0}function r(){b=!1}function l(t){return t.targetTouches?t.targetTouches[0]:t}function o(t){return!(t.pointerType&&"pen"===t.pointerType&&0===t.buttons||(!t.targetTouches||1!==t.targetTouches.length)&&(!t.pointerType||"mouse"===t.pointerType||t.pointerType===t.MSPOINTER_TYPE_MOUSE))}function s(t){if(o(t)){g=!0;var e=l(t);u.pageX=e.pageX,u.pageY=e.pageY,d=(new Date).getTime(),null!==f&&clearInterval(f),t.stopPropagation()}}function a(n){if(!g&&t.settings.swipePropagation&&s(n),!b&&g&&o(n)){var r=l(n),a={pageX:r.pageX,pageY:r.pageY},c=a.pageX-u.pageX,h=a.pageY-u.pageY;i(c,h),u=a;var f=(new Date).getTime(),v=f-d;v>0&&(p.x=c/v,p.y=h/v,d=f);var m=e(c,h),w=m.stop,Y=m.prevent;w&&n.stopPropagation(),Y&&n.preventDefault()}}function c(){!b&&g&&(g=!1,t.settings.swipeEasing&&(clearInterval(f),f=setInterval(function(){t.isInitialized?clearInterval(f):p.x||p.y?Math.abs(p.x)<.01&&Math.abs(p.y)<.01?clearInterval(f):(i(30*p.x,30*p.y),p.x*=.8,p.y*=.8):clearInterval(f)},10)))}if(L.supportsTouch||L.supportsIePointer){var h=t.element,u={},d=0,p={},f=null,b=!1,g=!1;L.supportsTouch?(t.event.bind(window,"touchstart",n),t.event.bind(window,"touchend",r),t.event.bind(h,"touchstart",s),t.event.bind(h,"touchmove",a),t.event.bind(h,"touchend",c)):L.supportsIePointer&&(window.PointerEvent?(t.event.bind(window,"pointerdown",n),t.event.bind(window,"pointerup",r),t.event.bind(h,"pointerdown",s),t.event.bind(h,"pointermove",a),t.event.bind(h,"pointerup",c)):window.MSPointerEvent&&(t.event.bind(window,"MSPointerDown",n),t.event.bind(window,"MSPointerUp",r),t.event.bind(h,"MSPointerDown",s),t.event.bind(h,"MSPointerMove",a),t.event.bind(h,"MSPointerUp",c)))}}},H=function(n,r){var l=this;if(void 0===r&&(r={}),"string"==typeof n&&(n=document.querySelector(n)),!n||!n.nodeName)throw new Error("no element is specified to initialize PerfectScrollbar");this.element=n,n.classList.add(m.main),this.settings={handlers:["click-rail","drag-thumb","keyboard","wheel","touch"],maxScrollbarLength:null,minScrollbarLength:null,scrollingThreshold:1e3,scrollXMarginOffset:0,scrollYMarginOffset:0,suppressScrollX:!1,suppressScrollY:!1,swipePropagation:!0,swipeEasing:!0,useBothWheelAxes:!1,wheelPropagation:!1,wheelSpeed:1};for(var o in r)l.settings[o]=r[o];this.containerWidth=null,this.containerHeight=null,this.contentWidth=null,this.contentHeight=null;var s=function(){return n.classList.add(m.state.focus)},a=function(){return n.classList.remove(m.state.focus)};this.isRtl="rtl"===t(n).direction,this.isNegativeScroll=function(){var t=n.scrollLeft,e=null;return n.scrollLeft=-1,e=n.scrollLeft<0,n.scrollLeft=t,e}(),this.negativeScrollAdjustment=this.isNegativeScroll?n.scrollWidth-n.clientWidth:0,this.event=new W,this.ownerDocument=n.ownerDocument||document,this.scrollbarXRail=i(m.element.rail("x")),n.appendChild(this.scrollbarXRail),this.scrollbarX=i(m.element.thumb("x")),this.scrollbarXRail.appendChild(this.scrollbarX),this.scrollbarX.setAttribute("tabindex",0),this.event.bind(this.scrollbarX,"focus",s),this.event.bind(this.scrollbarX,"blur",a),this.scrollbarXActive=null,this.scrollbarXWidth=null,this.scrollbarXLeft=null;var c=t(this.scrollbarXRail);this.scrollbarXBottom=parseInt(c.bottom,10),isNaN(this.scrollbarXBottom)?(this.isScrollbarXUsingBottom=!1,this.scrollbarXTop=u(c.top)):this.isScrollbarXUsingBottom=!0,this.railBorderXWidth=u(c.borderLeftWidth)+u(c.borderRightWidth),e(this.scrollbarXRail,{display:"block"}),this.railXMarginWidth=u(c.marginLeft)+u(c.marginRight),e(this.scrollbarXRail,{display:""}),this.railXWidth=null,this.railXRatio=null,this.scrollbarYRail=i(m.element.rail("y")),n.appendChild(this.scrollbarYRail),this.scrollbarY=i(m.element.thumb("y")),this.scrollbarYRail.appendChild(this.scrollbarY),this.scrollbarY.setAttribute("tabindex",0),this.event.bind(this.scrollbarY,"focus",s),this.event.bind(this.scrollbarY,"blur",a),this.scrollbarYActive=null,this.scrollbarYHeight=null,this.scrollbarYTop=null;var h=t(this.scrollbarYRail);this.scrollbarYRight=parseInt(h.right,10),isNaN(this.scrollbarYRight)?(this.isScrollbarYUsingRight=!1,this.scrollbarYLeft=u(h.left)):this.isScrollbarYUsingRight=!0,this.scrollbarYOuterWidth=this.isRtl?p(this.scrollbarY):null,this.railBorderYWidth=u(h.borderTopWidth)+u(h.borderBottomWidth),e(this.scrollbarYRail,{display:"block"}),this.railYMarginHeight=u(h.marginTop)+u(h.marginBottom),e(this.scrollbarYRail,{display:""}),this.railYHeight=null,this.railYRatio=null,this.reach={x:n.scrollLeft<=0?"start":n.scrollLeft>=this.contentWidth-this.containerWidth?"end":null,y:n.scrollTop<=0?"start":n.scrollTop>=this.contentHeight-this.containerHeight?"end":null},this.isAlive=!0,this.settings.handlers.forEach(function(t){return T[t](l)}),this.lastScrollTop=n.scrollTop,this.lastScrollLeft=n.scrollLeft,this.event.bind(this.element,"scroll",function(t){return l.onScroll(t)}),R(this)};return H.prototype.update=function(){this.isAlive&&(this.negativeScrollAdjustment=this.isNegativeScroll?this.element.scrollWidth-this.element.clientWidth:0,e(this.scrollbarXRail,{display:"block"}),e(this.scrollbarYRail,{display:"block"}),this.railXMarginWidth=u(t(this.scrollbarXRail).marginLeft)+u(t(this.scrollbarXRail).marginRight),this.railYMarginHeight=u(t(this.scrollbarYRail).marginTop)+u(t(this.scrollbarYRail).marginBottom),e(this.scrollbarXRail,{display:"none"}),e(this.scrollbarYRail,{display:"none"}),R(this),y(this,"top",0,!1,!0),y(this,"left",0,!1,!0),e(this.scrollbarXRail,{display:""}),e(this.scrollbarYRail,{display:""}))},H.prototype.onScroll=function(t){this.isAlive&&(R(this),y(this,"top",this.element.scrollTop-this.lastScrollTop),y(this,"left",this.element.scrollLeft-this.lastScrollLeft),this.lastScrollTop=this.element.scrollTop,this.lastScrollLeft=this.element.scrollLeft)},H.prototype.destroy=function(){this.isAlive&&(this.event.unbindAll(),r(this.scrollbarX),r(this.scrollbarY),r(this.scrollbarXRail),r(this.scrollbarYRail),this.removePsClasses(),this.element=null,this.scrollbarX=null,this.scrollbarY=null,this.scrollbarXRail=null,this.scrollbarYRail=null,this.isAlive=!1)},H.prototype.removePsClasses=function(){this.element.className=this.element.className.split(" ").filter(function(t){return!t.match(/^ps([-_].+|)$/)}).join(" ")},H}); \ No newline at end of file diff --git a/src/module.ts b/src/module.ts deleted file mode 100644 index 723ebb1..0000000 --- a/src/module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { PieChartCtrl } from './piechart_ctrl'; -import { loadPluginCss } from 'grafana/app/plugins/sdk'; - -loadPluginCss({ - dark: 'plugins/grafana-piechart-panel/styles/dark.css', - light: 'plugins/grafana-piechart-panel/styles/light.css', -}); - -export { PieChartCtrl as PanelCtrl }; diff --git a/src/piechart_ctrl.test.ts b/src/piechart_ctrl.test.ts deleted file mode 100644 index ffbcd8b..0000000 --- a/src/piechart_ctrl.test.ts +++ /dev/null @@ -1,7 +0,0 @@ -describe('Basic test', () => { - const text = 'hello'; - - it('should work', () => { - expect(text).toBe('hello'); - }); -}); diff --git a/src/piechart_ctrl.ts b/src/piechart_ctrl.ts deleted file mode 100644 index 333bc4a..0000000 --- a/src/piechart_ctrl.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { MetricsPanelCtrl } from 'grafana/app/plugins/sdk'; -import _ from 'lodash'; -import kbn from 'grafana/app/core/utils/kbn'; -// @ts-ignore -import TimeSeries from 'grafana/app/core/time_series'; -import rendering from './rendering'; -import './legend'; - -class PieChartCtrl extends MetricsPanelCtrl { - static templateUrl = 'module.html'; - $rootScope: any; - hiddenSeries: any; - unitFormats: any; - series: any; - data: any; - - /** @ngInject */ - constructor($scope: any, $injector: any, $rootScope: any) { - super($scope, $injector); - this.$rootScope = $rootScope; - this.hiddenSeries = {}; - - const panelDefaults = { - pieType: 'pie', - legend: { - show: true, // disable/enable legend - values: true, - }, - links: [], - datasource: null, - interval: null, - targets: [{}], - cacheTimeout: null, - nullPointMode: 'connected', - legendType: 'Under graph', - breakPoint: '50%', - aliasColors: {}, - format: 'short', - valueName: 'current', - strokeWidth: 1, - fontSize: '80%', - combine: { - threshold: 0.0, - label: 'Others', - }, - }; - - _.defaults(this.panel, panelDefaults); - _.defaults(this.panel.legend, panelDefaults.legend); - - this.events.on('render', this.onRender.bind(this)); - this.events.on('data-received', this.onDataReceived.bind(this)); - this.events.on('data-error', this.onDataError.bind(this)); - this.events.on('data-snapshot-load', this.onDataReceived.bind(this)); - this.events.on('init-edit-mode', this.onInitEditMode.bind(this)); - - this.setLegendWidthForLegacyBrowser(); - } - - onInitEditMode() { - this.addEditorTab('Options', 'public/plugins/grafana-piechart-panel/editor.html', 2); - this.unitFormats = kbn.getUnitFormats(); - } - - setUnitFormat(subItem: any) { - this.panel.format = subItem.value; - this.render(); - } - - onDataError() { - this.series = []; - this.render(); - } - - changeSeriesColor(series: any, color: any) { - series.color = color; - this.panel.aliasColors[series.alias] = series.color; - this.render(); - } - - onRender() { - this.data = this.parseSeries(this.series); - } - - parseSeries(series: any) { - return _.map(this.series, (serie, i) => { - return { - label: serie.alias, - data: serie.stats[this.panel.valueName], - color: this.panel.aliasColors[serie.alias] || this.$rootScope.colors[i], - legendData: serie.stats[this.panel.valueName], - }; - }); - } - - onDataReceived(dataList: any) { - this.series = dataList.map(this.seriesHandler.bind(this)); - this.data = this.parseSeries(this.series); - this.render(this.data); - } - - seriesHandler(seriesData: any) { - const series = new TimeSeries({ - datapoints: seriesData.datapoints, - alias: seriesData.target, - }); - - series.flotpairs = series.getFlotPairs(this.panel.nullPointMode); - return series; - } - - getDecimalsForValue(value: any) { - if (_.isNumber(this.panel.decimals)) { - return { decimals: this.panel.decimals, scaledDecimals: null }; - } - - const delta = value / 2; - let dec = -Math.floor(Math.log(delta) / Math.LN10); - - const magn = Math.pow(10, -dec); - const norm = delta / magn; // norm is between 1.0 and 10.0 - let size; - - if (norm < 1.5) { - size = 1; - } else if (norm < 3) { - size = 2; - // special case for 2.5, requires an extra decimal - if (norm > 2.25) { - size = 2.5; - ++dec; - } - } else if (norm < 7.5) { - size = 5; - } else { - size = 10; - } - - size *= magn; - - // reduce starting decimals if not needed - if (Math.floor(value) === value) { - dec = 0; - } - - const result = { - decimals: 0, - scaledDecimals: 0, - }; - result.decimals = Math.max(0, dec); - result.scaledDecimals = result.decimals - Math.floor(Math.log(size) / Math.LN10) + 2; - - return result; - } - - formatValue(value: any) { - const decimalInfo = this.getDecimalsForValue(value); - const formatFunc = kbn.valueFormats[this.panel.format]; - if (formatFunc) { - return formatFunc(value, decimalInfo.decimals, decimalInfo.scaledDecimals); - } - return value; - } - - link(scope: any, elem: any, attrs: any, ctrl: any) { - rendering(scope, elem, attrs, ctrl); - } - - toggleSeries(serie: any) { - if (this.hiddenSeries[serie.label]) { - delete this.hiddenSeries[serie.label]; - } else { - this.hiddenSeries[serie.label] = true; - } - this.render(); - } - - onLegendTypeChanged() { - this.setLegendWidthForLegacyBrowser(); - this.render(); - } - - setLegendWidthForLegacyBrowser() { - // @ts-ignore - const isIE11 = !!window.MSInputMethodContext && !!document.documentMode; - if (isIE11 && this.panel.legendType === 'Right side' && !this.panel.legend.sideWidth) { - this.panel.legend.sideWidth = 150; - } - } -} - -export { PieChartCtrl, PieChartCtrl as MetricsPanelCtrl }; diff --git a/src/plugin.json b/src/plugin.json deleted file mode 100644 index b13f734..0000000 --- a/src/plugin.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "type": "panel", - "name": "Pie Chart", - "id": "grafana-piechart-panel", - - "info": { - "description": "Pie chart panel for grafana", - "author": { - "name": "Grafana Labs", - "url": "http://grafana.com" - }, - "keywords": ["piechart", "panel"], - "logos": { - "small": "img/piechart_logo_small.svg", - "large": "img/piechart_logo_large.svg" - }, - "links": [ - { "name": "Project site", "url": "https://github.com/grafana/piechart-panel" }, - { "name": "Blog Post", "url": "https://blog.raintank.io/friends-dont-let-friends-abuse-pie-charts/" }, - { "name": "MIT License", "url": "https://github.com/grafana/piechart-panel/blob/master/LICENSE" } - ], - "screenshots": [ - { "name": "Donut!", "path": "img/piechart-donut.png" }, - { "name": "Legend on the graph", "path": "img/piechart-legend-on-graph.png" }, - { "name": "Legend to the right", "path": "img/piechart-legend-rhs.png" }, - { "name": "Legend underneath", "path": "img/piechart-legend-under.png" }, - { "name": "Piechart options", "path": "img/piechart-options.png" } - ], - "version": "%VERSION%", - "updated": "%TODAY%" - }, - - "dependencies": { - "grafanaVersion": "4.6", - "plugins": [] - } -} diff --git a/src/rendering.ts b/src/rendering.ts deleted file mode 100644 index 04d8bde..0000000 --- a/src/rendering.ts +++ /dev/null @@ -1,181 +0,0 @@ -import _ from 'lodash'; -import './lib/jquery.flot.pie'; -import $ from 'jquery'; -//import './lib/jquery.flot'; - -export default function link(scope: any, elem: any, attrs: any, ctrl: any) { - let data; - const panel = ctrl.panel; - elem = elem.find('.piechart-panel__chart'); - const $tooltip = $('
') as any; - - ctrl.events.on('render', () => { - if (panel.legendType === 'Right side') { - render(false); - setTimeout(() => { - render(true); - }, 50); - } else { - render(true); - } - }); - - function getLegendHeight(panelHeight: any) { - if (!ctrl.panel.legend.show || ctrl.panel.legendType === 'Right side' || ctrl.panel.legendType === 'On graph') { - return 20; - } - - if ((ctrl.panel.legendType === 'Under graph' && ctrl.panel.legend.percentage) || ctrl.panel.legend.values) { - const breakPoint = parseInt(ctrl.panel.breakPoint, 10) / 100; - const total = 23 + 20 * data.length; - return Math.min(total, Math.floor(panelHeight * breakPoint)); - } - - return 0; - } - - function formatter(label: any, slice: any) { - const sliceData = slice.data[0][slice.data[0].length - 1]; - let decimal = 2; - const start = `
${label}
`; - - if (ctrl.panel.legend.percentageDecimals) { - decimal = ctrl.panel.legend.percentageDecimals; - } - if (ctrl.panel.legend.values && ctrl.panel.legend.percentage) { - return start + ctrl.formatValue(sliceData) + '
' + slice.percent.toFixed(decimal) + '%
'; - } else if (ctrl.panel.legend.values) { - return start + ctrl.formatValue(sliceData) + '
'; - } else if (ctrl.panel.legend.percentage) { - return start + slice.percent.toFixed(decimal) + '%'; - } else { - return start + ''; - } - } - - function noDataPoints() { - const html = '
No data points
'; - elem.html(html); - } - - function addPieChart() { - const width = elem.width(); - const height = ctrl.height - getLegendHeight(ctrl.height); - - const size = Math.min(width, height); - - const plotCanvas = $('
'); - const plotCss = { - margin: 'auto', - position: 'relative', - paddingBottom: 20 + 'px', - height: size + 'px', - }; - - plotCanvas.css(plotCss); - - const backgroundColor = $('body').css('background-color'); - - const options = { - legend: { - show: false, - }, - series: { - pie: { - radius: 1, - innerRadius: 0, - show: true, - stroke: { - color: backgroundColor, - width: parseFloat(ctrl.panel.strokeWidth).toFixed(1), - }, - label: { - show: ctrl.panel.legend.show && ctrl.panel.legendType === 'On graph', - formatter: formatter, - }, - highlight: { - opacity: 0.0, - }, - combine: { - threshold: ctrl.panel.combine.threshold, - label: ctrl.panel.combine.label, - }, - }, - }, - grid: { - hoverable: true, - clickable: false, - }, - }; - - if (panel.pieType === 'donut') { - options.series.pie.innerRadius = 0.5; - } - - data = ctrl.data; - - for (let i = 0; i < data.length; i++) { - const series = data[i]; - - // if hidden remove points - if (ctrl.hiddenSeries[series.label]) { - series.data = {}; - } - } - - if (panel.legend.sort) { - if (ctrl.panel.valueName !== panel.legend.sort) { - panel.legend.sort = ctrl.panel.valueName; - } - if (panel.legend.sortDesc === true) { - data.sort((a: any, b: any) => { - return b.legendData - a.legendData; - }); - } else { - data.sort((a: any, b: any) => { - return a.legendData - b.legendData; - }); - } - } - - elem.html(plotCanvas); - - // @ts-ignore - $.plot(plotCanvas, data, options); - plotCanvas.bind('plothover', (event: any, pos: any, item: any) => { - if (!item) { - $tooltip.detach(); - return; - } - - let body; - const percent = parseFloat(item.series.percent).toFixed(2); - const formatted = ctrl.formatValue(item.series.data[0][1]); - - body = '
'; - body += '
' + _.escape(item.series.label) + ': ' + formatted; - body += ' (' + percent + '%)' + '
'; - body += '
'; - - $tooltip.html(body).place_tt(pos.pageX + 20, pos.pageY); - }); - } - - function render(incrementRenderCounter: any) { - if (!ctrl.data) { - return; - } - - data = ctrl.data; - - if (0 === ctrl.data.length) { - noDataPoints(); - } else { - addPieChart(); - } - - if (incrementRenderCounter) { - ctrl.renderingCompleted(); - } - } -} diff --git a/src/styles/dark.scss b/src/styles/dark.scss deleted file mode 100644 index c22f6ad..0000000 --- a/src/styles/dark.scss +++ /dev/null @@ -1,284 +0,0 @@ -@import '../../node_modules/@grafana/toolkit/sass/_variables.dark.scss'; -@import 'piechart'; - -.pieLabel > div { - color: $white; -} - -.piechart-panel { - display: flex; - flex-direction: column; - height: 100%; -} - -.piechart-panel--legend-right { - flex-direction: row; -} - -.piechart-panel--legend-right .piechart-legend { - flex: 0 1 10px; - height: 100%; -} - -.piechart-panel--legend-right .piechart-legend-series { - display: block; - padding-left: 0px; -} - -.piechart-panel--legend-right .piechart-legend-table .piechart-legend-series { - display: table-row; -} - -.piechart-legend__container { - height: 100%; -} - -.piechart-panel__chart { - position: relative; - cursor: crosshair; - flex-grow: 1; - top: 10px; -} - -.datapoints-warning { - pointer: none; - position: absolute; - top: 50%; - left: 50%; - z-index: 10; - margin-top: -50px; - margin-left: -100px; - width: 200px; - text-align: center; - cursor: auto; - padding: 10px; -} - -.piechart-legend { - flex: 0 1 auto; - margin: 0 1rem; - text-align: center; - padding-top: 6px; - position: relative; -} - -.piechart-legend .popover-content { - padding: 0; -} - -.piechart-legend-icon { - position: relative; - padding-right: 4px; - top: 1px; -} - -.piechart-legend-icon, -.piechart-legend-alias, -.piechart-legend-value { - cursor: pointer; - float: left; - white-space: nowrap; - font-size: 85%; - text-align: left; - color: #d8d9da; -} - -.piechart-legend-icon.current::before { - content: 'Current: '; -} - -.piechart-legend-icon.max::before { - content: 'Max: '; -} - -.piechart-legend-icon.min::before { - content: 'Min: '; -} - -.piechart-legend-icon.total::before { - content: 'Total: '; -} - -.piechart-legend-icon.avg::before { - content: 'Avg: '; -} - -.piechart-legend-alias.current::before { - content: 'Current: '; -} - -.piechart-legend-alias.max::before { - content: 'Max: '; -} - -.piechart-legend-alias.min::before { - content: 'Min: '; -} - -.piechart-legend-alias.total::before { - content: 'Total: '; -} - -.piechart-legend-alias.avg::before { - content: 'Avg: '; -} - -.piechart-legend-value.current::before { - content: 'Current: '; -} - -.piechart-legend-value.max::before { - content: 'Max: '; -} - -.piechart-legend-value.min::before { - content: 'Min: '; -} - -.piechart-legend-value.total::before { - content: 'Total: '; -} - -.piechart-legend-value.avg::before { - content: 'Avg: '; -} - -.piechart-legend-icon .fa { - font-size: 135%; - position: relative; - top: 1px; -} - -.piechart-legend-series { - float: left; - white-space: nowrap; - padding-left: 10px; -} - -.piechart-legend-series--right-y { - float: right; -} - -.piechart-legend-value { - padding-left: 6px; -} - -.piechart-legend-table tbody { - display: block; - overflow-y: auto; - overflow-x: hidden; - height: 100%; - padding-bottom: 1px; - padding-right: 5px; -} - -.piechart-legend-table .piechart-legend-series { - display: table-row; - float: none; - padding-left: 0; -} - -.piechart-legend-table .piechart-legend-series--right-y { - float: none; -} - -.piechart-legend-table .piechart-legend-series--right-y .piechart-legend-alias::after { - content: '(right-y)'; - padding: 0 5px; - color: #8e8e8e; -} - -.piechart-legend-table td, -.piechart-legend-alias, -.piechart-legend-icon, -.piechart-legend-value { - float: none; - display: table-cell; - white-space: nowrap; - padding: 2px 10px; - text-align: right; -} - -.piechart-legend-table .piechart-legend-icon { - width: 5px; - padding: 0; - top: 0; -} - -.piechart-legend-table .piechart-legend-icon .fa { - top: 4px; -} - -.piechart-legend-table .piechart-legend-value { - padding-left: 15px; -} - -.piechart-legend-table .piechart-legend-alias { - padding-left: 7px; - text-align: left; - width: 95%; - max-width: 650px; - text-overflow: ellipsis; - overflow: hidden; -} - -.piechart-legend-table .piechart-legend-series:nth-child(odd) { - background: #262628; -} - -.piechart-legend-table .piechart-legend-value.current::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.max::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.min::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.total::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.avg::before { - content: ''; -} - -.piechart-legend-table th { - text-align: right; - padding: 0px 10px 1px 0; - font-weight: bold; - color: #33b5e5; - font-size: 85%; - white-space: nowrap; -} - -.piechart-legend-series-hidden .piechart-legend-value, -.piechart-legend-series-hidden .piechart-legend-alias { - color: #8e8e8e; -} - -.piechart-tooltip { - white-space: nowrap; - font-size: 12px; - background-color: #141414; - color: #d8d9da; -} - -.piechart-tooltip .piechart-tooltip-time { - text-align: center; - position: relative; - top: -3px; - padding: 0.2rem; - font-weight: bold; - color: #d8d9da; -} - -.piechart-tooltip .piechart-tooltip-value { - display: table-cell; - font-weight: bold; - padding-left: 15px; - text-align: right; -} diff --git a/src/styles/light.scss b/src/styles/light.scss deleted file mode 100644 index b26ee71..0000000 --- a/src/styles/light.scss +++ /dev/null @@ -1,289 +0,0 @@ -@import '../../node_modules/@grafana/toolkit/sass/_variables.light.scss'; -@import 'piechart'; - -.pieLabel > div { - color: $black; -} - -.piechart-panel { - display: flex; - flex-direction: column; - height: 100%; -} - -.piechart-panel--legend-right { - flex-direction: row; -} - -.piechart-panel--legend-right .piechart-legend { - flex: 0 1 10px; - height: 100%; -} - -_:-ms-fullscreen, -:root .piechart-panel--legend-right .piechart-legend { - flex: 0 1 200px; -} - -.piechart-panel--legend-right .piechart-legend-series { - display: block; - padding-left: 0px; -} - -.piechart-panel--legend-right .piechart-legend-table .piechart-legend-series { - display: table-row; -} - -.piechart-legend__container { - height: 100%; -} - -.piechart-panel__chart { - position: relative; - cursor: crosshair; - flex-grow: 1; - top: 10px; -} - -.datapoints-warning { - pointer: none; - position: absolute; - top: 50%; - left: 50%; - z-index: 10; - margin-top: -50px; - margin-left: -100px; - width: 200px; - text-align: center; - cursor: auto; - padding: 10px; -} - -.piechart-legend { - flex: 0 1 auto; - margin: 0 1rem; - text-align: center; - padding-top: 6px; - position: relative; -} - -.piechart-legend .popover-content { - padding: 0; -} - -.piechart-legend-icon { - position: relative; - padding-right: 4px; - top: 1px; -} - -.piechart-legend-icon, -.piechart-legend-alias, -.piechart-legend-value { - cursor: pointer; - float: left; - white-space: nowrap; - font-size: 85%; - text-align: left; - color: 52545c; -} - -.piechart-legend-icon.current::before { - content: 'Current: '; -} - -.piechart-legend-icon.max::before { - content: 'Max: '; -} - -.piechart-legend-icon.min::before { - content: 'Min: '; -} - -.piechart-legend-icon.total::before { - content: 'Total: '; -} - -.piechart-legend-icon.avg::before { - content: 'Avg: '; -} - -.piechart-legend-alias.current::before { - content: 'Current: '; -} - -.piechart-legend-alias.max::before { - content: 'Max: '; -} - -.piechart-legend-alias.min::before { - content: 'Min: '; -} - -.piechart-legend-alias.total::before { - content: 'Total: '; -} - -.piechart-legend-alias.avg::before { - content: 'Avg: '; -} - -.piechart-legend-value.current::before { - content: 'Current: '; -} - -.piechart-legend-value.max::before { - content: 'Max: '; -} - -.piechart-legend-value.min::before { - content: 'Min: '; -} - -.piechart-legend-value.total::before { - content: 'Total: '; -} - -.piechart-legend-value.avg::before { - content: 'Avg: '; -} - -.piechart-legend-icon .fa { - font-size: 135%; - position: relative; - top: 1px; -} - -.piechart-legend-series { - float: left; - white-space: nowrap; - padding-left: 10px; -} - -.piechart-legend-series--right-y { - float: right; -} - -.piechart-legend-value { - padding-left: 6px; -} - -.piechart-legend-table tbody { - display: block; - overflow-y: auto; - overflow-x: hidden; - height: 100%; - padding-bottom: 1px; - padding-right: 5px; -} - -.piechart-legend-table .piechart-legend-series { - display: table-row; - float: none; - padding-left: 0; -} - -.piechart-legend-table .piechart-legend-series--right-y { - float: none; -} - -.piechart-legend-table .piechart-legend-series--right-y .piechart-legend-alias::after { - content: '(right-y)'; - padding: 0 5px; - color: #767980; -} - -.piechart-legend-table td, -.piechart-legend-alias, -.piechart-legend-icon, -.piechart-legend-value { - float: none; - display: table-cell; - white-space: nowrap; - padding: 2px 10px; - text-align: right; -} - -.piechart-legend-table .piechart-legend-icon { - width: 5px; - padding: 0; - top: 0; -} - -.piechart-legend-table .piechart-legend-icon .fa { - top: 4px; -} - -.piechart-legend-table .piechart-legend-value { - padding-left: 15px; -} - -.piechart-legend-table .piechart-legend-alias { - padding-left: 7px; - text-align: left; - width: 95%; - max-width: 650px; - text-overflow: ellipsis; - overflow: hidden; -} - -.piechart-legend-table .piechart-legend-series:nth-child(odd) { - background: #dde4ed; -} - -.piechart-legend-table .piechart-legend-value.current::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.max::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.min::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.total::before { - content: ''; -} - -.piechart-legend-table .piechart-legend-value.avg::before { - content: ''; -} - -.piechart-legend-table th { - text-align: right; - padding: 0px 10px 1px 0; - font-weight: bold; - color: #61c2f2; - font-size: 85%; - white-space: nowrap; -} - -.piechart-legend-series-hidden .piechart-legend-value, -.piechart-legend-series-hidden .piechart-legend-alias { - color: #acb6bf; -} - -.piechart-tooltip { - white-space: nowrap; - font-size: 12px; - background-color: #dde4ed; - color: #35373f; -} - -.piechart-tooltip .piechart-tooltip-time { - text-align: center; - position: relative; - top: -3px; - padding: 0.2rem; - font-weight: bold; - color: #35373f; -} - -.piechart-tooltip .piechart-tooltip-value { - display: table-cell; - font-weight: bold; - padding-left: 15px; - text-align: right; -} diff --git a/src/styles/piechart.scss b/src/styles/piechart.scss deleted file mode 100644 index b513c92..0000000 --- a/src/styles/piechart.scss +++ /dev/null @@ -1 +0,0 @@ -@import '../../node_modules/@grafana/toolkit/sass/_variables.scss';