├── quantum ├── lib │ ├── metrics-graphics │ │ ├── src │ │ │ ├── scss │ │ │ │ └── .gitignore │ │ │ └── js │ │ │ │ ├── MG.js │ │ │ │ ├── common │ │ │ │ ├── register.js │ │ │ │ ├── hooks.js │ │ │ │ ├── chart_title.js │ │ │ │ └── window_listeners.js │ │ │ │ └── misc │ │ │ │ ├── error.js │ │ │ │ └── transitions.js │ │ ├── tests │ │ │ ├── misc │ │ │ │ ├── .gitkeep │ │ │ │ ├── process_test.js │ │ │ │ └── utility_test.js │ │ │ ├── common │ │ │ │ ├── .gitkeep │ │ │ │ ├── resize_test.js │ │ │ │ ├── data_graphic_test.js │ │ │ │ └── chart_title_test.js │ │ │ ├── helpers.js │ │ │ └── charts │ │ │ │ ├── histogram_test.js │ │ │ │ ├── bar_test.js │ │ │ │ └── missing_test.js │ │ ├── gulpfile.js │ │ ├── index.js │ │ ├── .jshintignore │ │ ├── examples │ │ │ ├── images │ │ │ │ ├── divider.png │ │ │ │ └── og-logo.png │ │ │ ├── css │ │ │ │ ├── metricsgraphics-demo-accessible.css │ │ │ │ ├── addons │ │ │ │ │ └── mg_line_brushing.css │ │ │ │ └── highlightjs-default.css │ │ │ ├── data │ │ │ │ ├── neg2.json │ │ │ │ ├── small-range.json │ │ │ │ ├── xnotdate.json │ │ │ │ ├── missing-y.json │ │ │ │ ├── missing-is-hidden.json │ │ │ │ ├── missing-is-hidden-accessor.json │ │ │ │ ├── make_fake_data.py │ │ │ │ └── firefox_releases.json │ │ │ └── charts │ │ │ │ ├── other.htm │ │ │ │ └── addons.htm │ │ ├── .gitignore │ │ ├── .jshintrc │ │ ├── .travis.yml │ │ ├── .editorconfig │ │ ├── bower.json │ │ ├── contribute.json │ │ ├── testem.json │ │ ├── HOOKS.md │ │ └── package.json │ ├── jstree │ │ └── themes │ │ │ ├── apple │ │ │ ├── bg.jpg │ │ │ ├── d.png │ │ │ ├── throbber.gif │ │ │ └── dot_for_ie.gif │ │ │ ├── classic │ │ │ ├── d.gif │ │ │ ├── d.png │ │ │ ├── throbber.gif │ │ │ └── dot_for_ie.gif │ │ │ ├── default │ │ │ ├── d.gif │ │ │ ├── d.png │ │ │ └── throbber.gif │ │ │ └── default-rtl │ │ │ ├── d.gif │ │ │ ├── d.png │ │ │ ├── dots.gif │ │ │ └── throbber.gif │ ├── ccc │ │ ├── pvc │ │ │ ├── _namespace.pvc.js │ │ │ ├── pvcBarPanel.js │ │ │ ├── pvcNormalizedBarPanel.js │ │ │ ├── pvcCategoricalAbstractPanel.js │ │ │ ├── visual │ │ │ │ ├── plot │ │ │ │ │ ├── BarPlot.js │ │ │ │ │ ├── BulletPlot.js │ │ │ │ │ ├── NormalizedBarPlot.js │ │ │ │ │ ├── MetricXYPlot.js │ │ │ │ │ ├── CategoricalPlot.js │ │ │ │ │ ├── PointPlot.js │ │ │ │ │ ├── MetricPointPlot.js │ │ │ │ │ ├── WaterfallPlot.js │ │ │ │ │ ├── HeatGridPlot.js │ │ │ │ │ ├── BoxPlot.js │ │ │ │ │ └── BarPlotAbstract.js │ │ │ │ ├── CartesianAxisRootScene.js │ │ │ │ ├── sign │ │ │ │ │ ├── Label.js │ │ │ │ │ ├── Panel.js │ │ │ │ │ ├── Rule.js │ │ │ │ │ ├── Area.js │ │ │ │ │ ├── Bar.js │ │ │ │ │ └── Line.js │ │ │ │ ├── CartesianAxisTickScene.js │ │ │ │ ├── legend │ │ │ │ │ ├── BulletItemRenderer.js │ │ │ │ │ ├── BulletItemSceneVisibility.js │ │ │ │ │ ├── BulletItemSceneSelection.js │ │ │ │ │ ├── WaterfallBulletGroupScene.js │ │ │ │ │ └── BulletGroupScene.js │ │ │ │ └── SizeAxis.js │ │ │ ├── pvcTitlePanel.js │ │ │ ├── pvcPlotBgPanel.js │ │ │ ├── pvcAxisTitlePanel.js │ │ │ ├── data │ │ │ │ ├── DataOper.js │ │ │ │ ├── ComplexView.js │ │ │ │ ├── translation │ │ │ │ │ ├── BoxplotChartTranslationOper.js │ │ │ │ │ └── MetricPointChartTranslationOper.js │ │ │ │ ├── _data.js │ │ │ │ └── Atom.js │ │ │ ├── pvcPlotPanel.js │ │ │ ├── pvcAbstract.js │ │ │ ├── pvcNormalizedBarChart.js │ │ │ ├── pvcBarAbstract.js │ │ │ ├── pvcPieChart.js │ │ │ ├── pvcBaseChart.plots.js │ │ │ └── pvcBarChart.js │ │ ├── data │ │ │ ├── bp.js │ │ │ └── dt.js │ │ └── lib │ │ │ └── tipsy.css │ ├── jquery-ui │ │ └── css │ │ │ └── start │ │ │ └── images │ │ │ ├── animated-overlay.gif │ │ │ ├── ui-icons_0078ae_256x240.png │ │ │ ├── ui-icons_056b93_256x240.png │ │ │ ├── ui-icons_d8e7f3_256x240.png │ │ │ ├── ui-icons_e0fdff_256x240.png │ │ │ ├── ui-icons_f5e175_256x240.png │ │ │ ├── ui-icons_f7a50d_256x240.png │ │ │ ├── ui-icons_fcd113_256x240.png │ │ │ ├── ui-bg_flat_55_999999_40x100.png │ │ │ ├── ui-bg_flat_75_aaaaaa_40x100.png │ │ │ ├── ui-bg_glass_45_0078ae_1x400.png │ │ │ ├── ui-bg_glass_55_f8da4e_1x400.png │ │ │ ├── ui-bg_glass_75_79c9ec_1x400.png │ │ │ ├── ui-bg_inset-hard_100_fcfdfd_1x100.png │ │ │ ├── ui-bg_gloss-wave_45_e14f1c_500x100.png │ │ │ ├── ui-bg_gloss-wave_50_6eac2c_500x100.png │ │ │ └── ui-bg_gloss-wave_75_2191c0_500x100.png │ ├── jquery-linedtextarea │ │ ├── jquery-linedtextarea-license.txt │ │ ├── jquery-linedtextarea.html │ │ └── jquery-linedtextarea.css │ ├── d3 │ │ ├── LICENSE │ │ └── README.md │ └── jsonlint │ │ └── jsl.format.js ├── blockers.html ├── images │ ├── Add.png │ ├── Minus.png │ ├── New.gif │ ├── Plus.png │ ├── fxos.ico │ ├── grain.png │ ├── tab.png │ ├── Remove.png │ ├── bg-sand.png │ ├── spinner.gif │ ├── Spreadsheet.png │ └── bg-gradient-sand.png ├── modevlib │ ├── threads │ │ └── README.md │ ├── gui │ │ ├── Progress.js │ │ ├── README.md │ │ ├── RadioFilter.js │ │ └── accordion.js │ ├── util │ │ ├── aTest.js │ │ ├── aHTML.js │ │ ├── aParse.js │ │ ├── aTimer.js │ │ └── State.js │ ├── main.js │ ├── aLibrary.js │ ├── .editorconfig │ ├── aFormat.js │ ├── charts │ │ └── README.md │ ├── QuantumFlowBugs.js │ ├── Dimension-Jobs.js │ ├── ESQueryRunner.js │ ├── Dimension-Performance.js │ ├── collections │ │ ├── aSet.js │ │ └── aRelation.js │ ├── graph │ │ └── topologicalSort.js │ ├── ScrumBugs.js │ ├── qb │ │ ├── ActiveDataQuery.js │ │ └── aCompiler.js │ ├── Bugzilla.js │ ├── Dimension-Partners.js │ └── Settings.js ├── css │ ├── OpenSans-Bold-webfont.eot │ ├── OpenSans-Bold-webfont.ttf │ ├── OpenSans-Bold-webfont.woff │ ├── OpenSans-Light-webfont.eot │ ├── OpenSans-Light-webfont.ttf │ └── OpenSans-Light-webfont.woff ├── js │ ├── chart_lib.js │ ├── main_lib.js │ ├── burndown.js │ ├── hierarchy.js │ └── regressionCharts.js └── .editorconfig ├── .gitignore └── README.md /quantum/lib/metrics-graphics/src/scss/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/misc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/common/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quantum/blockers.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/src/js/MG.js: -------------------------------------------------------------------------------- 1 | window.MG = {version: '2.10.1'}; 2 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | require('./gulp'); 4 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./dist/metricsgraphics') 2 | -------------------------------------------------------------------------------- /quantum/images/Add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/Add.png -------------------------------------------------------------------------------- /quantum/images/Minus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/Minus.png -------------------------------------------------------------------------------- /quantum/images/New.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/New.gif -------------------------------------------------------------------------------- /quantum/images/Plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/Plus.png -------------------------------------------------------------------------------- /quantum/images/fxos.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/fxos.ico -------------------------------------------------------------------------------- /quantum/images/grain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/grain.png -------------------------------------------------------------------------------- /quantum/images/tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/tab.png -------------------------------------------------------------------------------- /quantum/modevlib/threads/README.md: -------------------------------------------------------------------------------- 1 | 2 | See main project https://github.com/mozilla/jsThreads 3 | -------------------------------------------------------------------------------- /quantum/images/Remove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/Remove.png -------------------------------------------------------------------------------- /quantum/images/bg-sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/bg-sand.png -------------------------------------------------------------------------------- /quantum/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/spinner.gif -------------------------------------------------------------------------------- /quantum/images/Spreadsheet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/Spreadsheet.png -------------------------------------------------------------------------------- /quantum/images/bg-gradient-sand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/images/bg-gradient-sand.png -------------------------------------------------------------------------------- /quantum/css/OpenSans-Bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Bold-webfont.eot -------------------------------------------------------------------------------- /quantum/css/OpenSans-Bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Bold-webfont.ttf -------------------------------------------------------------------------------- /quantum/css/OpenSans-Bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Bold-webfont.woff -------------------------------------------------------------------------------- /quantum/css/OpenSans-Light-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Light-webfont.eot -------------------------------------------------------------------------------- /quantum/css/OpenSans-Light-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Light-webfont.ttf -------------------------------------------------------------------------------- /quantum/css/OpenSans-Light-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/css/OpenSans-Light-webfont.woff -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/apple/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/apple/bg.jpg -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/apple/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/apple/d.png -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/classic/d.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/classic/d.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/classic/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/classic/d.png -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default/d.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default/d.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default/d.png -------------------------------------------------------------------------------- /quantum/modevlib/gui/Progress.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | (function(){ 4 | 5 | // 6 | 7 | 8 | 9 | 10 | 11 | 12 | })(); 13 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/_namespace.pvc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Namespace with protovis chart components. 3 | * @name pvc 4 | * @namespace 5 | */ -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/.jshintignore: -------------------------------------------------------------------------------- 1 | src/js/common/bootstrap_tooltip_popover.js 2 | src/js/layout/bootstrap_dropdown.js 3 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcBarPanel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Bar Panel. 3 | */ 4 | def 5 | .type('pvc.BarPanel', pvc.BarAbstractPanel) 6 | .add({ 7 | }); -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/apple/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/apple/throbber.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default-rtl/d.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default-rtl/d.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default-rtl/d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default-rtl/d.png -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/apple/dot_for_ie.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/apple/dot_for_ie.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/classic/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/classic/throbber.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default-rtl/dots.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default-rtl/dots.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default/throbber.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/classic/dot_for_ie.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/classic/dot_for_ie.gif -------------------------------------------------------------------------------- /quantum/lib/jstree/themes/default-rtl/throbber.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jstree/themes/default-rtl/throbber.gif -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/images/divider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/metrics-graphics/examples/images/divider.png -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/images/og-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/metrics-graphics/examples/images/og-logo.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/animated-overlay.gif -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_0078ae_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_0078ae_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_056b93_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_056b93_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_d8e7f3_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_d8e7f3_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_e0fdff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_e0fdff_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_f5e175_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_f5e175_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_f7a50d_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_f7a50d_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-icons_fcd113_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-icons_fcd113_256x240.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_flat_55_999999_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_flat_55_999999_40x100.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_flat_75_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_flat_75_aaaaaa_40x100.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_glass_45_0078ae_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_glass_45_0078ae_1x400.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_glass_55_f8da4e_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_glass_55_f8da4e_1x400.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_glass_75_79c9ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_glass_75_79c9ec_1x400.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png -------------------------------------------------------------------------------- /quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozilla/charts/HEAD/quantum/lib/jquery-ui/css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png -------------------------------------------------------------------------------- /quantum/modevlib/gui/README.md: -------------------------------------------------------------------------------- 1 | 2 | There are serious issues with this directory of classes. 3 | 4 | * GUI.js is responsible for some of the simpler GUI parameter inputs. These should be broken out into their own classes. 5 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | 4 | other/divider.psd 5 | 6 | other/htaccess.txt 7 | 8 | .DS_Store 9 | 10 | bare.html 11 | /.svn 12 | .idea 13 | *.iml 14 | libs 15 | import.js 16 | npm-debug.log 17 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/src/js/common/register.js: -------------------------------------------------------------------------------- 1 | function register(chartType, descriptor, defaults) { 2 | MG.charts[chartType] = { 3 | descriptor: descriptor, 4 | defaults: defaults || {} 5 | }; 6 | } 7 | 8 | MG.register = register; 9 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcNormalizedBarPanel.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Normalized Bar Panel. 4 | */ 5 | def 6 | .type('pvc.NormalizedBarPanel', pvc.BarAbstractPanel) 7 | .add({ 8 | _barVerticalMode: function(){ 9 | return 'expand'; 10 | } 11 | }); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "$": false, 4 | "jQuery": false, 5 | "MG": false, 6 | "d3": false 7 | }, 8 | "laxbreak": true, 9 | "validthis": true, 10 | "loopfunc": true, 11 | "sub": true 12 | } 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | .git 3 | .idea 4 | *.iml 5 | out 6 | html/es/lib/jstree/_lib 7 | html/es/lib/jstree/_docs 8 | html/es/lib/jstree/_demo 9 | /docs/2.1 vs 2.0 as of 2014-09-08.xlsx 10 | /docs/2.1 vs 2.0.xlsx 11 | /tests/__pycache__ 12 | /tests/*.pyc 13 | /.env 14 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | script: npm run test-ci 5 | notifications: 6 | irc: 7 | channels: 8 | - "irc.mozilla.org#metrics" 9 | on_success: change 10 | on_failure: always 11 | use_notice: true 12 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcCategoricalAbstractPanel.js: -------------------------------------------------------------------------------- 1 | 2 | def 3 | .type('pvc.CategoricalAbstractPanel', pvc.CartesianAbstractPanel) 4 | .init(function(chart, parent, plot, options){ 5 | 6 | this.base(chart, parent, plot, options); 7 | 8 | this.stacked = plot.option('Stacked'); 9 | }); -------------------------------------------------------------------------------- /quantum/modevlib/util/aTest.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | importScript("../debug/aLog.js"); 4 | 5 | assert = {}; 6 | 7 | (function(){ 8 | 9 | assert.equal = function(test, expected, errorMessage){ 10 | if (test==expected) return; 11 | 12 | Log.error(errorMessage); 13 | }; 14 | 15 | 16 | 17 | 18 | })(); 19 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/BarPlot.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes a bar plot. 4 | * 5 | * @name pvc.visual.BarPlot 6 | * @class Represents a bar plot. 7 | * @extends pvc.visual.BarPlotAbstract 8 | */ 9 | def 10 | .type('pvc.visual.BarPlot', pvc.visual.BarPlotAbstract) 11 | .add({ 12 | type: 'bar' 13 | }); -------------------------------------------------------------------------------- /quantum/js/chart_lib.js: -------------------------------------------------------------------------------- 1 | 2 | importScript([ 3 | '../modevlib/main.js', 4 | '../modevlib/Dimension-Bugzilla.js', 5 | "../modevlib/Dimension-Quantum.js", 6 | "../js/grid.js", 7 | "../modevlib/gui/accordion.js", 8 | "../modevlib/gui/dynamic.js", 9 | "../modevlib/gui/aColor.js", 10 | "blockerCharts.js", 11 | "nominationCharts.js", 12 | "regressionCharts.js", 13 | "blockers.css" 14 | ]); 15 | -------------------------------------------------------------------------------- /quantum/modevlib/util/aHTML.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | 7 | //REPRESENT RAW HTML 8 | function HTML(html){ 9 | this.html=html; 10 | } 11 | 12 | HTML.prototype.toString=function HTML_toString(){ 13 | return this.html; 14 | }; 15 | 16 | 17 | -------------------------------------------------------------------------------- /quantum/modevlib/util/aParse.js: -------------------------------------------------------------------------------- 1 | 2 | parse = {}; 3 | 4 | parse.URL = function parseURL(url){ 5 | var parser = document.createElement('a'); 6 | parser.href = url; 7 | return { 8 | "scheme": parser.protocol, 9 | "host": parser.hostname, 10 | "port": convert.String2Integer(parser.port), 11 | "path": parser.pathname, 12 | "params": convert.URLParam2Object(parser.search.slice(1)), 13 | "fragment": convert.URLParam2Object(parser.hash.slice(1)) 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/misc/process_test.js: -------------------------------------------------------------------------------- 1 | module('process'); 2 | 3 | test('args.missing_is_zero doesn\'t throw a "args.data[0][0] is undefined" error', function() { 4 | var data = [{"date": new Date('2014-02-02'), "value": 6}]; 5 | var params = { 6 | data: data, 7 | target: "#qunit-fixture", 8 | missing_is_zero: true 9 | }; 10 | 11 | MG.data_graphic(params); 12 | 13 | equal(params.data.length, 1, 'args.data is defined'); 14 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/CartesianAxisRootScene.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes an axis root scene. 4 | * 5 | * @name pvc.visual.CartesianAxisRootScene 6 | * 7 | * @extends pvc.visual.Scene 8 | * 9 | * @constructor 10 | * @param {pvc.visual.Scene} [parent] The parent scene, if any. 11 | * @param {object} [keyArgs] Keyword arguments. 12 | * See {@link pvc.visual.Scene} for supported keyword arguments. 13 | */ 14 | def 15 | .type('pvc.visual.CartesianAxisRootScene', pvc.visual.Scene); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/css/metricsgraphics-demo-accessible.css: -------------------------------------------------------------------------------- 1 | html { 2 | font-size: 16px; 3 | } 4 | 5 | .mg-x-axis text, 6 | .mg-y-axis text, 7 | .mg-histogram .axis text { 8 | opacity: 0.9; 9 | } 10 | 11 | .mg-x-axis line, 12 | .mg-y-axis line { 13 | opacity: 1; 14 | } 15 | 16 | .mg-markers text, 17 | .mg-year-marker text, 18 | .mg-baselines text { 19 | opacity: 0.9; 20 | } 21 | 22 | .mg-markers line, 23 | .mg-year-marker line, 24 | .mg-baselines line { 25 | opacity: 1; 26 | } -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/css/addons/mg_line_brushing.css: -------------------------------------------------------------------------------- 1 | .mg-brush-container { 2 | cursor: crosshair; } 3 | 4 | .mg-brush-container.mg-brushing { 5 | cursor: ew-resize; } 6 | 7 | .mg-brushed, .mg-brushed * { 8 | cursor: zoom-out !important; } 9 | 10 | .mg-brush rect.mg-extent { 11 | fill: rgba(0, 0, 0, 0.3); } 12 | 13 | .mg-brushing-in-progress { 14 | -webkit-touch-callout: none; 15 | -webkit-user-select: none; 16 | -khtml-user-select: none; 17 | -moz-user-select: none; 18 | -ms-user-select: none; 19 | user-select: none; } 20 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/helpers.js: -------------------------------------------------------------------------------- 1 | function generateMouseEvent(type) { 2 | var event = document.createEvent('MouseEvent'); 3 | event.initEvent(type, true, true); 4 | return event; 5 | } 6 | 7 | // essentially the same as $.extend 8 | function extend(){ 9 | var result = {}, 10 | $__arguments = [].slice.call(arguments); 11 | 12 | $__arguments.forEach(function(obj) { 13 | for (var prop in obj) { 14 | if (obj.hasOwnProperty(prop)) { 15 | result[prop] = obj[prop]; 16 | } 17 | } 18 | }); 19 | return result; 20 | } 21 | -------------------------------------------------------------------------------- /quantum/modevlib/main.js: -------------------------------------------------------------------------------- 1 | 2 | importScript("aLibrary.js"); 3 | importScript("Settings.js"); 4 | 5 | importScript("MozillaPrograms.js"); 6 | importScript("rest/BugzillaClient.js"); 7 | importScript("rest/ElasticSearch.js"); 8 | importScript("qb/ActiveDataQuery.js"); 9 | importScript("Bugzilla.js"); 10 | importScript("charts/cccChart.js"); 11 | importScript("charts/aColor.js"); 12 | importScript([ 13 | "gui/GUI.js", 14 | "../css/menu.css" 15 | ]); 16 | importScript("Hierarchy.js"); 17 | importScript("math/Stats.js"); 18 | importScript("qb/qb.js"); 19 | importScript("ScrumBugs.js"); 20 | 21 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/src/js/misc/error.js: -------------------------------------------------------------------------------- 1 | // call this to add a warning icon to a graph and log an error to the console 2 | function error(args) { 3 | console.error('ERROR : ', args.target, ' : ', args.error); 4 | 5 | d3.select(args.target).select('.mg-chart-title') 6 | .append('tspan') 7 | .attr('class', 'fa fa-x fa-exclamation-circle mg-warning') 8 | .attr('dx', '0.3em') 9 | .text('\uf06a'); 10 | } 11 | 12 | function internal_error(args) { 13 | console.error('INTERNAL ERROR : ', args.target, ' : ', args.internal_error); 14 | } 15 | 16 | MG.error = error; 17 | -------------------------------------------------------------------------------- /quantum/modevlib/aLibrary.js: -------------------------------------------------------------------------------- 1 | importScript("util/aUtil.js"); 2 | importScript("collections/aArray.js"); 3 | importScript("collections/aQueue.js"); 4 | importScript("collections/aSet.js"); 5 | importScript("collections/aRelation.js"); 6 | importScript("math/aMath.js"); 7 | importScript("util/aString.js"); 8 | importScript("util/aHTML.js"); 9 | importScript("util/convert.js"); 10 | importScript("util/aDate.js"); 11 | importScript("util/aDuration.js"); 12 | importScript("util/aTimer.js"); 13 | importScript("util/aTemplate.js"); 14 | 15 | 16 | importScript([ 17 | "debug/aLog.js", 18 | "threads/thread.js" 19 | ]); 20 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/neg2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "measure": 43.34, 4 | "subject": 32.0 5 | }, 6 | { 7 | "measure": 53.3423, 8 | "subject": 20.27 9 | }, 10 | { 11 | "measure": -10.343, 12 | "subject": 12.42 13 | }, 14 | { 15 | "measure": -1, 16 | "subject": -1.69 17 | }, 18 | { 19 | "measure": 10, 20 | "subject": -10.01 21 | }, 22 | { 23 | "measure": 25, 24 | "subject": -21.59 25 | }, 26 | { 27 | "measure": -20.343, 28 | "subject": -31.86 29 | } 30 | ] -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/small-range.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "date": "2014-01-01", 4 | "value": 1 5 | }, 6 | { 7 | "date": "2014-01-02", 8 | "value": 3 9 | }, 10 | { 11 | "date": "2014-01-03", 12 | "value": 2 13 | }, 14 | { 15 | "date": "2014-01-04", 16 | "value": 2 17 | }, 18 | { 19 | "date": "2014-01-05", 20 | "value": 2 21 | }, 22 | { 23 | "date": "2014-01-06", 24 | "value": 1 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /quantum/modevlib/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | [*] 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | indent_style = space 11 | indent_size = 2 12 | 13 | [*.js] 14 | indent_style = tab 15 | indent_size = 4 16 | 17 | [*.json] 18 | indent_style = tab 19 | indent_size = 4 20 | 21 | [*.css] 22 | indent_style = tab 23 | indent_size = 4 24 | 25 | [*.html] 26 | indent_style = tab 27 | indent_size = 4 28 | 29 | [*.{diff,md}] 30 | trim_trailing_whitespace = false 31 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/xnotdate.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "males": 50, 4 | "females": 12 5 | }, 6 | { 7 | "males": 95, 8 | "females": 66 9 | }, 10 | { 11 | "males": 143, 12 | "females": 89 13 | }, 14 | { 15 | "males": 198, 16 | "females": 105 17 | }, 18 | { 19 | "males": 244, 20 | "females": 533 21 | }, 22 | { 23 | "males": 277, 24 | "females": 175 25 | }, 26 | { 27 | "males": 344, 28 | "females": 401 29 | }, 30 | { 31 | "males": 441, 32 | "females": 1299 33 | } 34 | ] 35 | -------------------------------------------------------------------------------- /quantum/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [*.js] 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [*.json] 20 | indent_style = tab 21 | indent_size = 2 22 | 23 | [*.css] 24 | indent_style = space 25 | indent_size = 4 26 | 27 | [*.html] 28 | indent_style = space 29 | indent_size = 2 30 | 31 | [*.{diff,md}] 32 | trim_trailing_whitespace = false 33 | -------------------------------------------------------------------------------- /quantum/modevlib/aFormat.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | importScript([ 6 | "util/aString.js", 7 | "../lib/jquery.js", 8 | "../lib/jquery.numberformatter.js" 9 | ]); 10 | 11 | var aFormat={}; 12 | 13 | 14 | (function(){ 15 | aFormat.number=function(value, format){ 16 | if (format.trim().left(1)=="+"){ 17 | //FORCE PLUS SIGN 18 | if (value<=0) format="+"+format.rightBut(1); 19 | }//endif 20 | 21 | return $.formatNumber(value, {"format":format}); 22 | };//method 23 | 24 | 25 | aFormat.json=function(json){ 26 | if (typeof(json)!="string") return convert.value2json(json); 27 | return convert.value2json(convert.json2value(json)); 28 | };//method 29 | 30 | })(); 31 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | indent_style = space 13 | indent_size = 4 14 | 15 | [*.js] 16 | indent_style = space 17 | indent_size = 2 18 | 19 | [*.hbs] 20 | indent_style = space 21 | indent_size = 4 22 | 23 | [*.css] 24 | indent_style = space 25 | indent_size = 4 26 | 27 | [*.html] 28 | indent_style = space 29 | indent_size = 4 30 | 31 | [*.{diff,md}] 32 | trim_trailing_whitespace = false 33 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/BulletPlot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Initializes a bullet plot. 3 | * 4 | * @name pvc.visual.BulletPlot 5 | * @class Represents a bullet plot. 6 | * @extends pvc.visual.Plot 7 | */ 8 | def 9 | .type('pvc.visual.BulletPlot', pvc.visual.Plot) 10 | .add({ 11 | type: 'bullet', 12 | 13 | _getOptionsDefinition: function(){ 14 | return pvc.visual.BulletPlot.optionsDef; 15 | } 16 | }); 17 | 18 | pvc.visual.BulletPlot.optionsDef = def.create( 19 | pvc.visual.Plot.optionsDef, { 20 | ValuesVisible: { // override 21 | value: true 22 | }, 23 | 24 | ColorRole: { 25 | value: null 26 | } 27 | }); -------------------------------------------------------------------------------- /quantum/js/main_lib.js: -------------------------------------------------------------------------------- 1 | 2 | importScript("../modevlib/aLibrary.js"); 3 | importScript("../modevlib/Settings.js"); 4 | 5 | importScript("../modevlib/rest/BugzillaClient.js"); 6 | importScript("../modevlib/rest/ElasticSearch.js"); 7 | importScript("../modevlib/qb/ESQuery.js"); 8 | importScript("../modevlib/Bugzilla.js"); 9 | importScript([ 10 | "../modevlib/gui/GUI.js", 11 | "../css/menu.css" 12 | ]); 13 | 14 | importScript("../modevlib/math/Stats.js"); 15 | importScript("../modevlib/qb/qb.js"); 16 | 17 | importScript([ 18 | 'blockers.css', 19 | '../modevlib/Dimension-Bugzilla.js', 20 | "../modevlib/Dimension-Quantum.js", 21 | "../modevlib/charts/aColor.js", 22 | "hierarchy.js", 23 | "heat.js" 24 | ]); 25 | 26 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcTitlePanel.js: -------------------------------------------------------------------------------- 1 | 2 | def 3 | .type('pvc.TitlePanel', pvc.TitlePanelAbstract) 4 | .init(function(chart, parent, options){ 5 | 6 | if(!options){ 7 | options = {}; 8 | } 9 | 10 | var isV1Compat = chart.compatVersion() <= 1; 11 | if(isV1Compat){ 12 | var size = options.titleSize; 13 | if(size == null){ 14 | options.titleSize = 25; 15 | } 16 | } 17 | 18 | // Must be done before calling base, cause it uses _getExtension 19 | this._extensionPrefix = !chart.parent ? "title" : "smallTitle"; 20 | 21 | this.base(chart, parent, options); 22 | }) 23 | .add({ 24 | 25 | font: "14px sans-serif", 26 | 27 | defaultPaddings: 4 28 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/sign/Label.js: -------------------------------------------------------------------------------- 1 | 2 | def.type('pvc.visual.Label', pvc.visual.Sign) 3 | .init(function(panel, protoMark, keyArgs){ 4 | 5 | var pvMark = protoMark.add(pv.Label); 6 | 7 | this.base(panel, pvMark, keyArgs); 8 | }) 9 | .add({ 10 | _addInteractive: function(keyArgs){ 11 | keyArgs = def.setDefaults(keyArgs, 12 | 'noSelect', true, 13 | 'noHover', true, 14 | 'noTooltip', true, 15 | 'noClick', true, 16 | 'noDoubleClick', true); 17 | 18 | this.base(keyArgs); 19 | }, 20 | 21 | defaultColor: function(type){ 22 | return pv.Color.names.black; 23 | } 24 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/CartesianAxisTickScene.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes an axis tick scene. 4 | * 5 | * @name pvc.visual.CartesianAxisTickScene 6 | * 7 | * @extends pvc.visual.Scene 8 | * 9 | * @constructor 10 | * @param {pvc.visual.CartesianAxisRootScene} [parent] The parent scene, if any. 11 | * @param {object} [keyArgs] Keyword arguments. 12 | * See {@link pvc.visual.Scene} for supported keyword arguments. 13 | */ 14 | def 15 | .type('pvc.visual.CartesianAxisTickScene', pvc.visual.Scene) 16 | .init(function(parent, keyArgs){ 17 | 18 | this.base(parent, keyArgs); 19 | 20 | this.vars.tick = new pvc.visual.ValueLabelVar( 21 | def.get(keyArgs, 'tick'), 22 | def.get(keyArgs, 'tickLabel'), 23 | def.get(keyArgs, 'tickRaw')); 24 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/sign/Panel.js: -------------------------------------------------------------------------------- 1 | 2 | def.type('pvc.visual.Panel', pvc.visual.Sign) 3 | .init(function(panel, protoMark, keyArgs){ 4 | var pvPanel = def.get(keyArgs, 'panel'); 5 | if(!pvPanel){ 6 | var pvPanelType = def.get(keyArgs, 'panelType') || pv.Panel; 7 | 8 | pvPanel = protoMark.add(pvPanelType); 9 | } 10 | 11 | this.base(panel, pvPanel, keyArgs); 12 | }) 13 | .add({ 14 | _addInteractive: function(keyArgs){ 15 | var t = true; 16 | keyArgs = def.setDefaults(keyArgs, 17 | 'noSelect', t, 18 | 'noHover', t, 19 | 'noTooltip', t, 20 | 'noClick', t, 21 | 'noDoubleClick', t); 22 | 23 | this.base(keyArgs); 24 | } 25 | }); -------------------------------------------------------------------------------- /quantum/modevlib/charts/README.md: -------------------------------------------------------------------------------- 1 | Proposed Chart API 2 | ================== 3 | 4 | Yet another chart API! The priorities are: 5 | 6 | 1. No magic labels or prefixes - A surprising number APIs use a concatenation- 7 | of-names to inject parameter values. We will perfer the use of objects for compound values. 8 | 2. Use CSS style names - except when CSS names break rule #1 9 | 3. `data` is assumed to be an Array of Objects, or a qb query result. 10 | 4. `value` is can be a property name, or a qb expression 11 | 12 | If two, or more, charts share the same `axis` (as in `===`), they are 13 | considered *linked*, and act as a single chart. Use the [`$ref` property](https://github.com/klahnakoski/pyLibrary/tree/dev/pyLibrary/jsons#) to 14 | define a shared axis. 15 | 16 | 17 | [Link to the chart schema](chartSchema.md) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/NormalizedBarPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes a normalized bar plot. 5 | * 6 | * @name pvc.visual.NormalizedBarPlot 7 | * @class Represents a normalized bar plot. 8 | * @extends pvc.visual.BarPlotAbstract 9 | */ 10 | def 11 | .type('pvc.visual.NormalizedBarPlot', pvc.visual.BarPlotAbstract) 12 | .add({ 13 | type: 'bar', 14 | _getOptionsDefinition: function(){ 15 | return pvc.visual.NormalizedBarPlot.optionsDef; 16 | } 17 | }); 18 | 19 | pvc.visual.NormalizedBarPlot.optionsDef = def.create( 20 | pvc.visual.BarPlotAbstract.optionsDef, 21 | { 22 | Stacked: { 23 | resolve: null, 24 | value: true 25 | } 26 | }); 27 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcPlotBgPanel.js: -------------------------------------------------------------------------------- 1 | 2 | def 3 | .type('pvc.PlotBgPanel', pvc.BasePanel) 4 | .init(function(chart, parent, options) { 5 | // Prevent the border from affecting the box model, 6 | // providing a static 0 value, independently of the actual drawn value... 7 | //this.borderWidth = 0; 8 | 9 | this.base(chart, parent, options); 10 | 11 | //this._extensionPrefix = "plotBg"; 12 | }) 13 | .add({ 14 | anchor: 'fill', 15 | 16 | _getExtensionId: function(){ 17 | return 'plotBg'; 18 | }, 19 | 20 | _createCore: function(layoutInfo) { 21 | // Send the panel behind grid rules 22 | this.pvPanel 23 | .borderPanel 24 | .lock('zOrder', -13) 25 | .antialias(false) 26 | ; 27 | 28 | this.base(layoutInfo); 29 | } 30 | }); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/missing-y.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "date": "2014-01-08", 5 | "value": 500 6 | }, 7 | { 8 | "date": "2014-01-12", 9 | "value": 500 10 | }, 11 | { 12 | "date": "2014-01-19", 13 | "value": 2000 14 | }, 15 | { 16 | "date": "2014-01-20", 17 | "value": 2200 18 | }, 19 | { 20 | "date": "2014-01-21", 21 | "value": 2300 22 | }, 23 | { 24 | "date": "2014-04-23", 25 | "value": 500 26 | }, 27 | { 28 | "date": "2014-04-24", 29 | "value": 1500 30 | }, 31 | { 32 | "date": "2014-04-25", 33 | "value": 3000 34 | } 35 | ] 36 | -------------------------------------------------------------------------------- /quantum/modevlib/util/aTimer.js: -------------------------------------------------------------------------------- 1 | importScript("aDate.js"); 2 | importScript("aDuration.js"); 3 | importScript("../debug/aLog.js"); 4 | 5 | 6 | var aTimer=function(){}; 7 | 8 | //PROVIDE warningDuration IF ONLY NEED TO PRINT TIMES LONGER THAN GIVEN 9 | aTimer.start=function(name, warningDuration){ 10 | var t=new aTimer(); 11 | t.warningDuration=warningDuration==undefined ? undefined : warningDuration.getMilli(); 12 | t.name=name; 13 | t.start=window.performance.now(); 14 | return t; 15 | };//method 16 | 17 | aTimer.prototype.end=function(){ 18 | var end=window.performance.now(); 19 | var dur=Duration.newInstance(end-this.start); 20 | if (this.warningDuration===undefined){ 21 | Log.note(this.name+" ("+dur.toString()+")"); 22 | }else if (dur.getMilli()>this.warningDuration){ 23 | Log.warning(this.name+" ("+dur.toString()+")"); 24 | }//endif 25 | };//method 26 | 27 | aTimer.prototype.stop=aTimer.prototype.end; 28 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcAxisTitlePanel.js: -------------------------------------------------------------------------------- 1 | 2 | def 3 | .type('pvc.AxisTitlePanel', pvc.TitlePanelAbstract) 4 | .init(function(chart, parent, axis, options) { 5 | 6 | this.axis = axis; 7 | 8 | this.base(chart, parent, options); 9 | 10 | this._extensionPrefix = 11 | axis 12 | .extensionPrefixes 13 | .map(function(prefix){ 14 | return prefix + 'Title'; 15 | }); 16 | }) 17 | .add({ 18 | _calcLayout: function(layoutInfo){ 19 | var scale = this.axis.scale; 20 | if(!scale || scale.isNull){ 21 | return new pvc.Size(0, 0); 22 | } 23 | 24 | return this.base(layoutInfo); 25 | }, 26 | 27 | _createCore: function(layoutInfo){ 28 | var scale = this.axis.scale; 29 | if(!scale || scale.isNull){ 30 | return; 31 | } 32 | 33 | return this.base(layoutInfo); 34 | } 35 | }); 36 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/missing-is-hidden.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "date": "2014-01-08", 5 | "value": 500 6 | }, 7 | { 8 | "date": "2014-01-09", 9 | "value": 500 10 | }, 11 | { 12 | "date": "2014-01-10", 13 | "value": 400 14 | }, 15 | { 16 | "date": "2014-02-12", 17 | "value": 500 18 | }, 19 | { 20 | "date": "2014-02-13", 21 | "value": 100 22 | }, 23 | { 24 | "date": "2014-02-14", 25 | "value": null 26 | }, 27 | { 28 | "date": "2014-02-15", 29 | "value": 30 30 | }, 31 | { 32 | "date": "2014-02-16", 33 | "value": 300 34 | }, 35 | { 36 | "date": "2014-02-17", 37 | "value": 200 38 | } 39 | ] 40 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/MetricXYPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes an abstract metric XY plot. 5 | * 6 | * @name pvc.visual.MetricXYPlot 7 | * @class Represents an abstract metric XY plot. 8 | * @extends pvc.visual.CartesianPlot 9 | */ 10 | def 11 | .type('pvc.visual.MetricXYPlot', pvc.visual.CartesianPlot) 12 | .add({ 13 | _getOptionsDefinition: function(){ 14 | return pvc.visual.MetricXYPlot.optionsDef; 15 | } 16 | }); 17 | 18 | pvc.visual.MetricXYPlot.optionsDef = def.create( 19 | pvc.visual.CartesianPlot.optionsDef, { 20 | BaseRole: { // override 21 | value: 'x' 22 | }, 23 | 24 | OrthoAxis: { // override -> value 1 25 | resolve: null 26 | }, 27 | 28 | OrthoRole: { 29 | value: 'y' 30 | } 31 | }); 32 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/DataOper.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes a data operation. 4 | * 5 | * @name pvc.data.DataOper 6 | * 7 | * @class The base abstract class for a data operation. 8 | * Performs an initial query on the datums of the opertion's link parent 9 | * and hands the final implementation to a derived class. 10 | * 11 | * @property {string} key Set on construction with a value that identifies the operation. 12 | * 13 | * @constructor 14 | * 15 | * @param {pvc.data.Data} linkParent The link parent data. 16 | * @param {object} [keyArgs] Keyword arguments. 17 | */ 18 | def.type('pvc.data.DataOper') 19 | .init(function(linkParent, keyArgs){ 20 | this._linkParent = linkParent; 21 | }). 22 | add(/** @lends pvc.data.DataOper */{ 23 | 24 | key: null, 25 | 26 | /** 27 | * Performs the data operation. 28 | * 29 | * @returns {pvc.data.Data} The resulting root data. 30 | */ 31 | execute: def.method({isAbstract: true}) 32 | }); 33 | -------------------------------------------------------------------------------- /quantum/modevlib/QuantumFlowBugs.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | var QuantumFlowBugs = { 7 | "columns": ["projectName", "attributeName", "attributeValue", "esfilter"], 8 | 9 | "rows": [ 10 | ["Quantum Flow - Triage", "status_whiteboard.tokenized", "qf"], 11 | ["Quantum Flow - P1", "status_whiteboard.tokenized", "qf:p1"], 12 | ["Quantum Flow - P3", "status_whiteboard.tokenized", "qf:p3"], 13 | ["Quantum Flow - P5", "status_whiteboard.tokenized", "qf:p5"], 14 | ["Quantum Flow - Investigate", "status_whiteboard.tokenized", "qf:investigate"], 15 | ["Quantum Flow - Investigate - P1", "status_whiteboard.tokenized", "qf:investigate:p1"], 16 | ["Quantum Flow - Meta", "status_whiteboard.tokenized", "qf:meta"], 17 | ["Quantum Flow - N/A", "status_whiteboard.tokenized", "qf-"] 18 | ] 19 | }; 20 | -------------------------------------------------------------------------------- /quantum/modevlib/Dimension-Jobs.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | importScript("Dimension.js"); 6 | 7 | if (!Mozilla) var Mozilla = {"name": "Mozilla", "edges": []}; 8 | 9 | (function(){ 10 | var pastWeek = {"gt": {"build.date": Date.today().subtract(Duration.MONTH).unix()}}; 11 | 12 | Dimension.addEdges(false, Mozilla, [ 13 | {"name": "Timings", "index": "jobs.action.timings", "edges": [ 14 | {"name": "Platform", "field": "build.platform", "type": "set", "sample": pastWeek, "limit":100}, 15 | {"name": "Product", "field": "build.product", "type": "set", "sample": pastWeek, "limit":100}, 16 | {"name": "Suite", "field": "run.suite", "type": "set", "sample": pastWeek, "limit":100}, 17 | {"name": "Pool", "field": "run.machine.pool", "type": "set", "sample": pastWeek, "limit":100} 18 | ]} 19 | ]); 20 | 21 | 22 | })(); 23 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/CategoricalPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes an abstract categorical plot. 5 | * 6 | * @name pvc.visual.CategoricalPlot 7 | * @class Represents an abstract categorical plot. 8 | * @extends pvc.visual.CartesianPlot 9 | */ 10 | def 11 | .type('pvc.visual.CategoricalPlot', pvc.visual.CartesianPlot) 12 | .add({ 13 | _getOptionsDefinition: function(){ 14 | return pvc.visual.CategoricalPlot.optionsDef; 15 | } 16 | }); 17 | 18 | pvc.visual.CategoricalPlot.optionsDef = def.create( 19 | pvc.visual.CartesianPlot.optionsDef, { 20 | 21 | Stacked: { 22 | resolve: '_resolveFull', 23 | cast: Boolean, 24 | value: false 25 | }, 26 | 27 | BaseRole: { 28 | value: 'category' 29 | }, 30 | 31 | OrthoRole: { // override 32 | value: 'value' 33 | } 34 | }); 35 | }); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metrics-graphics", 3 | "main": [ 4 | "dist/metricsgraphics.js", 5 | "dist/metricsgraphics.css" 6 | ], 7 | "dependencies": { 8 | "d3": ">=4" 9 | }, 10 | "ignore": [ 11 | ".DS_Store", 12 | ".git", 13 | ".gitignore", 14 | "examples", 15 | "gulp", 16 | "gulpfile.js", 17 | "index.js", 18 | "node_modules", 19 | "package.json", 20 | "src", 21 | "testem.json", 22 | "tests" 23 | ], 24 | "license": "MPL-2.0", 25 | "authors": [ 26 | "Ali Almossawi", "Ali Almossawi (http://twitter.com/alialmossawi)>", 27 | "Hamilton Ulmer", "Hamilton Ulmer (http://twitter.com/hamiltonulmer)>" 28 | ], 29 | "homepage": "http://metricsgraphicsjs.org", 30 | "repository": { 31 | "type": "git", 32 | "url": "git://github.com/mozilla/metrics-graphics.git" 33 | }, 34 | "keywords": [ 35 | "metrics-graphics", 36 | "metricsgraphicsjs", 37 | "metricsgraphics", 38 | "metricsgraphics.js", 39 | "d3 charts" 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /quantum/modevlib/ESQueryRunner.js: -------------------------------------------------------------------------------- 1 | 2 | function ESQueryRunner(query, callback){ 3 | Thread.run(function*(){ 4 | yield(ESQuery.loadColumns(query)); 5 | var cubeQuery = new ESQuery(query); 6 | var data = yield(cubeQuery.run()); 7 | callback(data); 8 | }); 9 | }//method 10 | 11 | function ESQueryRunMany(queries, callback){ 12 | //ASSUME queries IS AN ARRAY 13 | Thread.run(function*(){ 14 | //LAUNCH ALL QUERIES 15 | var threads=[]; 16 | for(var i=0;i 12 | * The dimensions of this panel, upon each render, 13 | * provide bounds for drawing each bullet. 14 | *

15 | *

16 | * The properties of marks created as children of this panel will 17 | * receive a corresponding {@link pvc.visual.legend.BulletItemScene} 18 | * as first argument. 19 | *

20 | * 21 | * @name pvc.visual.legend.BulletItemRenderer#create 22 | * @function 23 | * @param {pvc.LegendPanel} legendPanel the legend panel 24 | * @param {pv.Panel} pvBulletPanel the protovis panel on which bullets are rendered. 25 | * @param {string} extensionPrefix The extension prefix to be used to build extension keys, without underscore. 26 | * @param {function} [wrapper] extension wrapper function to apply to created marks. 27 | * 28 | * @type undefined 29 | */ -------------------------------------------------------------------------------- /quantum/modevlib/Dimension-Performance.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | importScript("Dimension.js"); 6 | 7 | if (!Mozilla) var Mozilla = {"name": "Mozilla", "edges": []}; 8 | 9 | Dimension.addEdges(false, Mozilla, [ 10 | {"name": "Performance", "index": "perf", "edges": [ 11 | {"name": "Product", "field": "build.product", "type": "set", "limit": 1000}, 12 | {"name": "BuildType", "field": "build.type", "type": "set", "limit": 1000}, 13 | {"name": "Branch", "field": "build.branch", "type": "set", "limit": 1000}, 14 | {"name": "Platform", "field": "build.platform", "type": "set", "limit": 1000}, 15 | { 16 | "name": "OS", 17 | "field": ["run.machine.os", "run.machine.osversion"], 18 | "type": "set", 19 | "limit": 1000 20 | }, 21 | {"name": "Test", "field": ["run.suite", "result.test"], "type": "set", "limit": 1000, "esfilter": {"range": {"build.date": {"gt": Date.today().subtract(Duration.newInstance("month")).getMilli()}}}}, 22 | {"name": "Revision", "field": "build.revision", "type": "uid"} 23 | ]} 24 | ]); 25 | -------------------------------------------------------------------------------- /quantum/js/burndown.js: -------------------------------------------------------------------------------- 1 | function bugDetails(bugs) { 2 | 3 | var hasPriority=false; 4 | 5 | bugs.forall(function (b) { 6 | b.bugLink = Bugzilla.linkToBug(b.bug_id); 7 | hasPriority = hasPriority || (b.status !==undefined && b.status!=null); 8 | }); 9 | 10 | var output = new Template([ 11 | "", 12 | "", 13 | "", 14 | "", 15 | "", 16 | hasPriority ? "" : "", 17 | "", 18 | "", 19 | "", 20 | { 21 | "from":".", 22 | "template":[ 23 | "" + 24 | "" + 25 | "" + 26 | "" + 27 | (hasPriority ? "" : "")+ 28 | "" + 29 | "" 30 | ] 31 | }, 32 | "", 33 | "
IDSummaryStatus
Owner
PriorityEstimate
{{bugLink}}
{{summary|html}}
{{status}}:
{{owner|html}}
{{priority}}
{{estimate}}
" 34 | ]).expand(bugs); 35 | 36 | return output; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /quantum/lib/jquery-linedtextarea/jquery-linedtextarea-license.txt: -------------------------------------------------------------------------------- 1 | Open Source Initiative OSI - The MIT License:Licensing 2 | 3 | The MIT License 4 | 5 | Copyright (c) 2010 Alan Williamson http://alan.blog-city.com/ 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | http://www.opensource.org/licenses/mit-license.php -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/legend/BulletItemSceneVisibility.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @name pvc.visual.legend.BulletItemSceneVisibility 4 | * 5 | * @class A visibility behavior mixin for a legend bullet item scene. 6 | * Represents and controls the visible state of its datums. 7 | * 8 | * @extends pvc.visual.legend.BulletItemScene 9 | */ 10 | def 11 | .type('pvc.visual.legend.BulletItemSceneVisibility') 12 | .add(/** @lends pvc.visual.legend.BulletItemSceneVisibility# */{ 13 | /** 14 | * Returns true if at least one non-null datum of the scene's {@link #datums} is visible. 15 | * @type boolean 16 | */ 17 | isOn: function(){ 18 | return this.datums().any(function(datum){ 19 | return !datum.isNull && datum.isVisible; 20 | }); 21 | }, 22 | 23 | /** 24 | * Returns true. 25 | * @type boolean 26 | */ 27 | isClickable: function(){ 28 | return true; 29 | }, 30 | 31 | /** 32 | * Toggles the visible state of the datums present in this scene 33 | * and forces a re-render of the chart (without reloading data). 34 | */ 35 | click: function(){ 36 | if(pvc.data.Data.toggleVisible(this.datums())){ 37 | // Re-render chart 38 | this.chart().render(true, true, false); 39 | } 40 | } 41 | }); 42 | -------------------------------------------------------------------------------- /quantum/modevlib/collections/aSet.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | importScript("../util/aUtil.js"); 7 | importScript("aArray.js"); 8 | 9 | 10 | 11 | var aSet=function(data){ 12 | if (this.VERIFY_INSTANCE!=aSet.VERIFY_INSTANCE){ 13 | Log.error("Expecting to be called using 'new'"); 14 | }//endif 15 | this.map={}; 16 | if (data!==undefined) 17 | this.addArray(data); 18 | }; 19 | 20 | 21 | (function(){ 22 | aSet.VERIFY_INSTANCE={}; 23 | aSet.prototype.VERIFY_INSTANCE=aSet.VERIFY_INSTANCE; 24 | 25 | aSet.prototype.add=function(v){ 26 | this.map[v]=v; 27 | return this; 28 | }; 29 | 30 | aSet.prototype.addArray=function(a){ 31 | for(var i=a.length;i--;){ 32 | var v=a[i]; 33 | this.map[v]=v; 34 | }//for 35 | return this; 36 | }; 37 | 38 | aSet.prototype.remove=function(v){ 39 | this.map[v]=undefined; 40 | return this; 41 | }; 42 | 43 | aSet.prototype.getArray=function(){ 44 | return Map.getValues(this.map); 45 | }; 46 | 47 | aSet.prototype.contains=function(v){ 48 | return this.map[v]!==undefined; 49 | }; 50 | 51 | aSet.prototype.map=function(func){ 52 | return this.getArray().mapExists(func); 53 | }; 54 | 55 | 56 | })(); 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/missing-is-hidden-accessor.json: -------------------------------------------------------------------------------- 1 | 2 | [ 3 | { 4 | "date": "2014-01-08", 5 | "value": 500 6 | }, 7 | { 8 | "date": "2014-01-09", 9 | "value": 500 10 | }, 11 | { 12 | "date": "2014-01-10", 13 | "value": 400 14 | }, 15 | { 16 | "date": "2014-01-11", 17 | "value": 500, 18 | "dead": true 19 | }, 20 | { 21 | "date": "2014-01-12", 22 | "value": 400 23 | }, 24 | { 25 | "date": "2014-01-13", 26 | "value": 430 27 | }, 28 | { 29 | "date": "2014-01-14", 30 | "value": 410 31 | }, 32 | { 33 | "date": "2014-01-15", 34 | "value": 200, 35 | "dead": true 36 | }, 37 | { 38 | "date": "2014-01-16", 39 | "value": 500 40 | }, 41 | { 42 | "date": "2014-01-17", 43 | "value": 100 44 | }, 45 | { 46 | "date": "2014-01-18", 47 | "value": 30 48 | }, 49 | { 50 | "date": "2014-01-19", 51 | "value": 300 52 | }, 53 | { 54 | "date": "2014-01-20", 55 | "value": 200 56 | } 57 | ] 58 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "src_files": [ 4 | "node_modules/jquery/dist/jquery.js", 5 | "node_modules/d3/build/d3.js", 6 | 7 | "src/js/MG.js", 8 | "src/js/misc/utility.js", 9 | "src/js/common/register.js", 10 | "src/js/common/hooks.js", 11 | "src/js/common/data_graphic.js", 12 | "src/js/common/bootstrap_tooltip_popover.js", 13 | "src/js/common/chart_title.js", 14 | "src/js/common/y_axis.js", 15 | "src/js/common/x_axis.js", 16 | "src/js/common/init.js", 17 | "src/js/common/scales.js", 18 | "src/js/common/rollover.js", 19 | "src/js/common/markers.js", 20 | "src/js/common/window_listeners.js", 21 | "src/js/layout/bootstrap_dropdown.js", 22 | "src/js/layout/button.js", 23 | "src/js/charts/line.js", 24 | "src/js/charts/histogram.js", 25 | "src/js/charts/point.js", 26 | "src/js/charts/bar.js", 27 | "src/js/charts/table.js", 28 | "src/js/charts/missing.js", 29 | "src/js/misc/process.js", 30 | "src/js/misc/smoothers.js", 31 | "src/js/misc/formatters.js", 32 | "src/js/misc/transitions.js", 33 | "src/js/misc/error.js", 34 | 35 | "tests/helpers.js", 36 | 37 | "tests/**/*_test.js" 38 | ], 39 | "launch_in_ci": [ 40 | "PhantomJS" 41 | ], 42 | "launch_in_dev": [ 43 | "PhantomJS", 44 | "Chrome" 45 | ], 46 | "phantomjs_debug_port": 9000 47 | } 48 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/src/js/common/hooks.js: -------------------------------------------------------------------------------- 1 | /** 2 | Record of all registered hooks. 3 | For internal use only. 4 | */ 5 | MG._hooks = {}; 6 | 7 | /** 8 | Add a hook callthrough to the stack. 9 | 10 | Hooks are executed in the order that they were registered. 11 | */ 12 | MG.add_hook = function(name, func, context) { 13 | var hooks; 14 | 15 | if (!MG._hooks[name]) { 16 | MG._hooks[name] = []; 17 | } 18 | 19 | hooks = MG._hooks[name]; 20 | 21 | var already_registered = 22 | hooks.filter(function(hook) { 23 | return hook.func === func; 24 | }) 25 | .length > 0; 26 | 27 | if (already_registered) { 28 | throw 'That function is already registered.'; 29 | } 30 | 31 | hooks.push({ 32 | func: func, 33 | context: context 34 | }); 35 | }; 36 | 37 | /** 38 | Execute registered hooks. 39 | 40 | Optional arguments 41 | */ 42 | MG.call_hook = function(name) { 43 | var hooks = MG._hooks[name], 44 | result = [].slice.apply(arguments, [1]), 45 | processed; 46 | 47 | if (hooks) { 48 | hooks.forEach(function(hook) { 49 | if (hook.func) { 50 | var params = processed || result; 51 | 52 | if (params && params.constructor !== Array) { 53 | params = [params]; 54 | } 55 | 56 | params = [].concat.apply([], params); 57 | processed = hook.func.apply(hook.context, params); 58 | } 59 | }); 60 | } 61 | 62 | return processed || result; 63 | }; 64 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/ComplexView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Initializes a complex view instance. 3 | * 4 | * @name pvc.data.ComplexView 5 | * 6 | * @class Represents a view of certain dimensions over a given source complex instance. 7 | * @extends pvc.data.Complex 8 | * 9 | * @property {pvc.data.Complex} source The source complex instance. 10 | * @property {string} label The composite label of the own atoms in the view. 11 | * @constructor 12 | * @param {pvc.data.Complex} source The source complex instance. 13 | * @param {string[]} viewDimNames The dimensions that should be revealed by the view. 14 | */ 15 | def.type('pvc.data.ComplexView', pvc.data.Complex) 16 | .init(function(source, viewDimNames){ 17 | 18 | this.source = source; 19 | 20 | this.viewDimNames = viewDimNames; 21 | 22 | /* Collect desired source atoms */ 23 | var sourceAtoms = source.atoms, 24 | ownSourceAtoms = []; 25 | 26 | viewDimNames.forEach(function(dimName){ 27 | if(def.hasOwnProp.call(sourceAtoms, dimName)){ 28 | ownSourceAtoms[dimName] = sourceAtoms[dimName]; 29 | } 30 | }); 31 | 32 | // Call base constructor 33 | this.base(source, ownSourceAtoms, viewDimNames, source.owner.atoms, /* wantLabel */ true); 34 | }) 35 | .add({ 36 | values: function(){ 37 | return pvc.data.Complex.values(this, this.viewDimNames); 38 | }, 39 | labels: function(){ 40 | return pvc.data.Complex.labels(this, this.viewDimNames); 41 | } 42 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcPlotPanel.js: -------------------------------------------------------------------------------- 1 | 2 | def 3 | .type('pvc.PlotPanel', pvc.BasePanel) 4 | .init(function(chart, parent, plot, options) { 5 | // Prevent the border from affecting the box model, 6 | // providing a static 0 value, independently of the actual drawn value... 7 | //this.borderWidth = 0; 8 | 9 | this.base(chart, parent, options); 10 | 11 | this.plot = plot; 12 | this._extensionPrefix = plot.extensionPrefixes; 13 | this.dataPartValue = plot.option('DataPart'); 14 | this.axes.color = chart.getAxis('color', plot.option('ColorAxis') - 1); 15 | this.orientation = plot.option('Orientation' ); 16 | this.valuesVisible = plot.option('ValuesVisible'); 17 | this.valuesAnchor = plot.option('ValuesAnchor' ); 18 | this.valuesMask = plot.option('ValuesMask' ); 19 | this.valuesFont = plot.option('ValuesFont' ); 20 | 21 | this.chart._addPlotPanel(this); 22 | }) 23 | .add({ 24 | anchor: 'fill', 25 | 26 | _getExtensionId: function(){ 27 | // chart is deprecated 28 | var extensionIds = ['chart', 'plot']; 29 | if(this.plotName){ 30 | extensionIds.push(this.plotName); 31 | } 32 | 33 | return extensionIds; 34 | }, 35 | 36 | /* @override */ 37 | isOrientationVertical: function(){ 38 | return this.orientation === pvc.orientation.vertical; 39 | }, 40 | 41 | /* @override */ 42 | isOrientationHorizontal: function(){ 43 | return this.orientation === pvc.orientation.horizontal; 44 | } 45 | }); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/HOOKS.md: -------------------------------------------------------------------------------- 1 | # Hooks 2 | ### Global 3 | | Name | args | Description | 4 | |------|------|-------------| 5 | | `global.defaults` | `defaults` | Passes the global defaults prior to merging with args and chart-specific defaults | 6 | | `global.before_init` | `args` | Called before initializing a chart. Allows pre-processing of the arguments passed into `MG.data_graphic`. | 7 | | `x_axis.process_min_max` | `args`, `min_x`, `max_x` | Called after calculating the min and max values for the X axis | 8 | | `y_axis.process_min_max` | `args`, `min_y`, `max_y` | Called after calculating the min and max values for the Y axis | 9 | 10 | ### Line 11 | | Name | args | Description | Notes | 12 | |------|------|-------------|-------| 13 | | `line.after_init` | `lineChart` - chart descriptor | Called after intializing the chart | | 14 | | `line.after_rollover` | `args` | Called after setting up the rollover | | 15 | | `line.before_all_series` | `args` | Called before rendering the chart. | Returning `false` will prevent the default rendering process from being executed. | 16 | | `line.before_each_series` | `data[i]` - The current data in the for loop
`args` | Called within the render loop, before any other render takes place. | | 17 | | `line.after_each_series` | `data[i]` - The current data in the for loop
`args` | Called within the render loop, after the default render has taken place. | | 18 | | `line.before_destroy` | `lineChart` - chart descriptor | Called before destroying the chart on a subsequent call to the same target element. | Available as of v2.10 | 19 | -------------------------------------------------------------------------------- /quantum/lib/d3/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2010-2016 Mike Bostock 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of contributors may be used to 15 | endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /quantum/modevlib/util/State.js: -------------------------------------------------------------------------------- 1 | importScript("aParse.js"); 2 | importScript("convert.js"); 3 | 4 | 5 | window.Session = window.Session || function(){ 6 | }; 7 | 8 | (function(){ 9 | 10 | var state={}; 11 | 12 | Session.get = function(field){ 13 | return Map.get(state, field); 14 | }; 15 | 16 | Session.set = function(field, value){ 17 | return Map.set(state, field, value); 18 | }; 19 | 20 | Session.URL = function(){ 21 | }; 22 | 23 | Session.URL.getFragment = function(){ 24 | //GET WHOLE FRAGMENT, AS OBJECT 25 | var url = parse.URL(window.location.href); 26 | return url.fragment; 27 | }; 28 | 29 | Session.URL.setFragment = function(value){ 30 | //SET WHOLE FRAGMENT, OLD VALUES ARE LOST 31 | var url = parse.URL(window.location.href); 32 | url.fragment = value; 33 | window.history.replaceState(url, "", serialize(url)) 34 | }; 35 | 36 | Session.URL.set = function(field, value){ 37 | //SET JUST ONE FRAGMENT PARAMETER 38 | var url = parse.URL(window.location.href); 39 | Map.set(url.fragment, field, value); 40 | 41 | var newURL = serialize(url); 42 | window.history.replaceState(url, "", newURL) 43 | }; 44 | 45 | 46 | function serialize(url){ 47 | //var newURL = url.scheme + "://" + url.host; 48 | //if (url.port) newURL += ":" + url.port; 49 | var newURL = url.path.split("/").last(); 50 | if (url.param && Map.getKeys(url.param).length>0) newURL += "?" + convert.Object2URLParam(url.param); 51 | if (url.fragment && Map.getKeys(url.fragment).length>0) newURL += "#" + convert.Object2URLParam(url.fragment); 52 | 53 | return newURL; 54 | } 55 | 56 | })(); 57 | -------------------------------------------------------------------------------- /quantum/lib/jquery-linedtextarea/jquery-linedtextarea.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | JQuery LinedTextArea Demo 4 | 5 | 6 | 7 | 8 | 9 | 10 |

JQuery LinedTextArea Demo

11 | 12 |

Add a scrollable lined area to a standard TextArea control.

13 | 14 | 34 | 35 | 42 | 43 |

Visit http://alan.blog-city.com/jquerylinedtextarea.htm for details and download

44 | 45 | 46 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcAbstract.js: -------------------------------------------------------------------------------- 1 | def 2 | .type('pvc.Abstract') 3 | .init(function(){ 4 | this._syncLog(); 5 | }) 6 | .add({ 7 | invisibleLineWidth: 0.001, 8 | defaultLineWidth: 1.5, 9 | 10 | _logInstanceId: null, 11 | 12 | _syncLog: function(){ 13 | if (pvc.debug && typeof console !== "undefined"){ 14 | var logId = this._getLogInstanceId(); 15 | 16 | ['log', 'info', ['trace', 'debug'], 'error', 'warn', 'group', 'groupEnd'].forEach(function(ps){ 17 | ps = ps instanceof Array ? ps : [ps, ps]; 18 | 19 | pvc._installLog(this, '_' + ps[0], ps[1], logId); 20 | }, this); 21 | } 22 | }, 23 | 24 | _getLogInstanceId: function(){ 25 | return this._logInstanceId || 26 | (this._logInstanceId = this._processLogInstanceId(this._createLogInstanceId())); 27 | }, 28 | 29 | _createLogInstanceId: function(){ 30 | return '' + this.constructor; 31 | }, 32 | 33 | _processLogInstanceId: function(logInstanceId){ 34 | var L = 30; 35 | var s = logInstanceId.substr(0, L); 36 | if(s.length < L){ 37 | s += def.array.create(L - s.length, ' ').join(''); 38 | } 39 | 40 | return "[" + s + "]"; 41 | } 42 | }); 43 | 44 | def.scope(function(){ 45 | var o = pvc.Abstract.prototype; 46 | var syncLogHook = function(){ this._syncLog(); }; 47 | 48 | ['log', 'info', 'trace', 'error', 'warn', 'group', 'groupEnd'].forEach(function(p){ 49 | o['_' + p] = syncLogHook; 50 | }); 51 | }); 52 | 53 | -------------------------------------------------------------------------------- /quantum/modevlib/graph/topologicalSort.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // This Source Code Form is subject to the terms of the Mozilla Public 3 | // License, v. 2.0. If a copy of the MPL was not distributed with this 4 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | //////////////////////////////////////////////////////////////////////////////// 6 | // Author: Kyle Lahnakoski (kyle@lahnakoski.com) 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | 10 | function toposort(edges, nodes){ 11 | /* 12 | edges IS AN ARRAY OF [parent, child] PAIRS 13 | nodes IS AN OPTIONAL ARRAY OF ALL NODES 14 | */ 15 | if (!nodes){ 16 | nodes = uniqueNodes(edges); 17 | }//endif 18 | var numNodes = nodes.length; 19 | var sorted = new Array(numNodes); 20 | var visited = {}; 21 | 22 | function visit(node, i, predecessors){ 23 | if (predecessors.indexOf(node) >= 0) { 24 | Log.error(node + " found in loop" + JSON.stringify(predecessors)) 25 | }//endif 26 | 27 | if (visited[i]) return; 28 | visited[i] = true; 29 | 30 | edges.forEach(function(edge, i){ 31 | if (edge[1] !== node) return; 32 | visit(edge[0], i, predecessors + [node]) 33 | }); 34 | sorted[--numNodes] = node; 35 | }//function 36 | 37 | for(var i=numNodes;i--;){ 38 | if (!visited[i]) visit(nodes[i], i, []) 39 | }//for 40 | return sorted; 41 | } 42 | 43 | function uniqueNodes(arr){ 44 | var res = []; 45 | arr.forEach(function(edge){ 46 | if (!res.contains[edge[0]]) res.push(edge[0]); 47 | if (!res.contains[edge[1]]) res.push(edge[1]); 48 | }); 49 | return res; 50 | }//function 51 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/common/resize_test.js: -------------------------------------------------------------------------------- 1 | module('resize'); 2 | 3 | test("Resize does not leak listeners", function () { 4 | // Instrument window event listener methods 5 | var realWindowAddEventListener = window.addEventListener; 6 | var realWindowRemoveEventListener = window.removeEventListener; 7 | var resizeListeners = []; 8 | 9 | window.addEventListener = function () { 10 | if (arguments[0] === 'resize' && resizeListeners.indexOf(arguments[1]) === -1) { 11 | resizeListeners.push(arguments[1]); 12 | } 13 | realWindowAddEventListener.apply(this, arguments); 14 | } 15 | 16 | window.removeEventListener = function () { 17 | if (arguments[0] === 'resize') { 18 | var index = resizeListeners.indexOf(arguments[1]); 19 | if (index !== -1) { 20 | resizeListeners.splice(index, 1); 21 | } 22 | } 23 | realWindowRemoveEventListener.apply(this, arguments); 24 | } 25 | 26 | var params = { 27 | target: '#qunit-fixture', 28 | full_width: true, 29 | data: [{'date': new Date('2014-11-01'), 'value': 12}, 30 | {'date': new Date('2014-11-02'), 'value': 18}], 31 | height: 100 32 | }; 33 | MG.data_graphic(params); 34 | var listenerCountAfterOne = resizeListeners.length; 35 | const REPEAT_CREATE = 20; 36 | for (var i = 0; i < REPEAT_CREATE; i++) { 37 | MG.data_graphic(params); 38 | } 39 | equal(resizeListeners.length, listenerCountAfterOne, "Listener count constant after chart recreated " + REPEAT_CREATE + " times"); 40 | 41 | // Restore default methods 42 | window.addEventListener = realWindowAddEventListener; 43 | window.removeEventListener = realWindowRemoveEventListener; 44 | }); 45 | -------------------------------------------------------------------------------- /quantum/lib/jquery-linedtextarea/jquery-linedtextarea.css: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery Lined Textarea Plugin 3 | * http://alan.blog-city.com/jquerylinedtextarea.htm 4 | * 5 | * Copyright (c) 2010 Alan Williamson 6 | * 7 | * Contribution done by Ryan Zielke (neoalchemy@gmail.com) 8 | * 9 | * Released under the MIT License: 10 | * http://www.opensource.org/licenses/mit-license.php 11 | * 12 | * Usage: 13 | * Displays a line number count column to the left of the textarea 14 | * 15 | * Class up your textarea with a given class, or target it directly 16 | * with JQuery Selectors 17 | * 18 | * $(".lined").linedtextarea({ 19 | * selectedLine: 10, 20 | * selectedClass: 'lineselect' 21 | * }); 22 | * 23 | */ 24 | 25 | textarea { resize:both; } 26 | 27 | .linedwrap { 28 | border: 1px solid #c0c0c0; 29 | padding: 3px; 30 | display: inline-block; 31 | } 32 | 33 | .linedtextarea { 34 | padding: 0px; 35 | margin: 0px; 36 | } 37 | 38 | .linedtextarea textarea, .linedwrap .codelines .lineno { 39 | font-size: 10pt; 40 | font-family: monospace; 41 | line-height: normal !important; 42 | } 43 | 44 | .linedtextarea textarea { 45 | padding-right:0.3em; 46 | padding-top:0.3em; 47 | border: 0; 48 | } 49 | 50 | .linedwrap .lines { 51 | margin-top: 0px; 52 | width: 50px; 53 | float: left; 54 | overflow: hidden; 55 | border-right: 1px solid #c0c0c0; 56 | margin-right: 10px; 57 | } 58 | 59 | .linedwrap .codelines { 60 | padding-top: 5px; 61 | } 62 | 63 | .linedwrap .codelines .lineno { 64 | color:#AAAAAA; 65 | padding-right: 0.5em; 66 | padding-top: 0.0em; 67 | text-align: right; 68 | white-space: nowrap; 69 | } 70 | 71 | .linedwrap .codelines .lineselect { 72 | color: red; 73 | } 74 | -------------------------------------------------------------------------------- /quantum/modevlib/ScrumBugs.js: -------------------------------------------------------------------------------- 1 | 2 | importScript("aLibrary.js"); 3 | 4 | 5 | var ScrumBugs={}; 6 | 7 | 8 | 9 | (function(){ 10 | var noMatch=[undefined, undefined]; 11 | 12 | var pointsPattern=/[\[\s,]p[=:]([\d\.]+)[ ,\]]/; 13 | var componentPattern=/[\[\s,]c[=:](\w+)[ ,\]]/; 14 | var featurePattern=/[\[\s,](feature|ft)[=:](\w+)[ ,\]]/; 15 | var userPattern=/[\[\s,]u[=:](\w+)[ ,\]]/; 16 | 17 | 18 | function getDates(whiteboard){ 19 | var dates=whiteboard.between("feature=iteration", ")")+")"; 20 | var startDate=Date.newInstance(dates.between("(", "-")); 21 | var endDate=Date.newInstance(dates.between("-", ")")); 22 | 23 | }//method 24 | 25 | 26 | ScrumBugs.parse=function(whiteboard){ 27 | whiteboard=whiteboard+" "; 28 | var output={ 29 | "feature":coalesce(featurePattern.exec(whiteboard), noMatch)[1], 30 | "component":coalesce(componentPattern.exec(whiteboard), noMatch)[1], 31 | "user":coalesce(userPattern.exec(whiteboard), noMatch)[1], 32 | "points":coalesce((pointsPattern.exec(whiteboard)), noMatch)[1] 33 | }; 34 | if (output.feature=="iteration"){ 35 | //feature=iteration (May 02, 2013 - May 23, 2013) 36 | var dates=whiteboard.between("feature=iteration", ")")+")"; 37 | output.startDate=Date.newInstance(dates.between("(", "-")); 38 | output.endDate=Date.newInstance(dates.between("-", ")")); 39 | }//endif 40 | 41 | 42 | return output; 43 | };//method 44 | 45 | var TEST = false; 46 | if (TEST){ 47 | var white = "[est:4d, p=4][coordination]"; 48 | ASSERT(ScrumBugs.parse(white).points == 4, "Wrong"); 49 | 50 | white="[p=3, est:3d, 1.5:p2, ft:webrtc]"; 51 | ASSERT(ScrumBugs.parse(white).points == 3, "Wrong"); 52 | 53 | }//endif 54 | 55 | 56 | })(); 57 | 58 | 59 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "metrics-graphics", 3 | "version": "2.10.1", 4 | "description": "A library optimized for concise, principled data graphics and layouts", 5 | "main": "dist/metricsgraphics.js", 6 | "scripts": { 7 | "build": "gulp build:js", 8 | "test": "gulp test", 9 | "test-ci": "./node_modules/testem/testem.js ci testem.json" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/mozilla/metrics-graphics.git" 14 | }, 15 | "keywords": [ 16 | "metrics-graphics", 17 | "metricsgraphicsjs", 18 | "metricsgraphics", 19 | "metricsgraphics.js", 20 | "d3 charts" 21 | ], 22 | "author": "Mozilla", 23 | "contributors": [ 24 | "Ali Almossawi (http://twitter.com/alialmossawi)", 25 | "Hamilton Ulmer (http://twitter.com/hamiltonulmer)" 26 | ], 27 | "license": "MPL-2.0", 28 | "bugs": { 29 | "url": "https://github.com/mozilla/metrics-graphics/issues" 30 | }, 31 | "engines": { 32 | "node": ">=0.8.0" 33 | }, 34 | "homepage": "http://metricsgraphicsjs.org", 35 | "dependencies": { 36 | "d3": "^4" 37 | }, 38 | "peerDependencies": { 39 | "jquery": ">=1.11.1" 40 | }, 41 | "devDependencies": { 42 | "jquery": ">=1.11.1", 43 | "gulp": "^3.8.10", 44 | "gulp-concat": "^2.4.2", 45 | "gulp-connect": "^2.2.0", 46 | "gulp-es6-module-transpiler": "^0.2.0", 47 | "gulp-jshint": "^1.9.0", 48 | "gulp-rename": "^1.2.0", 49 | "gulp-rimraf": "^0.1.1", 50 | "gulp-testem": "0.0.1", 51 | "gulp-uglify": "^1.0.2", 52 | "gulp-umd": "^0.1.3", 53 | "gulp-util": "^3.0.1", 54 | "qunitjs": "^1.16.0", 55 | "require-dir": "^0.1.0", 56 | "testem": "^0.6.24" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/translation/BoxplotChartTranslationOper.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @name pvc.data.BoxplotChartTranslationOper 4 | * 5 | * @class The translation mixin operation of the box plot chart. 6 | * 7 | *

8 | * The default box plot format is: 9 | *

10 | *
11 |  * +----------+----------+--------------+--------------+------------+-------------+
12 |  * | 0        | 1        | 2            | 3            | 4          | 5           |
13 |  * +----------+----------+--------------+--------------+------------+-------------+
14 |  * | category | median   | lowerQuartil | upperQuartil | minimum    | maximum     |
15 |  * +----------+----------+--------------+--------------+------------+-------------+
16 |  * | any      | number   | number       | number       | number     | number      |
17 |  * +----------+----------+--------------+--------------+------------+-------------+
18 |  * 
19 | * 20 | * @extends pvc.data.MatrixTranslationOper 21 | */ 22 | def.type('pvc.data.BoxplotChartTranslationOper') 23 | .add(/** @lends pvc.data.BoxplotChartTranslationOper# */{ 24 | /** 25 | * @override 26 | */ 27 | _configureTypeCore: function(){ 28 | var autoDimNames = []; 29 | 30 | var V = this.virtualItemSize(); 31 | var C = V - this.M; 32 | 33 | this._getUnboundRoleDefaultDimNames('category', C, autoDimNames); 34 | 35 | pvc.BoxplotChart.measureRolesNames.forEach(function(roleName){ 36 | this._getUnboundRoleDefaultDimNames(roleName, 1, autoDimNames); 37 | }, this); 38 | 39 | autoDimNames.slice(0, this.freeVirtualItemSize()); 40 | if(autoDimNames.length){ 41 | this.defReader({names: autoDimNames}); 42 | } 43 | } 44 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | charts 2 | ====== 3 | Static pages for [charts.mozilla.org](http://charts.mozilla.org/) The summary 4 | of the this project is found on [the Mozilla wiki](https://wiki.mozilla.org/Auto-tools/Projects/Charts#Overview_of_charts.mozilla.org) 5 | 6 | 7 | Prerequisits 8 | ------------ 9 | 10 | You should be able to reach the public cluster. My people page has [a test page to confirm public cluster is accessible](http://people.mozilla.org/~klahnakoski/modevmetrics/Tutorial01-Minimum.html). 11 | 12 | 13 | Setup 14 | ----- 15 | 16 | Simply clone from Github. 17 | 18 | https://github.com/klahnakoski/MoDevMetrics.git 19 | 20 | You can then open the files with your browser 21 | 22 | 23 | Contribution 24 | ------------ 25 | 26 | There are three main branches 27 | 28 | * [master](https://github.com/mozilla/charts/tree/master) - deployed to production: charts.mozilla.org 29 | * [allizom](https://github.com/mozilla/charts/tree/allizom) - deployed to staging: charts.paas.allizom.org 30 | * [dev](https://github.com/mozilla/charts/tree/dev) - active development: **add you pull requests here** 31 | 32 | Other branches may exist which are working on new dashboards for other teams in the company. 33 | 34 | ###Submitting a Patch 35 | At a bare minimum: 36 | 37 | * fork this repo 38 | * craft your changes, and 39 | * send a pull request 40 | 41 | Extra appreciation is granted if you also 42 | 43 | * update the corresponding bugzilla bug with an attachment pointing to the 44 | pull request 45 | 46 | Using Github pull requests for code submission, and Bugzilla for issue 47 | tracking, is clunky: So stick to the Github if you find this is a nasty 48 | barrier to getting stuff done. What's most important is you submit code! 49 | I will deal with the administration. 50 | 51 | -------------------------------------------------------------------------------- /quantum/modevlib/collections/aRelation.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | 7 | //GOOD FOR MANY-MANY RELATIONS 8 | var Relation=function(){ 9 | this.map={}; 10 | }; 11 | 12 | Relation.prototype.add=function(from, to){ 13 | if (!this.map[from]) this.map[from]={}; 14 | this.map[from][to]=1; 15 | return this; 16 | }; 17 | 18 | 19 | //RETURN TRUE IF THIS RELATION IS NET-NEW 20 | Relation.prototype.testAndAdd=function(from, to){ 21 | var isNew=true; 22 | var f=this.map[from]; 23 | if (!f){ 24 | this.map[from]=Map.newInstance(to, 1); 25 | }else if (f[to]){ 26 | isNew=false; 27 | }else{ 28 | f[to]=1; 29 | }//endif 30 | return isNew; 31 | }; 32 | 33 | Relation.prototype.domain = function(){ 34 | return Object.keys(this.map); 35 | }; 36 | 37 | Relation.prototype.addArray=function(from, toArray){ 38 | var f=this.map[from]; 39 | if (!f){ 40 | f={}; 41 | this.map[from]=f; 42 | }//endif 43 | 44 | for(var i=toArray.length;i--;){ 45 | var c=toArray[i]; 46 | if (c===undefined || c==null || c=="") continue; 47 | f[c]=1; 48 | }//for 49 | return this; 50 | }; 51 | 52 | //RETURN AN ARRAY OF OBJECTS THAT from MAPS TO 53 | Relation.prototype.get=function(from){ 54 | var o=this.map[from]; 55 | if (!o) return []; 56 | return Object.keys(o); 57 | }; 58 | 59 | //RETURN AN ARRAY OF OBJECTS THAT from MAPS TO 60 | Relation.prototype.getMap=function(from){ 61 | return this.map[from]; 62 | }; 63 | 64 | Relation.prototype.forall=function(func){ 65 | var keys=Object.keys(this.map); 66 | for(var i=0;i 2 |
3 |
4 | 5 | 6 |
d3.json('data/fake_users3.json', function(data) {
 7 |     for(var i = 0; i < data.length; i++) {
 8 |         data[i] = MG.convert.date(data[i], 'date');
 9 |     }
10 | 
11 |     MG.data_graphic({
12 |         title: "Preserving the aspect ratio",
13 |         description: "You can automatically set the width or height of a data graphic to fit its parent element. When done the graphic will rescale to fit the size of the parent element while preserving its aspect ratio.",
14 |         data: data,
15 |         full_width: true,
16 |         height: 300,
17 |         right: 40,
18 |         x_extended_ticks: true,
19 |         target: '#aspect1',
20 |         x_accessor: 'date',
21 |         y_accessor: 'value'
22 |     });
23 | });
24 | 25 |
26 | 27 | 28 | 49 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/legend/BulletItemSceneSelection.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @name pvc.visual.legend.BulletItemSceneSelection 3 | * @class A selection behavior mixin for the legend bullet item scene. 4 | * Represents and controls the selected state of its datums. 5 | * 6 | * @extends pvc.visual.legend.BulletItemScene 7 | */ 8 | def 9 | .type('pvc.visual.legend.BulletItemSceneSelection') 10 | .add(/** @lends pvc.visual.legend.BulletItemSceneSelection# */{ 11 | /** 12 | * Returns true if there are no selected datums in the owner data, 13 | * or if at least one non-null datum of the scene's {@link #datums} is selected. 14 | * @type boolean 15 | */ 16 | isOn: function(){ 17 | var owner = (this.group || this.datum).owner; 18 | return !owner.selectedCount() || 19 | this.datums().any(function(datum){ 20 | return !datum.isNull && datum.isSelected; 21 | }); 22 | 23 | // Cannot use #isSelected() cause it includes null datums. 24 | //return this.isSelected(); 25 | }, 26 | 27 | /** 28 | * Returns true if the chart is selectable by clicking. 29 | * @type boolean 30 | */ 31 | isClickable: function(){ 32 | return this.chart()._canSelectWithClick(); 33 | }, 34 | 35 | /** 36 | * Toggles the selected state of the datums present in this scene 37 | * and updates the chart if necessary. 38 | */ 39 | click: function(){ 40 | var datums = this.datums().array(); 41 | if(datums.length){ 42 | var chart = this.chart(); 43 | chart._updatingSelections(function(){ 44 | datums = chart._onUserSelection(datums); 45 | if(datums){ 46 | var on = def.query(datums).any(function(datum){ return datum.isSelected; }); 47 | pvc.data.Data.setSelected(datums, !on); 48 | } 49 | }); 50 | } 51 | } 52 | }); 53 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/MetricPointPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes a metric XY plot. 5 | * 6 | * @name pvc.visual.MetricPointPlot 7 | * @class Represents a metric point plot. 8 | * @extends pvc.visual.MetricXYPlot 9 | */ 10 | def 11 | .type('pvc.visual.MetricPointPlot', pvc.visual.MetricXYPlot) 12 | .add({ 13 | type: 'scatter', 14 | _getOptionsDefinition: function(){ 15 | return pvc.visual.MetricPointPlot.optionsDef; 16 | } 17 | }); 18 | 19 | function visibleData(type){ 20 | return { 21 | resolveV1: function(optionInfo){ 22 | this._specifyChartOption(optionInfo, 'show' + type); 23 | return true; 24 | } 25 | }; 26 | } 27 | 28 | pvc.visual.MetricPointPlot.optionsDef = def.create( 29 | pvc.visual.MetricXYPlot.optionsDef, { 30 | SizeRole: { 31 | resolve: '_resolveFixed', 32 | value: 'size' 33 | }, 34 | 35 | SizeAxis: { 36 | resolve: '_resolveFixed', 37 | value: 1 38 | }, 39 | 40 | Shape: { 41 | resolve: '_resolveFull', 42 | cast: pvc.parseShape, 43 | value: 'circle' 44 | }, 45 | 46 | DotsVisible: { 47 | resolve: '_resolveFull', 48 | data: visibleData('Dots'), 49 | cast: Boolean, 50 | value: false 51 | }, 52 | 53 | LinesVisible: { 54 | resolve: '_resolveFull', 55 | data: visibleData('Lines'), 56 | cast: Boolean, 57 | value: false 58 | }, 59 | 60 | ValuesAnchor: { // override 61 | value: 'right' 62 | } 63 | }); 64 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/legend/WaterfallBulletGroupScene.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes a waterfall legend bullet group scene. 4 | * 5 | * @name pvc.visual.legend.WaterfallBulletGroupScene 6 | 7 | * @extends pvc.visual.Scene 8 | * 9 | * @constructor 10 | * @param {pvc.visual.legend.BulletRootScene} parent The parent bullet root scene. 11 | * @param {object} [keyArgs] Keyword arguments. 12 | * See {@link pvc.visual.Scene} for additional keyword arguments. 13 | * @param {pv.visual.legend.renderer} [keyArgs.renderer] Keyword arguments. 14 | */ 15 | def 16 | .type('pvc.visual.legend.WaterfallBulletGroupScene', pvc.visual.Scene) 17 | .init(function(rootScene, keyArgs){ 18 | 19 | this.base(rootScene, keyArgs); 20 | 21 | this.extensionPrefix = def.get(keyArgs, 'extensionPrefix') || ''; 22 | 23 | var item = this.createItem({ 24 | value: null, 25 | rawValue: null, 26 | label: def.get(keyArgs, 'label') 27 | }); 28 | 29 | item.color = def.get(keyArgs, 'color'); 30 | }) 31 | .add(/** @lends pvc.visual.legend.WaterfallBulletGroupScene# */{ 32 | hasRenderer: function(){ 33 | return this._renderer; 34 | }, 35 | 36 | renderer: function(renderer){ 37 | if(renderer != null){ 38 | this._renderer = renderer; 39 | } 40 | 41 | return this._renderer; 42 | }, 43 | 44 | itemSceneType: function(){ 45 | var ItemType = this._itemSceneType; 46 | if(!ItemType){ 47 | ItemType = def.type(pvc.visual.legend.BulletItemScene); 48 | 49 | // Apply legend item scene extensions 50 | this.panel()._extendSceneType('item', ItemType, ['isOn', 'isClickable', 'click']); 51 | 52 | this._itemSceneType = ItemType; 53 | } 54 | 55 | return ItemType; 56 | }, 57 | 58 | createItem: function(keyArgs){ 59 | var ItemType = this.itemSceneType(); 60 | return new ItemType(this, keyArgs); 61 | } 62 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/WaterfallPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes a waterfall plot. 5 | * 6 | * @name pvc.visual.WaterfallPlot 7 | * @class Represents a waterfall plot. 8 | * @extends pvc.visual.BarPlotAbstract 9 | */ 10 | def 11 | .type('pvc.visual.WaterfallPlot', pvc.visual.BarPlotAbstract) 12 | .add({ 13 | type: 'water', 14 | _getOptionsDefinition: function(){ 15 | return pvc.visual.WaterfallPlot.optionsDef; 16 | } 17 | }); 18 | 19 | pvc.visual.WaterfallPlot.optionsDef = def.create( 20 | pvc.visual.BarPlotAbstract.optionsDef, 21 | { 22 | Stacked: { // override 23 | resolve: null, 24 | value: true 25 | }, 26 | 27 | TotalLineLabel: { 28 | resolve: '_resolveFull', 29 | cast: String, 30 | value: "Accumulated" 31 | }, 32 | 33 | TotalValuesVisible: { 34 | resolve: '_resolveFull', 35 | data: { 36 | // Dynamic default 37 | resolveDefault: function(optionInfo){ 38 | optionInfo.defaultValue(this.option('ValuesVisible')); 39 | return true; 40 | } 41 | }, 42 | cast: Boolean 43 | }, 44 | 45 | Direction: { // up/down 46 | resolve: '_resolveFull', 47 | cast: pvc.parseWaterDirection, 48 | value: 'down' 49 | }, 50 | 51 | AreasVisible: { 52 | resolve: '_resolveFull', 53 | cast: Boolean, 54 | value: true 55 | }, 56 | 57 | AllCategoryLabel: { 58 | resolve: '_resolveFull', 59 | cast: String, 60 | value: "All" 61 | } 62 | }); 63 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcBarAbstract.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * BarAbstract is the base class for generating charts of the bar family. 4 | */ 5 | def 6 | .type('pvc.BarAbstract', pvc.CategoricalAbstract) 7 | .init(function(options){ 8 | 9 | this.base(options); 10 | 11 | var parent = this.parent; 12 | if(parent) { 13 | this._valueRole = parent._valueRole; 14 | } 15 | }) 16 | .add({ 17 | // NOTE 18 | // Timeseries category with bar charts are supported differently in V2 than in V1 19 | // They worked in v1 if the data set brought all 20 | // categories, according to chosen timeseries scale date unit 21 | // Then, bars were drawn with a category scale, 22 | // whose positions ended up coinciding with the ticks in a linear axis... 23 | // To mimic v1 behavior the category dimensions are "coerced" to isDiscrete 24 | // The axis will be categoric, the parsing will work, 25 | // and the formatting will be the desired one 26 | 27 | /** 28 | * Initializes each chart's specific roles. 29 | * @override 30 | */ 31 | _initVisualRoles: function(){ 32 | 33 | this.base(); 34 | 35 | this._addVisualRole('value', { 36 | isMeasure: true, 37 | isRequired: true, 38 | isPercent: this.options.stacked, 39 | requireSingleDimension: true, 40 | requireIsDiscrete: false, 41 | valueType: Number, 42 | defaultDimension: 'value' 43 | }); 44 | 45 | this._valueRole = this.visualRoles('value'); 46 | }, 47 | 48 | _getCategoryRoleSpec: function(){ 49 | var catRoleSpec = this.base(); 50 | 51 | // Force dimension to be discrete! 52 | catRoleSpec.requireIsDiscrete = true; 53 | 54 | return catRoleSpec; 55 | }, 56 | 57 | _initData: function(){ 58 | this.base.apply(this, arguments); 59 | 60 | var data = this.data; 61 | 62 | // Cached 63 | this._valueDim = data.dimensions(this._valueRole.firstDimensionName()); 64 | } 65 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcPieChart.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * PieChart is the main class for generating... pie charts (surprise!). 4 | */ 5 | def 6 | .type('pvc.PieChart', pvc.BaseChart) 7 | .add({ 8 | 9 | pieChartPanel: null, 10 | 11 | _getColorRoleSpec: function(){ 12 | return { isRequired: true, defaultSourceRole: 'category', defaultDimension: 'color*', requireIsDiscrete: true }; 13 | }, 14 | 15 | /** 16 | * Initializes each chart's specific roles. 17 | * @override 18 | */ 19 | _initVisualRoles: function(){ 20 | 21 | this.base(); 22 | 23 | this._addVisualRole('category', { 24 | isRequired: true, 25 | defaultDimension: 'category*', 26 | autoCreateDimension: true 27 | }); 28 | 29 | this._addVisualRole('value', { 30 | isMeasure: true, 31 | isRequired: true, 32 | isPercent: true, 33 | requireSingleDimension: true, 34 | requireIsDiscrete: false, 35 | valueType: Number, 36 | defaultDimension: 'value' 37 | }); 38 | }, 39 | 40 | _initPlotsCore: function(hasMultiRole){ 41 | new pvc.visual.PiePlot(this); 42 | }, 43 | 44 | _preRenderContent: function(contentOptions) { 45 | 46 | this.base(); 47 | 48 | var isV1Compat = this.compatVersion() <= 1; 49 | if(isV1Compat){ 50 | var innerGap = pvc.castNumber(this.options.innerGap) || 0.95; 51 | innerGap = def.between(innerGap, 0.1, 1); 52 | contentOptions.paddings = ((1 - innerGap) * 100 / 2).toFixed(2) + "%"; 53 | } else if(contentOptions.paddings == null) { 54 | contentOptions.paddings = new pvc.PercentValue(0.025); 55 | } 56 | 57 | var piePlot = this.plots.pie; 58 | this.pieChartPanel = new pvc.PieChartPanel(this, this.basePanel, piePlot, def.create(contentOptions, { 59 | scenes: def.getPath(this.options, 'pie.scenes') 60 | })); 61 | } 62 | }); 63 | -------------------------------------------------------------------------------- /quantum/lib/d3/README.md: -------------------------------------------------------------------------------- 1 | # D3: Data-Driven Documents 2 | 3 | 4 | 5 | **D3** (or **D3.js**) is a JavaScript library for visualizing data using web standards. D3 helps you bring data to life using SVG, Canvas and HTML. D3 combines powerful visualization and interaction techniques with a data-driven approach to DOM manipulation, giving you the full capabilities of modern browsers and the freedom to design the right visual interface for your data. 6 | 7 | ## Resources 8 | 9 | * [API Reference](https://github.com/d3/d3/blob/master/API.md) 10 | * [Release Notes](https://github.com/d3/d3/releases) 11 | * [Gallery](https://github.com/d3/d3/wiki/Gallery) 12 | * [Examples](http://bl.ocks.org/mbostock) 13 | * [Wiki](https://github.com/d3/d3/wiki) 14 | 15 | ## Installing 16 | 17 | If you use NPM, `npm install d3`. Otherwise, download the [latest release](https://github.com/d3/d3/releases/latest). The released bundle supports anonymous AMD, CommonJS, and vanilla environments. You can load directly from [d3js.org](https://d3js.org), [CDNJS](https://cdnjs.com/libraries/d3), or [npmcdn](https://npmcdn.com/d3/). For example: 18 | 19 | ```html 20 | 21 | ``` 22 | 23 | For the minified version: 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can also use the standalone D3 microlibraries. For example, [d3-selection](https://github.com/d3/d3-selection): 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | D3 is written using [ES2015 modules](http://www.2ality.com/2014/09/es6-modules-final.html). Create a [custom bundle using Rollup](http://bl.ocks.org/mbostock/bb09af4c39c79cffcde4), Webpack, or your preferred bundler. To import D3 into an ES2015 application, either import specific symbols from specific D3 modules: 36 | 37 | ```js 38 | import {scaleLinear} from "d3-scale"; 39 | ``` 40 | 41 | Or import everything into a namespace (here, `d3`): 42 | 43 | ```js 44 | import * as d3 from "d3"; 45 | ``` 46 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/common/data_graphic_test.js: -------------------------------------------------------------------------------- 1 | module('data_graphic'); 2 | 3 | test('Required arguments are set', function() { 4 | var params = { 5 | target: '#qunit-fixture', 6 | data: [{'date': new Date('2014-11-01'), 'value': 12}, 7 | {'date': new Date('2014-11-02'), 'value': 18}] 8 | }; 9 | 10 | MG.data_graphic(params); 11 | 12 | ok(params.width, 'args.width is set'); 13 | ok(params.height, 'args.height is set'); 14 | ok(params.data, 'args.data is set'); 15 | ok(params.target, 'args.target is set'); 16 | }); 17 | 18 | test('Dom element works as target', function() { 19 | var params = { 20 | target: document.getElementById('qunit-fixture'), 21 | data: [{'date': new Date('2014-11-01'), 'value': 12}, 22 | {'date': new Date('2014-11-02'), 'value': 18}] 23 | }; 24 | 25 | MG.data_graphic(params); 26 | 27 | ok(document.querySelector('#qunit-fixture svg') != null, 'passing in dom element works properly'); 28 | }); 29 | 30 | // Can be removed in 2.x 31 | test('Correctly aliases callbacks when using 1.x-style method names', function() { 32 | var mouseoverCalled = false, 33 | mouseoutCalled = false, 34 | 35 | params = { 36 | target: '#qunit-fixture', 37 | data: [{value: 1, label: 'One'}], 38 | chart_type: 'bar', 39 | rollover_callback: function() { 40 | mouseoverCalled = true; 41 | }, 42 | rollout_callback: function() { 43 | mouseoutCalled = true; 44 | } 45 | }; 46 | 47 | MG.data_graphic(params); 48 | 49 | var bar = document.getElementsByClassName('mg-bar-rollover')[0]; 50 | 51 | bar.dispatchEvent(generateMouseEvent('mouseover')); 52 | equal(mouseoverCalled, true, 'rollover_callback was called'); 53 | 54 | bar.dispatchEvent(generateMouseEvent('mouseout')); 55 | equal(mouseoutCalled, true, 'rollout_callback was called'); 56 | 57 | ok(MG.deprecations.rollover_callback.warned, 'rollover_callback deprecation notice displayed'); 58 | ok(MG.deprecations.rollout_callback.warned, 'rollout_callback deprecation notice displayed'); 59 | }); 60 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/HeatGridPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes a heat grid plot. 5 | * 6 | * @name pvc.visual.HeatGridPlot 7 | * @class Represents a heat grid plot. 8 | * @extends pvc.visual.CategoricalPlot 9 | */ 10 | def 11 | .type('pvc.visual.HeatGridPlot', pvc.visual.CategoricalPlot) 12 | .add({ 13 | type: 'heatGrid', 14 | _getOptionsDefinition: function(){ 15 | return pvc.visual.HeatGridPlot.optionsDef; 16 | } 17 | }); 18 | 19 | pvc.visual.HeatGridPlot.optionsDef = def.create( 20 | pvc.visual.CategoricalPlot.optionsDef, 21 | { 22 | SizeRole: { 23 | value: 'size' 24 | }, 25 | 26 | SizeAxis: { 27 | value: 1 28 | }, 29 | 30 | UseShapes: { 31 | resolve: '_resolveFull', 32 | cast: Boolean, 33 | value: false 34 | }, 35 | 36 | Shape: { 37 | resolve: '_resolveFull', 38 | cast: pvc.parseShape, 39 | value: 'square' 40 | }, 41 | 42 | NullShape: { 43 | resolve: '_resolveFull', 44 | cast: pvc.parseShape, 45 | value: 'cross' 46 | }, 47 | 48 | ValuesVisible: { // override 49 | value: true 50 | }, 51 | 52 | OrthoRole: { // override 53 | value: 'series' 54 | }, 55 | 56 | OrthoAxis: { // override 57 | resolve: null 58 | }, 59 | 60 | // Not supported 61 | NullInterpolationMode: { 62 | resolve: null, 63 | value: 'none' 64 | }, 65 | 66 | // Not supported 67 | Stacked: { // override 68 | resolve: null, 69 | value: false 70 | } 71 | }); 72 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/data/bp.js: -------------------------------------------------------------------------------- 1 | var boxplotData_01 = { 2 | "resultset": [ 3 | ["product A", 50, 40, 60, 30, 70], 4 | ["product B", 80, 65, 95, 45, 110], 5 | ["product C", 50, 45, 56, 20, 63] 6 | ], 7 | "metadata": [{ 8 | "colIndex": 0, 9 | "colType": "String", 10 | "colName": "category" 11 | }, { 12 | "colIndex": 1, 13 | "colType": "Numeric", 14 | "colName": "median" 15 | }, { 16 | "colIndex": 2, 17 | "colType": "Numeric", 18 | "colName": "p25" 19 | }, { 20 | "colIndex": 3, 21 | "colType": "Numeric", 22 | "colName": "p75" 23 | }, { 24 | "colIndex": 4, 25 | "colType": "Numeric", 26 | "colName": "p5" 27 | }, { 28 | "colIndex": 5, 29 | "colType": "Numeric", 30 | "colName": "p95" 31 | } 32 | ] 33 | }; 34 | 35 | var boxplotData_02 = { 36 | "resultset": [ 37 | ["USA", "Product A", 50, 40, 60, 30, 70], 38 | ["USA", "Product B", 100, 30, 130, 10, 180], 39 | ["EU", "Product B", 80, 65, 95, 45, 110], 40 | ["EU", "Product C", 120, 45, 160, 20, 170] 41 | ], 42 | "metadata": [{ 43 | "colIndex": 0, 44 | "colType": "String", 45 | "colName": "Region" 46 | }, { 47 | "colIndex": 0, 48 | "colType": "String", 49 | "colName": "Product" 50 | }, { 51 | "colIndex": 1, 52 | "colType": "Numeric", 53 | "colName": "median" 54 | }, { 55 | "colIndex": 2, 56 | "colType": "Numeric", 57 | "colName": "p25" 58 | }, { 59 | "colIndex": 3, 60 | "colType": "Numeric", 61 | "colName": "p75" 62 | }, { 63 | "colIndex": 4, 64 | "colType": "Numeric", 65 | "colName": "p5" 66 | }, { 67 | "colIndex": 5, 68 | "colType": "Numeric", 69 | "colName": "p95" 70 | } 71 | ] 72 | }; 73 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/charts/addons.htm: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
<script src='js/addons/mg_line_brushing.js'></script>
 7 | <link rel='stylesheet' href='css/addons/mg_line_brushing.css' />
 8 | d3.json('data/fake_users2.json', function(data) {
 9 |     for (var i = 0; i < data.length; i++) {
10 |         data[i] = MG.convert.date(data[i], 'date');
11 |     }
12 | 
13 |     MG.data_graphic({
14 |         title: "Brushing Addon by Dan De Havilland",
15 |         description: "Drag the crosshair over the chart to zoom. For further details about this addon, take a look at its GitHub repo.",
16 |         data: data,
17 |         top: 70,
18 |         width: 600,
19 |         height: 240,
20 |         right: 40,
21 |         missing_is_hidden: true,
22 |         target: '#brushing'
23 |     });
24 | });
25 | 26 |
27 |
28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/make_fake_data.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from datetime import datetime, date, timedelta 3 | import json 4 | from random import random 5 | import argparse 6 | 7 | parser = argparse.ArgumentParser(description="Fake data maker.") 8 | parser.add_argument('-s', '--start', help="start date", nargs=1) 9 | parser.add_argument('-d', '--small', help="allow decimal values", action="store_true") 10 | parser.add_argument('-r', '--range', help="how many days from start date", nargs=1) 11 | parser.add_argument('-m', '--magnitude', help="size of change", nargs=1) 12 | parser.add_argument('-p', '--percentage', help="whether or not this is a percentage", action="store_true") 13 | parser.add_argument('-n', '--let_negative', help="let the data values go negative", action="store_true") 14 | parser.add_argument('-v', '--start_value', help='start value', nargs=1) 15 | args = parser.parse_args() 16 | 17 | doy = { 18 | 0: 1, 19 | 1:.9, 20 | 2:1, 21 | 3:1.1, 22 | 4:1.05, 23 | 5:.7, 24 | 6:.75 25 | } 26 | if args.percentage: convert = lambda x: float(x) 27 | elif args.small: convert = lambda x: float(x) 28 | else: convert = lambda x: int(x) 29 | 30 | current_date = datetime.strptime(args.start[0], '%Y-%m-%d').date() 31 | length = int(args.range[0]) 32 | 33 | baseline = convert(args.start_value[0]) 34 | 35 | if args.magnitude: magnitude = convert(args.magnitude[0]) 36 | elif args.percentage: magnitude = baseline/50. 37 | elif args.small: magnitude = baseline/20. 38 | else: magnitude = baseline/5 39 | out = [] 40 | 41 | # Needed to automatically convert dates to strings in json. 42 | dthandler = lambda obj: obj.isoformat() if isinstance(obj, date) else None 43 | 44 | for i in xrange(length): 45 | out.append({'date': current_date, 'value': baseline}) 46 | nb = convert(magnitude * (random()-.5)) 47 | if args.percentage: 48 | if (baseline+nb < 0 or baseline+nb > 1) and (not args.let_negative): pass 49 | else: baseline += nb 50 | else: 51 | if baseline+nb < 0 and not args.let_negative: pass 52 | else: baseline += nb 53 | 54 | current_date += timedelta(days=1) 55 | 56 | sys.stdout.write(json.dumps(out,default=dthandler, indent=4)) -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/charts/histogram_test.js: -------------------------------------------------------------------------------- 1 | module('histogram'); 2 | 3 | 4 | // THIS TEST NEEDS TO BE REWRITTEN AS A RESULT OF #614 5 | // test('A solitary active datapoint exists', function() { 6 | // var params = { 7 | // target: '#qunit-fixture', 8 | // data: d3.range(10000).map(d3.random.bates(10)), 9 | // chart_type: 'histogram', 10 | // linked: true 11 | // }; 12 | 13 | // MG.data_graphic(params); 14 | // equal(document.querySelectorAll('.mg-active-datapoint').length, 1, 'One active datapoint exists'); 15 | // }); 16 | 17 | test('Rollovers exist', function() { 18 | var params = { 19 | target: '#qunit-fixture', 20 | data: d3.range(10000).map(d3.randomBates(10)), 21 | chart_type: 'histogram', 22 | linked: true 23 | }; 24 | 25 | MG.data_graphic(params); 26 | ok(document.querySelector('.mg-rollover-rect'), 'Rollovers exist'); 27 | }); 28 | 29 | test('We have only one set of rollovers', function() { 30 | var params = { 31 | target: '#qunit-fixture', 32 | data: d3.range(10000).map(d3.randomBates(10)), 33 | chart_type: 'histogram', 34 | linked: true 35 | }; 36 | 37 | MG.data_graphic(params); 38 | equal(document.querySelectorAll('.mg-rollover-rect').length, 1, 'One set of rollovers exists'); 39 | }); 40 | 41 | test('Linked chart has the required class set', function() { 42 | var params = { 43 | target: '#qunit-fixture', 44 | data: d3.range(10000).map(d3.randomBates(10)), 45 | chart_type: 'histogram', 46 | linked: true 47 | }; 48 | 49 | MG.data_graphic(params); 50 | var matches = document.querySelector(params.target + ' svg').getAttribute('class').match(/linked/); 51 | ok(matches, 'Linked chart has class `linked` set'); 52 | }); 53 | 54 | test('Histogram exists', function() { 55 | var params = { 56 | target: '#qunit-fixture', 57 | data: d3.range(10000).map(d3.randomBates(10)), 58 | chart_type: 'histogram', 59 | linked: true 60 | }; 61 | 62 | MG.data_graphic(params); 63 | ok(document.querySelector('.mg-histogram'), 'Histogram exists'); 64 | }); 65 | -------------------------------------------------------------------------------- /quantum/modevlib/gui/RadioFilter.js: -------------------------------------------------------------------------------- 1 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | */ 6 | 7 | 8 | importScript("../debug/aLog.js"); 9 | importScript("../util/aTemplate.js"); 10 | importScript("../util/convert.js"); 11 | 12 | 13 | RadioFilter = function(){}; 14 | 15 | RadioFilter.newInstance=function(param){ 16 | var self = new RadioFilter(); 17 | Map.expecting(param, ["id", "name", "options", "default"]); 18 | Map.copy(param, self); 19 | self.description = coalesce(self.description, self.message); 20 | self.selected=self["default"]; 21 | self.isFilter=true; 22 | self.doneSetup=false; 23 | return self; 24 | }; 25 | 26 | 27 | RadioFilter.prototype.getSummary=function(){ 28 | var html = this.name+": "+this.selected; 29 | return html; 30 | };//method 31 | 32 | 33 | //RETURN SOMETHING SIMPLE ENOUGH TO BE USED IN A URL 34 | RadioFilter.prototype.getSimpleState=function(){ 35 | return this.selected; 36 | }; 37 | 38 | RadioFilter.prototype.setSimpleState=function(value){ 39 | if (this.options.contains(value)){ 40 | this.selected=value; 41 | }//endif 42 | var radios=$("input:radio[name='"+this.id+"']"); 43 | radios.val([self.selected]); 44 | this.refresh(); 45 | }; 46 | 47 | RadioFilter.prototype.makeHTML=function(){ 48 | var html = new Template([ 49 | '
', 50 | this.description===undefined ? "" : "
{{description}}
", 51 | { 52 | "from": "options", 53 | "template": '{{.}}
' 54 | }, 55 | '
' 56 | ]); 57 | 58 | return html.expand(this); 59 | };//method 60 | 61 | 62 | RadioFilter.prototype.setup=function(){ 63 | if (this.doneSetup) return; 64 | 65 | var self=this; 66 | var radios=$("input:radio[name='"+this.id+"']"); 67 | if (radios.length==0) return; //NOT BEEN CREATED YET 68 | radios.val([self.selected]); 69 | radios.change(function(){ 70 | self.selected=$(this).val(); 71 | if (self.refreshCallback){ 72 | self.refreshCallback(); 73 | GUI.refresh(false); 74 | }else{ 75 | GUI.refresh(); 76 | }//endif 77 | }); 78 | this.doneSetup=true; 79 | };//method 80 | 81 | 82 | RadioFilter.prototype.refresh = function(){ 83 | this.setup(); 84 | }; 85 | 86 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/SizeAxis.js: -------------------------------------------------------------------------------- 1 | var sizeAxis_optionsDef; 2 | 3 | def.scope(function(){ 4 | /** 5 | * Initializes a size axis. 6 | * 7 | * @name pvc.visual.SizeAxis 8 | * 9 | * @class Represents an axis that maps sizes to the values of a role. 10 | * 11 | * @extends pvc.visual.Axis 12 | */ 13 | def 14 | .type('pvc.visual.SizeAxis', pvc.visual.Axis) 15 | .init(function(chart, type, index, keyArgs){ 16 | 17 | // prevent naked resolution of size axis 18 | keyArgs = def.set(keyArgs, 'byNaked', false); 19 | 20 | this.base(chart, type, index, keyArgs); 21 | }) 22 | .add(/** @lends pvc.visual.SizeAxis# */{ 23 | 24 | scaleTreatsNullAs: function(){ 25 | return 'min'; 26 | }, 27 | 28 | scaleUsesAbs: function(){ 29 | return this.option('UseAbs'); 30 | }, 31 | 32 | setScaleRange: function(range){ 33 | var scale = this.scale; 34 | scale.min = range.min; 35 | scale.max = range.max; 36 | scale.size = range.max - range.min; 37 | 38 | scale.range(scale.min, scale.max); 39 | 40 | if(pvc.debug >= 4){ 41 | pvc.log("Scale: " + pvc.stringify(def.copyOwn(scale))); 42 | } 43 | 44 | return this; 45 | }, 46 | 47 | _getOptionsDefinition: function(){ 48 | return sizeAxis_optionsDef; 49 | } 50 | }); 51 | 52 | /*global axis_optionsDef:true */ 53 | sizeAxis_optionsDef = def.create(axis_optionsDef, { 54 | /* sizeAxisOriginIsZero 55 | * Force zero to be part of the domain of the scale to make 56 | * the scale "proportionally" comparable. 57 | */ 58 | OriginIsZero: { 59 | resolve: '_resolveFull', 60 | cast: Boolean, 61 | value: false 62 | }, 63 | 64 | FixedMin: { 65 | resolve: '_resolveFull', 66 | cast: pvc.castNumber 67 | }, 68 | 69 | FixedMax: { 70 | resolve: '_resolveFull', 71 | cast: pvc.castNumber 72 | }, 73 | 74 | UseAbs: { 75 | resolve: '_resolveFull', 76 | cast: Boolean, 77 | value: false 78 | } 79 | }); 80 | 81 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/BoxPlot.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes a box plot. 5 | * 6 | * @name pvc.visual.BoxPlot 7 | * @class Represents a box plot. 8 | * @extends pvc.visual.CategoricalPlot 9 | */ 10 | def 11 | .type('pvc.visual.BoxPlot', pvc.visual.CategoricalPlot) 12 | .add({ 13 | type: 'box', 14 | 15 | _getOptionsDefinition: function(){ 16 | return pvc.visual.BoxPlot.optionsDef; 17 | } 18 | }); 19 | 20 | pvc.visual.BoxPlot.optionsDef = def.create( 21 | pvc.visual.CategoricalPlot.optionsDef, 22 | { 23 | // NO Values Label! 24 | 25 | Stacked: { 26 | resolve: null, 27 | value: false 28 | }, 29 | 30 | OrthoRole: { 31 | value: ['median', 'lowerQuartil', 'upperQuartil', 'minimum', 'maximum'] // content of pvc.BoxplotChart.measureRolesNames 32 | }, 33 | 34 | BoxSizeRatio: { 35 | resolve: '_resolveFull', 36 | cast: function(value){ 37 | value = pvc.castNumber(value); 38 | if(value == null){ 39 | value = 1; 40 | } else if(value < 0.05){ 41 | value = 0.05; 42 | } else if(value > 1){ 43 | value = 1; 44 | } 45 | 46 | return value; 47 | }, 48 | value: 1/3 49 | }, 50 | 51 | BoxSizeMax: { 52 | resolve: '_resolveFull', 53 | data: { 54 | resolveV1: function(optionInfo){ 55 | // default to v1 option 56 | this._specifyChartOption(optionInfo, 'maxBoxSize'); 57 | return true; 58 | } 59 | }, 60 | cast: function(value){ 61 | value = pvc.castNumber(value); 62 | if(value == null){ 63 | value = Infinity; 64 | } else if(value < 1){ 65 | value = 1; 66 | } 67 | 68 | return value; 69 | }, 70 | value: Infinity 71 | } 72 | }); 73 | }); -------------------------------------------------------------------------------- /quantum/js/hierarchy.js: -------------------------------------------------------------------------------- 1 | //EXPECTING 2 | // esfilter - TO GENERATE THE TOP-LEVEL BUG IDS 3 | // allOpen - true IF WE COUNT OPEN DEPENDENCIES OF CLOSED BUGS 4 | //RETURNS CUBE OF bug X date, WITH OBJECT ELEMENTS HAVING "counted" PROPERTY INDICATING DEPENDENCY STATUS 5 | function* allOpenDependencies(esfilter, selects) { 6 | 7 | var a = Log.action("Get dependencies", true); 8 | var topBugs; 9 | if (esfilter.term && esfilter.term.bug_id){ 10 | topBugs=[esfilter.term.bug_id]; 11 | }else{ 12 | topBugs = (yield(ESQuery.run({ 13 | "from": "bugs", 14 | "select": "bug_id", 15 | "esfilter": {"and": [ 16 | esfilter, 17 | Mozilla.CurrentRecords.esfilter 18 | ]} 19 | }))).list; 20 | topBugs = [].union(topBugs); 21 | }//endif 22 | 23 | if (topBugs.length==0){ 24 | return []; 25 | }//endif 26 | 27 | var possibleTree = (yield(ESQuery.run({ 28 | "from": "bug_hierarchy", 29 | "select": [ 30 | "bug_id", 31 | "descendants" 32 | ], 33 | "esfilter": {"terms": {"bug_id": topBugs}} 34 | }))).list; 35 | possibleTree = possibleTree.select("descendants"); 36 | possibleTree.append(topBugs); 37 | possibleTree = Array.union(possibleTree); 38 | Log.actionDone(a); 39 | 40 | var allSelects= Array.union([["bug_id","dependson","bug_status"], selects]); 41 | 42 | var a = Log.action("Pull dependencies"); 43 | var raw_data = yield (ESQuery.run({ 44 | "name": "Open Bug Count", 45 | "from": "bugs", 46 | "select": allSelects.copy(), 47 | "esfilter": {"and": [ 48 | Mozilla.CurrentRecords.esfilter, 49 | Mozilla.BugStatus.Open.esfilter, 50 | {"terms": {"bug_id": possibleTree}} 51 | ]} 52 | })); 53 | Log.actionDone(a); 54 | 55 | //ENSURE RE HAVE ONE RECORD PER BUG 56 | var data = yield (Q({ 57 | "from": raw_data, 58 | "select": allSelects.map(function(v){ 59 | return {"value": v, "aggregate": "one"} 60 | }), 61 | "edges": [ 62 | {"name":"unique", "value":"bug_id"} 63 | ] 64 | })); 65 | 66 | var openBugs = data.cube; 67 | var openTopBugs = openBugs.filter({"and":[ 68 | esfilter, 69 | 70 | ]}); 71 | 72 | Hierarchy.addDescendants({ 73 | "from": openBugs, 74 | "id_field": "bug_id", 75 | "fk_field": "dependson", 76 | "descendants_field": "dependencies" 77 | }); yield (Thread.YIELD); 78 | 79 | 80 | var openDescendantsForToday = Array.union(openTopBugs.select("dependencies")).map(function(v){return v-0;}); 81 | var shortList = openBugs.filter({"terms":{"bug_id":openDescendantsForToday}}); 82 | 83 | yield (shortList); 84 | }//function 85 | 86 | 87 | -------------------------------------------------------------------------------- /quantum/modevlib/qb/ActiveDataQuery.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | importScript("../Settings.js"); 7 | importScript("../util/convert.js"); 8 | importScript("../charts/aColor.js"); 9 | importScript("../collections/aArray.js"); 10 | importScript("../util/aDate.js"); 11 | importScript("../util/aUtil.js"); 12 | importScript("../util/aParse.js"); 13 | importScript("../debug/aLog.js"); 14 | importScript("MVEL.js"); 15 | importScript("qb.js"); 16 | 17 | importScript("../rest/ElasticSearch.js"); 18 | importScript("../rest/Rest.js"); 19 | 20 | 21 | const ActiveDataQuery = {}; 22 | 23 | ActiveDataQuery.TrueFilter = {"match_all": {}}; 24 | ActiveDataQuery.DEBUG = false; 25 | ActiveDataQuery.INDEXES = window.Settings.indexes; 26 | 27 | 28 | (function () { 29 | ActiveDataQuery.run = function* (query) { 30 | let path = splitField(query.from); 31 | let index = ESQuery.INDEXES[path[0]]; 32 | if (index === undefined) Log.error("{{index}} must be defined in Setting.js", {"index": path[0]}); 33 | if (index.index) path[0] = index.index; 34 | query.from = joinField(path); 35 | 36 | let url = index.host + index.path; 37 | if (!url.endsWith("/query")) url += "/query"; 38 | if (ActiveDataQuery.DEBUG) Log.note(convert.value2json(query)); 39 | 40 | try { 41 | try { 42 | let output = yield (Rest.post({ 43 | url: url, 44 | data: convert.value2json(query), 45 | dataType: "json", 46 | timeout: query.timeout, 47 | })); 48 | output.index = index; 49 | yield (output); 50 | } catch (e) { 51 | if (!e.contains(Exception.TIMEOUT)) { 52 | throw e; 53 | } else if (e.contains.indexOf("dynamic scripting disabled")) { 54 | Log.error("Public cluster can not be used", e) 55 | } else { 56 | Log.action("Query timeout"); 57 | this.nextDelay = coalesce(this.nextDelay, 500) * 2; 58 | yield (Thread.sleep(this.nextDelay)); 59 | Log.action("Retrying Query..."); 60 | //TODO: TRY TO DO TAIL-RECURSION 61 | let output = yield (this.run()); 62 | yield output; 63 | }//endif 64 | }//try 65 | } catch (e) { 66 | Log.error("Error with ActiveDataQuery", e); 67 | }//try 68 | 69 | };//method 70 | 71 | Settings.host_types["undefined"]=ActiveDataQuery.run; 72 | Settings.host_types["null"]=ActiveDataQuery.run; 73 | Settings.host_types["ActiveData"]=ActiveDataQuery.run; 74 | 75 | return 0; 76 | })(); 77 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/src/js/common/chart_title.js: -------------------------------------------------------------------------------- 1 | function chart_title(args) { 2 | 'use strict'; 3 | 4 | var svg = mg_get_svg_child_of(args.target); 5 | 6 | //remove the current title if it exists 7 | svg.select('.mg-header').remove(); 8 | 9 | if (args.target && args.title) { 10 | var chartTitle = svg.insert('text') 11 | .attr('class', 'mg-header') 12 | .attr('x', args.center_title_full_width ? args.width /2 : (args.width + args.left - args.right) / 2) 13 | .attr('y', args.title_y_position) 14 | .attr('text-anchor', 'middle') 15 | .attr('dy', '0.55em'); 16 | 17 | //show the title 18 | chartTitle.append('tspan') 19 | .attr('class', 'mg-chart-title') 20 | .text(args.title); 21 | 22 | //show and activate the description icon if we have a description 23 | if (args.show_tooltips && args.description && mg_jquery_exists()) { 24 | chartTitle.append('tspan') 25 | .attr('class', 'mg-chart-description') 26 | .attr('dx', '0.3em') 27 | .text('\uf059'); 28 | 29 | //now that the title is an svg text element, we'll have to trigger 30 | //mouseenter, mouseleave events manually for the popover to work properly 31 | var $chartTitle = $(chartTitle.node()); 32 | $chartTitle.popover({ 33 | html: true, 34 | animation: false, 35 | placement: 'top', 36 | content: args.description, 37 | container: args.target, 38 | trigger: 'manual', 39 | template: '

' 40 | }).on('mouseenter', function() { 41 | d3.selectAll(args.target) 42 | .selectAll('.mg-popover') 43 | .remove(); 44 | 45 | $(this).popover('show'); 46 | $(d3.select(args.target).select('.popover').node()) 47 | .on('mouseleave', function () { 48 | $chartTitle.popover('hide'); 49 | }); 50 | }).on('mouseleave', function () { 51 | setTimeout(function () { 52 | if (!$('.popover:hover').length) { 53 | $chartTitle.popover('hide'); 54 | } 55 | }, 120); 56 | }); 57 | } else if (args.show_tooltips && args.description && typeof $ === 'undefined') { 58 | args.error = 'In order to enable tooltips, please make sure you include jQuery.'; 59 | } 60 | } 61 | 62 | if (args.error) { 63 | error(args); 64 | } 65 | } 66 | 67 | MG.chart_title = chart_title; 68 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/sign/Area.js: -------------------------------------------------------------------------------- 1 | 2 | def.type('pvc.visual.Area', pvc.visual.Sign) 3 | .init(function(panel, protoMark, keyArgs){ 4 | 5 | var pvMark = protoMark.add(pv.Area); 6 | 7 | if(!keyArgs) { keyArgs = {}; } 8 | 9 | keyArgs.freeColor = true; 10 | 11 | this.base(panel, pvMark, keyArgs); 12 | 13 | var antialias = def.get(keyArgs, 'antialias', true); 14 | 15 | this 16 | .lock('segmented', 'smart') // fixed, not inherited 17 | .lock('antialias', antialias) 18 | ; 19 | 20 | if(!def.get(keyArgs, 'freePosition', false)){ 21 | var basePosProp = panel.isOrientationVertical() ? "left" : "bottom", 22 | orthoPosProp = panel.anchorOrtho(basePosProp), 23 | orthoLenProp = panel.anchorOrthoLength(orthoPosProp); 24 | 25 | /* Positions */ 26 | this 27 | ._lockDynamic(basePosProp, 'x') // ex: left 28 | ._lockDynamic(orthoPosProp, 'y') // ex: bottom 29 | ._lockDynamic(orthoLenProp, 'dy') // ex: height 30 | ; 31 | } 32 | 33 | /* Colors */ 34 | this._bindProperty('fillStyle', 'fillColor', 'color'); 35 | 36 | // These really have no real meaning in the area and should not be used. 37 | // If lines are desired, they should be created with linesVisible of LineChart 38 | this.lock('strokeStyle', null) 39 | .lock('lineWidth', 0) 40 | ; 41 | }) 42 | .add({ 43 | _addInteractive: function(keyArgs){ 44 | keyArgs = def.setDefaults(keyArgs, 45 | 'noTooltip', true); 46 | 47 | this.base(keyArgs); 48 | }, 49 | 50 | /* Sign Spatial Coordinate System 51 | * -> Cartesian coordinates 52 | * -> Grows Up, vertically, and Right, horizontally 53 | * -> Independent of the chart's orientation 54 | * -> X - horizontal axis 55 | * -> Y - vertical axis 56 | * 57 | * y ^ 58 | * ^ dY | 59 | * | - y 60 | * | 61 | * o-----> x 62 | */ 63 | x: function(){ return 0; }, 64 | y: function(){ return 0; }, 65 | dy: function(){ return 0; }, 66 | 67 | /* COLOR */ 68 | /** 69 | * @override 70 | */ 71 | interactiveColor: function(color, type){ 72 | if(type === 'fill' && 73 | this.showsSelection() && 74 | this.scene.anySelected() && 75 | !this.scene.isSelected()) { 76 | return this.dimColor(color, type); 77 | } 78 | 79 | return this.base(color, type); 80 | } 81 | }); 82 | -------------------------------------------------------------------------------- /quantum/modevlib/Bugzilla.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | importScript("util/aHTML.js"); 6 | importScript("aLibrary.js"); 7 | importScript("rest/BugzillaClient.js"); 8 | 9 | 10 | Bugzilla={}; 11 | Bugzilla.URL="https://bugzilla.mozilla.org/buglist.cgi"; 12 | 13 | Bugzilla.showBugs=function(bugList, columnList){ 14 | var url=Bugzilla.searchBugsURL(bugList, columnList); 15 | window.open(url); 16 | };//method 17 | 18 | 19 | Bugzilla.searchBugsURL=function(bugList, columnList){ 20 | var url = ""; 21 | if (bugList instanceof Array){ 22 | url += Bugzilla.URL+"?quicksearch="+bugList.join('%2C'); 23 | }else if (isString(bugList)){ 24 | url += Bugzilla.URL+"?quicksearch="+bugList.replaceAll(", ", "%2C"); 25 | }else{ 26 | url += Bugzilla.URL+"?quicksearch="+bugList; 27 | }//endif 28 | 29 | if (columnList){ 30 | url += "&columnlist=" + Array.newInstance(columnList).join('%2C') 31 | }//endif 32 | 33 | return url; 34 | };//method 35 | 36 | 37 | Bugzilla.linkToBug=function(bugList){ 38 | return new HTML(""+bugList+""); 39 | };//method 40 | 41 | 42 | Bugzilla.search=function*(bugList, fields){ 43 | var BLOCK_SIZE=100; 44 | 45 | var resume=yield (Thread.Resume); 46 | var result=[]; 47 | var numCalls=aMath.floor((bugList.length+BLOCK_SIZE-1)/BLOCK_SIZE); 48 | if (!fields.contains("id")) fields.prepend("id"); 49 | 50 | for(i=0;i 0 || svg.node().parentNode.offsetHeight > 0)) { 17 | var aspect = svg.attr('width') !== 0 ? (svg.attr('height') / svg.attr('width')) : 0; 18 | 19 | var newWidth = get_width(target); 20 | 21 | svg.attr('width', newWidth); 22 | svg.attr('height', aspect * newWidth); 23 | } 24 | }); 25 | } 26 | 27 | function remove_target(target) { 28 | var index = targets.indexOf(target); 29 | if (index !== -1) { 30 | targets.splice(index, 1); 31 | } 32 | 33 | if (targets.length === 0) { 34 | window.removeEventListener('resize', window_listener, true); 35 | } 36 | } 37 | 38 | return { 39 | add_target: function(target) { 40 | if (targets.length === 0) { 41 | window.addEventListener('resize', window_listener, true); 42 | } 43 | 44 | if (targets.indexOf(target) === -1) { 45 | targets.push(target); 46 | 47 | if (Observer) { 48 | var observer = new Observer(function(mutations) { 49 | var targetNode = d3.select(target).node(); 50 | 51 | if (!targetNode || mutations.some( 52 | function(mutation) { 53 | for (var i = 0; i < mutation.removedNodes.length; i++) { 54 | if (mutation.removedNodes[i] === targetNode) { 55 | return true; 56 | } 57 | } 58 | })) { 59 | observer.disconnect(); 60 | remove_target(target); 61 | } 62 | }); 63 | 64 | observer.observe(d3.select(target).node().parentNode, { childList: true }); 65 | } 66 | } 67 | } 68 | }; 69 | } 70 | 71 | var mg_window_resize_tracker = new MG_WindowResizeTracker(); 72 | 73 | function mg_window_listeners(args) { 74 | mg_if_aspect_ratio_resize_svg(args); 75 | } 76 | 77 | function mg_if_aspect_ratio_resize_svg(args) { 78 | // have we asked the svg to fill a div, if so resize with div 79 | if (args.full_width || args.full_height) { 80 | mg_window_resize_tracker.add_target(args.target); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /quantum/modevlib/Dimension-Partners.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | importScript("Dimension.js"); 6 | 7 | if (!Mozilla) var Mozilla = {"name": "Mozilla", "edges": []}; 8 | 9 | Dimension.addEdges(false, Mozilla, [ 10 | {"name": "QA", "edges": [ 11 | { 12 | "name": "Partners", 13 | "esfilter": {"and": [ 14 | {"term": {"component": "preinstalled b2g apps"}}, 15 | {"terms": {"blocked": [868100,1009908,922475,889951,871656,871661,916312,976821,869192,871238,837298,904129,951752,869212,1009918,871236,869205,977321,869240,1009904,871910]}}, 16 | // {"not": {"regexp": {"short_desc": ".*\\[tracking\\].*"}}} 17 | ]}, 18 | "partitions": [ 19 | {"name": "Accuweather", "index": "bugs", "esfilter": {"term": {"blocked": 868100}}}, 20 | {"name": "Aviary", "index": "bugs", "esfilter": {"term": {"blocked": 1009908}}}, 21 | {"name": "Captain Rogers", "index": "bugs", "esfilter": {"term": {"blocked": 922475}}}, 22 | {"name": "Cut the Rope", "index": "bugs", "esfilter": {"term": {"blocked": 889951}}}, 23 | {"name": "Desert Rescue", "index": "bugs", "esfilter": {"term": {"blocked": 871656}}}, 24 | {"name": "Distant Orbit", "index": "bugs", "esfilter": {"term": {"blocked": 871661}}}, 25 | {"name": "Entanglement", "index": "bugs", "esfilter": {"term": {"blocked": 916312}}}, 26 | {"name": "Evernav", "index": "bugs", "esfilter": {"term": {"blocked": 976821}}}, 27 | {"name": "Facebook", "index": "bugs", "esfilter": {"term": {"blocked": 869192}}}, 28 | {"name": "Gamepack", "index": "bugs", "esfilter": {"term": {"blocked": 871238}}}, 29 | {"name": "HERE Maps", "index": "bugs", "esfilter": {"term": {"blocked": 837298}}}, 30 | {"name": "Napster", "index": "bugs", "esfilter": {"term": {"blocked": 904129}}}, 31 | {"name": "NILE", "index": "bugs", "esfilter": {"term": {"blocked": 951752}}}, 32 | {"name": "Notes", "index": "bugs", "esfilter": {"term": {"blocked": 869212}}}, 33 | {"name": "Pinterest", "index": "bugs", "esfilter": {"term": {"blocked": 1009918}}}, 34 | {"name": "Poppit", "index": "bugs", "esfilter": {"term": {"blocked": 871236}}}, 35 | {"name": "Twitter", "index": "bugs", "esfilter": {"term": {"blocked": 869205}}}, 36 | {"name": "Weather Channel", "index": "bugs", "esfilter": {"term": {"blocked": 977321}}}, 37 | {"name": "Wikipedia", "index": "bugs", "esfilter": {"term": {"blocked": 869240}}}, 38 | {"name": "Yelp", "index": "bugs", "esfilter": {"term": {"blocked": 1009904}}}, 39 | {"name": "YouTube", "index": "bugs", "esfilter": {"term": {"blocked": 871910}}} 40 | ]} 41 | ]} 42 | ]) 43 | ; 44 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/sign/Bar.js: -------------------------------------------------------------------------------- 1 | 2 | def.type('pvc.visual.Bar', pvc.visual.Sign) 3 | .init(function(panel, protoMark, keyArgs){ 4 | 5 | var pvMark = protoMark.add(pv.Bar); 6 | 7 | keyArgs = def.setDefaults(keyArgs, 'freeColor', false); 8 | 9 | this.base(panel, pvMark, keyArgs); 10 | 11 | this.normalStroke = def.get(keyArgs, 'normalStroke', false); 12 | 13 | this._bindProperty('lineWidth', 'strokeWidth'); 14 | }) 15 | .prototype 16 | .property('strokeWidth') 17 | .constructor 18 | .add({ 19 | /* COLOR */ 20 | /** 21 | * @override 22 | */ 23 | normalColor: function(color, type){ 24 | if(type === 'stroke' && !this.normalStroke){ 25 | return null; 26 | } 27 | 28 | return color; 29 | }, 30 | 31 | /** 32 | * @override 33 | */ 34 | interactiveColor: function(color, type){ 35 | var scene = this.scene; 36 | 37 | if(type === 'stroke'){ 38 | if(scene.isActive){ 39 | return color.brighter(1.3).alpha(0.7); 40 | } 41 | 42 | if(!this.normalStroke){ 43 | return null; 44 | } 45 | 46 | if(this.showsSelection() && scene.anySelected() && !scene.isSelected()) { 47 | if(this.isActiveSeriesAware && scene.isActiveSeries()) { 48 | return pv.Color.names.darkgray.darker().darker(); 49 | } 50 | 51 | return this.dimColor(color, type); 52 | 53 | } 54 | 55 | if(this.isActiveSeriesAware && scene.isActiveSeries()){ 56 | return color.brighter(1).alpha(0.7); 57 | } 58 | 59 | } else if(type === 'fill'){ 60 | if(scene.isActive) { 61 | return color.brighter(0.2).alpha(0.8); 62 | } 63 | 64 | if(this.showsSelection() && scene.anySelected() && !scene.isSelected()) { 65 | if(this.isActiveSeriesAware && scene.isActiveSeries()) { 66 | return pv.Color.names.darkgray.darker(2).alpha(0.8); 67 | } 68 | 69 | return this.dimColor(color, type); 70 | } 71 | 72 | if(this.isActiveSeriesAware && scene.isActiveSeries()){ 73 | return color.brighter(0.2).alpha(0.8); 74 | } 75 | } 76 | 77 | return this.base(color, type); 78 | }, 79 | 80 | /* STROKE WIDTH */ 81 | defaultStrokeWidth: function(){ 82 | return 0.5; 83 | }, 84 | 85 | interactiveStrokeWidth: function(strokeWidth){ 86 | if(this.scene.isActive){ 87 | return Math.max(1, strokeWidth) * 1.3; 88 | } 89 | 90 | return strokeWidth; 91 | } 92 | }); 93 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/plot/BarPlotAbstract.js: -------------------------------------------------------------------------------- 1 | def.scope(function(){ 2 | 3 | /** 4 | * Initializes an abstract bar plot. 5 | * 6 | * @name pvc.visual.BarPlotAbstract 7 | * @class Represents an abstract bar plot. 8 | * @extends pvc.visual.CategoricalPlot 9 | */ 10 | def 11 | .type('pvc.visual.BarPlotAbstract', pvc.visual.CategoricalPlot) 12 | .add({ 13 | _getOptionsDefinition: function(){ 14 | return pvc.visual.BarPlotAbstract.optionsDef; 15 | } 16 | }); 17 | 18 | pvc.visual.BarPlotAbstract.optionsDef = def.create( 19 | pvc.visual.CategoricalPlot.optionsDef, { 20 | 21 | BarSizeRatio: { // for grouped bars 22 | resolve: '_resolveFull', 23 | cast: function(value){ 24 | value = pvc.castNumber(value); 25 | if(value == null){ 26 | value = 1; 27 | } else if(value < 0.05){ 28 | value = 0.05; 29 | } else if(value > 1){ 30 | value = 1; 31 | } 32 | 33 | return value; 34 | }, 35 | value: 0.9 36 | }, 37 | 38 | BarSizeMax: { 39 | resolve: '_resolveFull', 40 | data: { 41 | resolveV1: function(optionInfo){ 42 | // default to v1 option 43 | this._specifyChartOption(optionInfo, 'maxBarSize'); 44 | return true; 45 | } 46 | }, 47 | cast: function(value){ 48 | value = pvc.castNumber(value); 49 | if(value == null){ 50 | value = Infinity; 51 | } else if(value < 1){ 52 | value = 1; 53 | } 54 | 55 | return value; 56 | }, 57 | value: 2000 58 | }, 59 | 60 | BarStackedMargin: { // for stacked bars 61 | resolve: '_resolveFull', 62 | cast: function(value){ 63 | value = pvc.castNumber(value); 64 | if(value != null && value < 0){ 65 | value = 0; 66 | } 67 | 68 | return value; 69 | }, 70 | value: 0 71 | }, 72 | 73 | OverflowMarkersVisible: { 74 | resolve: '_resolveFull', 75 | cast: Boolean, 76 | value: true 77 | }, 78 | 79 | ValuesAnchor: { // override default value only 80 | value: 'center' 81 | } 82 | 83 | /* TODO valuesMask... showValuePercentage 84 | ValuePercentage: { 85 | value: false 86 | } 87 | */ 88 | }); 89 | }); -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/misc/utility_test.js: -------------------------------------------------------------------------------- 1 | module('utility'); 2 | 3 | test('MG.convert.date', function() { 4 | var data = [{'date': '2014-01-01', 'value': 12}, 5 | {'date': '2014-03-01', 'value': 18}]; 6 | 7 | MG.convert.date(data, 'date'); 8 | equal($.type(data[0].date), 'date', 'First date is of type date'); 9 | equal($.type(data[0].date), 'date', 'Second date is of type date'); 10 | }); 11 | 12 | test('MG.convert.date with an alternative timestamp style', function() { 13 | var data = [{'date': '2014-20-12', 'value': 12}, 14 | {'date': '2014-21-12', 'value': 18}]; 15 | 16 | MG.convert.date(data, 'date', '%Y-%d-%m'); 17 | equal($.type(data[0].date), 'date', 'First date is of type date'); 18 | equal($.type(data[0].date), 'date', 'Second date is of type date'); 19 | }); 20 | 21 | test('MG.convert.number', function() { 22 | var data = [{'date': '2014-20-12', 'value': '12'}, 23 | {'date': '2014-21-12', 'value': '18'}]; 24 | 25 | MG.convert.number(data, 'value'); 26 | equal($.type(data[0].value), 'number', 'First value is a number'); 27 | equal($.type(data[0].value), 'number', 'Second value is a number'); 28 | }); 29 | 30 | test('mg_get_svg_child_of', function(){ 31 | d3.select('#qunit-fixture').append('svg'); 32 | 33 | var svg_element_with_node = mg_get_svg_child_of(document.querySelector('#qunit-fixture')); 34 | var svg_element_with_text = mg_get_svg_child_of('#qunit-fixture'); 35 | 36 | equal(svg_element_with_node.nodes().length, 1, 'Node-based argument should return a d3 selection with svg.'); 37 | equal(svg_element_with_node.nodes().length, 1, 'Selector-based argument should return a d3 selection with svg.'); 38 | }); 39 | 40 | 41 | test('mg_target_ref', function() { 42 | var chart_area2 = document.createElement('div'); 43 | mg_target_ref(chart_area2); 44 | ok(chart_area2.getAttribute('data-mg-uid').match(/mg-[\d]/), 'applies generated ID to DOM element'); 45 | }); 46 | 47 | test('Overlapping markers are taken care of', function() { 48 | var params = { 49 | data: [{ 50 | "date": new Date('2016-01-01'), 51 | "value": 6 52 | }, 53 | { 54 | "date": new Date('2016-01-02'), 55 | "value": 8 56 | }, 57 | { 58 | "date": new Date('2016-01-03'), 59 | "value": 34 60 | }, 61 | { 62 | "date": new Date('2016-01-04'), 63 | "value": 38 64 | }], 65 | markers: [{'date': new Date('2016-01-02'), 'label': 'A happened'},{'date': new Date('2016-01-02'), 'label': 'B happened'}], 66 | target: "#qunit-fixture" 67 | }; 68 | 69 | MG.data_graphic(params); 70 | 71 | equal(mg_is_horizontally_overlapping(d3.selectAll('.mg-marker-text').node(), d3.selectAll('.mg-marker-text').nodes()), false, 'Markers aren\'t overlapping'); 72 | }); 73 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/sign/Line.js: -------------------------------------------------------------------------------- 1 | 2 | def.type('pvc.visual.Line', pvc.visual.Sign) 3 | .init(function(panel, protoMark, keyArgs){ 4 | 5 | var pvMark = protoMark.add(pv.Line); 6 | 7 | this.base(panel, pvMark, keyArgs); 8 | 9 | this.lock('segmented', 'smart') // fixed 10 | .lock('antialias', true) 11 | ; 12 | 13 | if(!def.get(keyArgs, 'freePosition', false)){ 14 | var basePosProp = panel.isOrientationVertical() ? "left" : "bottom", 15 | orthoPosProp = panel.anchorOrtho(basePosProp); 16 | 17 | this/* Positions */ 18 | ._lockDynamic(orthoPosProp, 'y') 19 | ._lockDynamic(basePosProp, 'x'); 20 | } 21 | 22 | this/* Colors & Line */ 23 | ._bindProperty('strokeStyle', 'strokeColor', 'color') 24 | ._bindProperty('lineWidth', 'strokeWidth') 25 | ; 26 | 27 | // Segmented lines use fill color instead of stroke...so this doesn't work. 28 | //this.pvMark.lineCap('square'); 29 | }) 30 | .prototype 31 | .property('strokeWidth') 32 | .constructor 33 | .add({ 34 | _addInteractive: function(keyArgs){ 35 | keyArgs = def.setDefaults(keyArgs, 36 | 'noTooltip', true); 37 | 38 | this.base(keyArgs); 39 | }, 40 | 41 | /* Sign Spatial Coordinate System 42 | * -> Cartesian coordinates 43 | * -> Grows Up, vertically, and Right, horizontally 44 | * -> Independent of the chart's orientation 45 | * -> X - horizontal axis 46 | * -> Y - vertical axis 47 | * 48 | * y 49 | * ^ 50 | * | 51 | * | 52 | * o-----> x 53 | */ 54 | y: function(){ return 0; }, 55 | x: function(){ return 0; }, 56 | 57 | /* STROKE WIDTH */ 58 | defaultStrokeWidth: function(){ 59 | return 1.5; 60 | }, 61 | 62 | interactiveStrokeWidth: function(strokeWidth){ 63 | if(this.isActiveSeriesAware && this.scene.isActiveSeries()){ 64 | /* - Ensure a normal width of at least 1, 65 | * - Double and a half that 66 | */ 67 | return Math.max(1, strokeWidth) * 2.5; 68 | } 69 | 70 | return strokeWidth; 71 | }, 72 | 73 | /* STROKE COLOR */ 74 | /** 75 | * @override 76 | */ 77 | interactiveColor: function(color, type){ 78 | var scene = this.scene; 79 | if(this.showsSelection() && scene.anySelected() && !scene.isSelected()) { 80 | 81 | if(this.isActiveSeriesAware && scene.isActiveSeries()) { 82 | //return color.darker(1.5); 83 | return pv.Color.names.darkgray.darker().darker(); 84 | } 85 | 86 | if(type === 'stroke'){ 87 | return this.dimColor(color, type); 88 | } 89 | } 90 | 91 | return this.base(color, type); 92 | } 93 | }); 94 | -------------------------------------------------------------------------------- /quantum/js/regressionCharts.js: -------------------------------------------------------------------------------- 1 | function showRegressionAge(args) { 2 | var timeDomain = Map.copy(args.timeDomain); 3 | timeDomain.max = timeDomain.max.add(timeDomain.interval); 4 | 5 | Thread.run(function*() { 6 | /////////////////////////////////////////////////////////////////////// 7 | // THREAD TO AGE OF REGRESSIONS 8 | /////////////////////////////////////////////////////////////////////// 9 | 10 | var allBlockers = null; 11 | var allBlockersThread = Thread.run(function*() { 12 | allBlockers = yield(ESQuery.run({ 13 | "from": "bugs", 14 | "select": [ 15 | "bug_id", 16 | "cf_blocking_b2g", 17 | "cf_blocking_loop", 18 | "target_milestone", 19 | "keywords" 20 | ], 21 | "esfilter": {"and": [ 22 | GUI.getFilters("bugs"), 23 | Mozilla.CurrentRecords.esfilter, 24 | Mozilla.Quantum.Regressions.esfilter, 25 | {"or": [ 26 | {"range": {"expires_on": {"gte": timeDomain.min.getMilli()}}}, 27 | Mozilla.BugStatus.Open.esfilter 28 | ]} 29 | ]} 30 | })); 31 | }); 32 | 33 | var blockers = yield (ElasticSearch.getMinMax({"and": [ 34 | GUI.getFilters("bugs"), 35 | Mozilla.Quantum.Regressions.esfilter, 36 | Mozilla.BugStatus.Open.esfilter 37 | ]})); 38 | 39 | yield(Thread.join(allBlockersThread)); 40 | 41 | {//ADD THOSE max, min TO TO MAIN LIST OF BUGS (WE SHOULD BE MERGING IN SOME FORM) 42 | data = {}; 43 | var domain = blockers.edges[0].domain; 44 | var data = blockers.cube; 45 | allBlockers.list.forall(function (v) { 46 | Map.copy({"min": null, "max": null}, v); //DEFAULT VALUES 47 | Map.copy(nvl(data[domain.getPartByKey(v.bug_id).dataIndex], {}), v); 48 | }); 49 | } 50 | 51 | var projectDomain = Mozilla.Quantum.FinalState.getDomain(); 52 | projectDomain.partitions.pop(); //DO NOT SHOW THE Untargeted 53 | 54 | var a = Log.action("Request Bugs", true); 55 | var chart = yield(Q({ 56 | "name": "Average Age of Regressions (Days)", 57 | "from": allBlockers.list, 58 | "select": {"name": "Average", "value": "nvl(min, time.min)>time.min ? null : (time.min.getMilli() - nvl(min, time.min).getMilli())/Duration.DAY.milli", "aggregate": "average", "default": 0, "style": {"color": "#00d6ff", "visibility": "hidden"}}, 59 | "edges": [ 60 | {"name": "Project", "domain": projectDomain}, 61 | {"name": "date", 62 | "range": {"min": "min", "max": "max"}, 63 | "allowNulls": false, 64 | domain: timeDomain 65 | } 66 | ] 67 | })); 68 | Log.actionDone(a); 69 | 70 | //DIRTY REVERSE OF THE TYPES 71 | chart.edges[0].domain.partitions.reverse(); 72 | chart.cube.reverse(); 73 | chart.edges[0].domain.partitions[0].style.visibility = "visible"; 74 | 75 | aChart.show({ 76 | "id": args.chart.id, 77 | "name": args.chart.name, 78 | "type": "line", 79 | "stacked": false, 80 | "cube": chart 81 | }); 82 | 83 | 84 | }); 85 | 86 | 87 | } 88 | 89 | -------------------------------------------------------------------------------- /quantum/lib/jsonlint/jsl.format.js: -------------------------------------------------------------------------------- 1 | /*jslint white: true, devel: true, onevar: true, browser: true, undef: true, nomen: true, regexp: true, plusplus: false, bitwise: true, newcap: true, maxerr: 50, indent: 4 */ 2 | var jsl = typeof jsl === 'undefined' ? {} : jsl; 3 | 4 | /** 5 | * jsl.format - Provide json reformatting in a character-by-character approach, so that even invalid JSON may be reformatted (to the best of its ability). 6 | * 7 | **/ 8 | jsl.format = (function () { 9 | 10 | function repeat(s, count) { 11 | return new Array(count + 1).join(s); 12 | } 13 | 14 | function formatJson(json) { 15 | var i = 0, 16 | il = 0, 17 | tab = " ", 18 | newJson = "", 19 | indentLevel = 0, 20 | inString = false, 21 | currentChar = null; 22 | 23 | for (i = 0, il = json.length; i < il; i += 1) { 24 | currentChar = json.charAt(i); 25 | 26 | switch (currentChar) { 27 | case '{': 28 | case '[': 29 | if (!inString) { 30 | newJson += currentChar + "\n" + repeat(tab, indentLevel + 1); 31 | indentLevel += 1; 32 | } else { 33 | newJson += currentChar; 34 | } 35 | break; 36 | case '}': 37 | case ']': 38 | if (!inString) { 39 | indentLevel -= 1; 40 | newJson += "\n" + repeat(tab, indentLevel) + currentChar; 41 | } else { 42 | newJson += currentChar; 43 | } 44 | break; 45 | case ',': 46 | if (!inString) { 47 | newJson += ",\n" + repeat(tab, indentLevel); 48 | } else { 49 | newJson += currentChar; 50 | } 51 | break; 52 | case ':': 53 | if (!inString) { 54 | newJson += ": "; 55 | } else { 56 | newJson += currentChar; 57 | } 58 | break; 59 | case ' ': 60 | case "\n": 61 | case "\t": 62 | if (inString) { 63 | newJson += currentChar; 64 | } 65 | break; 66 | case '"': 67 | if (i > 0 && json.charAt(i - 1) !== '\\') { 68 | inString = !inString; 69 | } 70 | newJson += currentChar; 71 | break; 72 | default: 73 | newJson += currentChar; 74 | break; 75 | } 76 | } 77 | 78 | return newJson; 79 | } 80 | 81 | return { "formatJson": formatJson }; 82 | 83 | }()); -------------------------------------------------------------------------------- /quantum/lib/ccc/lib/tipsy.css: -------------------------------------------------------------------------------- 1 | .tipsy { pointer-events: none; padding: 5px; font-size: 10px; font-family: Arial,Helvetica,sans-serif; position: absolute; z-index: 100000; } 2 | .tipsy-inner { padding: 5px 8px 4px 8px; background-color: black; color: white; max-width: 200px; text-align: center; } 3 | .tipsy-inner { border-radius: 3px; -moz-border-radius:3px; -webkit-border-radius:3px; } 4 | 5 | /* Uncomment for shadow */ 6 | /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ 7 | 8 | .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } 9 | 10 | .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } 11 | .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 12 | .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} 13 | 14 | .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 15 | .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 16 | .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } 17 | 18 | .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } 19 | .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } 20 | 21 | /* 22 | Corner arrow styles. 23 | .tipsy-nww .tipsy-arrow { left: 0; top: 10px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } 24 | .tipsy-nee .tipsy-arrow { right: 0; top: 10px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } 25 | .tipsy-sww .tipsy-arrow { right: 0; top: 10px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } 26 | .tipsy-see .tipsy-arrow { right: 0; bottom: -10px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent;} 27 | */ 28 | 29 | /* 30 | .tipsy-arrow { border-color: green; } 31 | .tipsy { border-width: 1px; border-style:solid; border-color:red;} 32 | 33 | */ -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/_data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Namespace with data related classes. 3 | * @name pvc.data 4 | * @namespace 5 | */ 6 | 7 | /** 8 | * @name NoDataException 9 | * @class An error thrown when a chart has no data. 10 | */ 11 | def.global.NoDataException = function(){}; 12 | 13 | 14 | pvc.data = { 15 | visibleKeyArgs: {visible: true} 16 | }; 17 | 18 | /** 19 | * Disposes a list of child objects. 20 | * 21 | * @name pvc.data._disposeChildList 22 | * 23 | * @param {Array} list The list with children to dispose. 24 | * @param {string} [parentProp] The child's parent property to reset. 25 | * 26 | * @static 27 | * @private 28 | */ 29 | function data_disposeChildList(list, parentProp) { 30 | if(list){ 31 | list.forEach(function(child){ 32 | if(parentProp) { 33 | child[parentProp] = null; // HACK: to avoid child removing itself from its parent (this) 34 | } 35 | 36 | child.dispose(); 37 | }); 38 | 39 | list.length = 0; 40 | } 41 | } 42 | 43 | /** 44 | * Adds a child object. 45 | * 46 | * @name pvc.data._addColChild 47 | * 48 | * @param {object} parent The parent. 49 | * @param {string} childrenProp A parent's children array property. 50 | * @param {object} child The child to add. 51 | * @param {string} parentProp The child's parent property to set. 52 | * @param {number} [index=null] The index at which to insert the child. 53 | * 54 | * @static 55 | * @private 56 | */ 57 | function data_addColChild(parent, childrenProp, child, parentProp, index) { 58 | // 59 | /*jshint expr:true */ 60 | (child && !child[parentProp]) || def.assert("Must not have a '" + parentProp + "'."); 61 | // 62 | 63 | child[parentProp] = parent; 64 | 65 | var col = (parent[childrenProp] || (parent[childrenProp] = [])); 66 | if(index == null || index >= col.length){ 67 | col.push(child); 68 | } else { 69 | col.splice(index, 0, child); 70 | } 71 | } 72 | 73 | /** 74 | * Removes a child object. 75 | * 76 | * @name pvc.data._removeColChild 77 | * 78 | * @param {object} parent The parent. 79 | * @param {string} childrenProp A parent's children array property. 80 | * @param {object} child The child to remove. 81 | * @param {string} parentProp The child's parent property to reset. 82 | * 83 | * @static 84 | * @private 85 | */ 86 | function data_removeColChild(parent, childrenProp, child, parentProp) { 87 | // 88 | /*jshint expr:true */ 89 | (child && (!child[parentProp] || child[parentProp] === parent)) || def.assert("Not a child"); 90 | // 91 | 92 | var children = parent[childrenProp]; 93 | if(children) { 94 | var index = children.indexOf(child); 95 | if(index >= 0){ 96 | def.array.removeAt(children, index); 97 | } 98 | } 99 | 100 | child[parentProp] = null; 101 | } -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcBaseChart.plots.js: -------------------------------------------------------------------------------- 1 | pvc.BaseChart 2 | .add({ 3 | _initPlots: function(hasMultiRole){ 4 | 5 | this.plotPanelList = null; 6 | 7 | // reset plots 8 | if(!this.parent){ 9 | this.plots = {}; 10 | this.plotList = []; 11 | this.plotsByType = {}; 12 | 13 | this._initPlotsCore(hasMultiRole); 14 | } else { 15 | var root = this.root; 16 | 17 | this.plots = root.plots; 18 | this.plotList = root.plotList; 19 | this.plotsByType = root.plotsByType; 20 | } 21 | }, 22 | 23 | _initPlotsCore: function(/*hasMultiRole*/){ 24 | // NOOP 25 | }, 26 | 27 | _addPlot: function(plot){ 28 | var plotsByType = this.plotsByType; 29 | var plots = this.plots; 30 | 31 | var plotType = plot.type; 32 | var plotIndex = plot.index; 33 | var plotName = plot.name; 34 | var plotId = plot.id; 35 | 36 | if(plotName && def.hasOwn(plots, plotName)){ 37 | throw def.error.operationInvalid("Plot name '{0}' already taken.", [plotName]); 38 | } 39 | 40 | if(def.hasOwn(plots, plotId)){ 41 | throw def.error.operationInvalid("Plot id '{0}' already taken.", [plotId]); 42 | } 43 | 44 | var typePlots = def.array.lazy(plotsByType, plotType); 45 | if(def.hasOwn(typePlots, plotIndex)){ 46 | throw def.error.operationInvalid("Plot index '{0}' of type '{1}' already taken.", [plotIndex, plotType]); 47 | } 48 | 49 | plot.globalIndex = this.plotList.length; 50 | typePlots[plotIndex] = plot; 51 | this.plotList.push(plot); 52 | plots[plotId] = plot; 53 | if(plotName){ 54 | plots[plotName] = plot; 55 | } 56 | }, 57 | 58 | _collectPlotAxesDataCells: function(plot, dataCellsByAxisTypeThenIndex){ 59 | /* Configure Color Axis Data Cell */ 60 | var colorRoleName = plot.option('ColorRole'); 61 | if(colorRoleName){ 62 | var colorRole = this.visualRoles(colorRoleName); 63 | if(colorRole.isBound()){ 64 | var colorDataCellsByAxisIndex = 65 | def 66 | .array 67 | .lazy(dataCellsByAxisTypeThenIndex, 'color'); 68 | 69 | def 70 | .array 71 | .lazy(colorDataCellsByAxisIndex, plot.option('ColorAxis') - 1) 72 | .push({ 73 | plot: plot, 74 | role: colorRole, 75 | dataPartValue: plot.option('DataPart') 76 | }); 77 | } 78 | } 79 | }, 80 | 81 | // Called by the pvc.PlotPanel class 82 | _addPlotPanel: function(plotPanel){ 83 | def.lazy(this, 'plotPanels')[plotPanel.plot.id] = plotPanel; 84 | def.array.lazy(this, 'plotPanelList').push(plotPanel); 85 | }, 86 | 87 | /* @abstract */ 88 | _createPlotPanels: function(/*parentPanel, baseOptions*/){ 89 | throw def.error.notImplemented(); 90 | } 91 | }); 92 | 93 | -------------------------------------------------------------------------------- /quantum/modevlib/Settings.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | importScript("charts/aColor.js"); 6 | 7 | 8 | (function(){ 9 | var green = Color.GREEN.multiply(0.5).hue(10).toHTML(); 10 | var blue = Color.BLUE.multiply(0.5).hue(10).toHTML(); 11 | var yellow = Color.RED.multiply(0.7).hue(-60).toHTML(); 12 | var red = Color.RED.multiply(0.5).toHTML(); 13 | 14 | 15 | window.Settings = { 16 | "imagePath" : "images", 17 | 18 | // POINTERS TO THE MANY SYSTEMS 19 | "indexes" : { 20 | 21 | // BUGZILLA TABLES (ElasticSearch Indexes) 22 | "bugs" : {"name" : "public bugs cluster", "style" : {"color" : "black", "background-color" : green}, "host" : "https://activedata-public.devsvcprod.mozaws.net", "path":"/query", "index":"public_bugs", "host_type":"ActiveData"}, 23 | "public_bugs" : {"name" : "Mozilla public bugs cluster", "style" : {"color" : "white", "background-color" : green}, "host" : "https://activedata-public.devsvcprod.mozaws.net", "path":"/query", "host_type":"ActiveData"}, 24 | "public_comments" : {"style" : {"color" : "black", "background-color" : yellow}, "host" : "https://activedata-public.devsvcprod.mozaws.net", "path":"/query", "host_type":"ActiveData"}, 25 | "private_bugs" : {"style" : {"color" : "black", "background-color" : yellow}, "host" : "https://activedata-private.devsvcprod.mozaws.net", "path":"/query", "host_type":"ActiveData"}, 26 | "private_comments" : {"style" : {"color" : "black", "background-color" : yellow}, "host" : "https://activedata-private.devsvcprod.mozaws.net", "path":"/query", "host_type":"ActiveData"}, 27 | // ACTIVE DATA TABLES 28 | "branches": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"branches", "host_type":"ActiveData"}, 29 | "jobs": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"jobs", "host_type":"ActiveData"}, 30 | "jobs.action.timings": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"jobs.action.timings", "host_type":"ActiveData"}, 31 | "local_jobs.action.timings": {"style" : {"background-color" : blue}, "host" : "http://localhost:5000", "table":"jobs.action.timings", "host_type":"ActiveData"}, 32 | "timings": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"jobs.action.timings", "host_type":"ActiveData"}, 33 | "unittests": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"unittest", "host_type":"ActiveData"}, 34 | "perf": {"style" : {"background-color" : blue}, "host" : "https://activedata.allizom.org", "table":"perf", "host_type":"ActiveData"}, 35 | "failures": {"style" : {"background-color" : blue}, "host" : "https://localhost", "table":"failures", "host_type":"ActiveData"} 36 | 37 | }, 38 | 39 | //REGISTER GENERATORS THAT HANDLE qb QUERIES 40 | "host_types": { 41 | } 42 | }; 43 | 44 | 45 | //GIVE ALL CLUSTERS NAMES AND IDS 46 | Map.forall(Settings.indexes, function(k, v){ 47 | v._id=k; 48 | v.name=coalesce(v.name, k); 49 | }); 50 | })(); 51 | -------------------------------------------------------------------------------- /quantum/modevlib/qb/aCompiler.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | 6 | aCompile={}; 7 | 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // EXECUTE SIMPLE CODE IN THE CONTEXT OF AN OBJECT'S VARIABLES 10 | //////////////////////////////////////////////////////////////////////////////// 11 | aCompile.method_usingObjects=function(code, contextObjects){ 12 | if (!(contextObjects instanceof Array)) contextObjects=[contextObjects]; 13 | 14 | var contextTypes=[]; 15 | contextObjects.forall(function(v, i){ 16 | contextTypes[i]={"columns":qb.getColumnsFromList([v])}; 17 | }); 18 | 19 | return aCompile.method(code, contextTypes); 20 | 21 | }; 22 | 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // EXECUTE SIMPLE CODE IN THE CONTEXT OF AN OBJECT'S VARIABLES 25 | // contextTypes ARE TABLES 26 | //////////////////////////////////////////////////////////////////////////////// 27 | aCompile.method=function(code, contextTypes){ 28 | if (!(contextTypes instanceof Array)) contextTypes=[contextTypes]; 29 | var output; 30 | 31 | var contexTypeNames=[]; 32 | contextTypes.forall(function(c, i){ 33 | contexTypeNames.push("__source"+i); 34 | }); 35 | 36 | var f = 37 | "output=function("+contexTypeNames.join(",")+"){\n"; 38 | 39 | for(var s = contextTypes.length; s--;){ 40 | contextTypes[s].columns.forall(function(p){ 41 | //ONLY DEFINE VARS THAT ARE USED 42 | if (code.indexOf(p.name) != -1){ 43 | f += "var " + p.name + "="+contexTypeNames[s]+"." + p.name + ";\n"; 44 | }//endif 45 | }); 46 | }//for 47 | 48 | f+=code.trim().rtrim(";")+";\n"; 49 | 50 | //FIRST CONTEXT OBJECT IS SPECIAL, AND WILL HAVE IT'S VARS ASSIGNED BACK 51 | contextTypes[0].columns.forall(function(p){ 52 | if (code.indexOf(p.name) != -1){ 53 | f += contexTypeNames[0] + "." + p.name + "=" + p.name + "; \n"; 54 | }//endif 55 | }); 56 | 57 | f += "}"; 58 | try{ 59 | eval(f); 60 | }catch(e){ 61 | Log.error("Expression does not eval():\n\t"+f, e) 62 | }//try 63 | 64 | return output; 65 | 66 | }; 67 | 68 | 69 | //////////////////////////////////////////////////////////////////////////////// 70 | // COMPILE AN EXPRESSION, WHICH WILL RETURN A VALUE 71 | //////////////////////////////////////////////////////////////////////////////// 72 | aCompile.expression=function(code, contextTypes){ 73 | if (!(contextTypes instanceof Array)) contextTypes=[contextTypes]; 74 | var output; 75 | 76 | var contexTypeNames=[]; 77 | contextTypes.forall(function(c, i){ 78 | contexTypeNames.push("__source"+i); 79 | }); 80 | 81 | var f = 82 | "output=function("+contexTypeNames.join(",")+"){\n"; 83 | 84 | for(var s = contextTypes.length; s--;){ 85 | contextTypes[s].columns.forall(function(p){ 86 | //ONLY DEFINE VARS THAT ARE USED 87 | if (code.indexOf(p.name) != -1){ 88 | f += "var " + p.name + "="+contexTypeNames[s]+"." + p.name + ";\n"; 89 | }//endif 90 | }); 91 | }//for 92 | 93 | f+="return "+code.trim().rtrim(";")+";\n}"; 94 | eval(f); 95 | 96 | return output; 97 | 98 | }; 99 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/common/chart_title_test.js: -------------------------------------------------------------------------------- 1 | module('chart_title'); 2 | 3 | test('Chart title is updated', function() { 4 | var params = { 5 | title: 'foo', 6 | target: '#qunit-fixture', 7 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 8 | {'date': new Date('2014-03-01'), 'value': 18}] 9 | }; 10 | 11 | var params2 = MG.clone(params); 12 | params2.title = 'bar'; 13 | 14 | MG.data_graphic(params); 15 | MG.data_graphic(params2); 16 | 17 | equal(document.querySelector('.mg-chart-title').textContent, 'bar', 'Chart title is foo'); 18 | }); 19 | 20 | test('Chart title is removed if title is set to blank', function() { 21 | var params = { 22 | title: 'foo', 23 | target: '#qunit-fixture', 24 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 25 | {'date': new Date('2014-03-01'), 'value': 18}] 26 | }; 27 | 28 | var params2 = MG.clone(params); 29 | params2.title = ''; 30 | 31 | MG.data_graphic(params); 32 | MG.data_graphic(params2); 33 | equal(document.querySelector('.mg-chart-title'), null, 'Chart title is not added'); 34 | }); 35 | 36 | test('Chart title is removed if title is not set', function() { 37 | var params = { 38 | title: 'foo', 39 | target: '#qunit-fixture', 40 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 41 | {'date': new Date('2014-03-01'), 'value': 18}] 42 | }; 43 | 44 | var params2 = MG.clone(params); 45 | delete params2.title; 46 | 47 | MG.data_graphic(params); 48 | MG.data_graphic(params2); 49 | equal(document.querySelector('.mg-chart-title'), null, 'Chart title is not added'); 50 | }); 51 | 52 | test('When a description is set, we get a question mark', function() { 53 | var params = { 54 | title: 'foo', 55 | description: 'bar', 56 | target: '#qunit-fixture', 57 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 58 | {'date': new Date('2014-03-01'), 'value': 18}], 59 | show_tooltips: true 60 | }; 61 | 62 | MG.data_graphic(params); 63 | ok(document.querySelector('.mg-chart-description'), 'Description icon exists'); 64 | }); 65 | 66 | test('When an error is set, we get an exclamation icon', function() { 67 | var params = { 68 | title: 'foo', 69 | description: 'bar', 70 | target: '#qunit-fixture', 71 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 72 | {'date': new Date('2014-03-01'), 'value': 18}], 73 | error: 'lorem ipsum' 74 | }; 75 | 76 | MG.data_graphic(params); 77 | ok(document.querySelector('.mg-chart-title .mg-warning'), 'Error icon exists'); 78 | }); 79 | 80 | test('Chart title is not duplicated on redraw', function() { 81 | var params = { 82 | title: 'foo', 83 | target: '#qunit-fixture', 84 | data: [{'date': new Date('2014-01-01'), 'value': 12}, 85 | {'date': new Date('2014-03-01'), 'value': 18}] 86 | }; 87 | 88 | var params2 = MG.clone(params); 89 | MG.data_graphic(params); 90 | MG.data_graphic(params2); 91 | 92 | equal(document.querySelectorAll('.mg-chart-title').length, 1, 'there is once chart title'); 93 | }); 94 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/data/firefox_releases.json: -------------------------------------------------------------------------------- 1 | { 2 | "releases": [ 3 | { 4 | "version": "30.0", 5 | "date": "2014-06-01", 6 | "end": "2014-08-01" 7 | }, 8 | { 9 | "version": "29.0", 10 | "date": "2014-04-29", 11 | "end": "2014-06-01" 12 | 13 | }, 14 | { 15 | "version": "28.0", 16 | "date": "2014-03-18", 17 | "end": "2014-04-29" 18 | }, 19 | { 20 | "version": "27.0", 21 | "date": "2014-01-21", 22 | "end": "2014-03-18" 23 | }, 24 | { 25 | "version": "26.0", 26 | "date": "2013-12-10", 27 | "end": "2014-01-21" 28 | }, 29 | { 30 | "version": "25.0", 31 | "date": "2013-10-29", 32 | "end": "2013-12-10" 33 | 34 | }, 35 | { 36 | "version": "24.0", 37 | "date": "2013-09-17", 38 | "end": "2013-10-29" 39 | 40 | }, 41 | { 42 | "version": "23.0", 43 | "date": "2013-08-06", 44 | "end": "2013-09-17" 45 | 46 | }, 47 | { 48 | "version": "22.0", 49 | "date": "2013-06-25" 50 | }, 51 | { 52 | "version": "21.0", 53 | "date": "2013-05-14" 54 | }, 55 | { 56 | "version": "20.0", 57 | "date": "2013-04-02" 58 | }, 59 | { 60 | "version": "19.0", 61 | "date": "2013-02-19" 62 | }, 63 | { 64 | "version": "18.0", 65 | "date": "2013-01-08" 66 | }, 67 | { 68 | "version": "17.0.1", 69 | "date": "2012-11-30" 70 | }, 71 | { 72 | "version": "17.0", 73 | "date": "2012-11-20" 74 | }, 75 | { 76 | "version": "16.0.2", 77 | "date": "2012-10-26" 78 | }, 79 | { 80 | "version": "16.0.1", 81 | "date": "2012-10-11" 82 | }, 83 | { 84 | "version": "16.0", 85 | "date": "2012-10-09" 86 | }, 87 | { 88 | "version": "15.0.1", 89 | "date": "2012-09-06" 90 | }, 91 | { 92 | "version": "15.0", 93 | "date": "2012-08-28" 94 | }, 95 | { 96 | "version": "14.0", 97 | "date": "2012-07-17" 98 | }, 99 | { 100 | "version": "13.0.1", 101 | "date": "2012-06-15" 102 | }, 103 | { 104 | "version": "13.0", 105 | "date": "2012-06-05" 106 | }, 107 | { 108 | "version": "12.0", 109 | "date": "2012-04-24" 110 | }, 111 | { 112 | "version": "11.0", 113 | "date": "2012-03-13" 114 | }, 115 | { 116 | "version": "10.0", 117 | "date": "2012-01-31" 118 | }, 119 | { 120 | "version": "9.0", 121 | "date": "2011-12-20" 122 | }, 123 | { 124 | "version": "8.0", 125 | "date": "2011-11-08" 126 | }, 127 | { 128 | "version": "7.0", 129 | "date": "2011-09-27" 130 | }, 131 | { 132 | "version": "6.0", 133 | "date": "2011-08-16" 134 | }, 135 | { 136 | "version": "5.0", 137 | "date": "2011-06-21" 138 | }, 139 | { 140 | "version": "4.0", 141 | "date": "2011-03-22" 142 | }, 143 | { 144 | "version": "3.6", 145 | "date": "2010-01-21" 146 | }, 147 | { 148 | "version": "3.5", 149 | "date": "2009-06-30" 150 | }, 151 | { 152 | "version": "3.0", 153 | "date": "2008-06-17" 154 | }, 155 | { 156 | "version": "2.0", 157 | "date": "2006-10-24" 158 | }, 159 | { 160 | "version": "1.5", 161 | "date": "2005-11-29" 162 | }, 163 | { 164 | "version": "1.0", 165 | "date": "2004-11-09" 166 | } 167 | ] 168 | } 169 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/visual/legend/BulletGroupScene.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Initializes a legend bullet group scene. 4 | * 5 | * @name pvc.visual.legend.BulletGroupScene 6 | 7 | * @extends pvc.visual.Scene 8 | * 9 | * @constructor 10 | * @param {pvc.visual.legend.BulletRootScene} parent The parent bullet root scene. 11 | * @param {object} [keyArgs] Keyword arguments. 12 | * See {@link pvc.visual.Scene} for additional keyword arguments. 13 | * @param {pv.visual.legend.renderer} [keyArgs.renderer] Keyword arguments. 14 | */ 15 | def 16 | .type('pvc.visual.legend.BulletGroupScene', pvc.visual.Scene) 17 | .init(function(rootScene, keyArgs){ 18 | 19 | this.base(rootScene, keyArgs); 20 | 21 | this.extensionPrefix = def.get(keyArgs, 'extensionPrefix') || ''; 22 | this._renderer = def.get(keyArgs, 'renderer'); 23 | 24 | this.colorAxis = def.get(keyArgs, 'colorAxis'); 25 | this.clickMode = def.get(keyArgs, 'clickMode'); 26 | 27 | if(this.colorAxis && !this.clickMode){ 28 | this.clickMode = this.colorAxis.option('LegendClickMode'); 29 | } 30 | }) 31 | .add(/** @lends pvc.visual.legend.BulletGroupScene# */{ 32 | hasRenderer: function(){ 33 | return this._renderer; 34 | }, 35 | 36 | renderer: function(renderer){ 37 | if(renderer != null){ 38 | this._renderer = renderer; 39 | } else { 40 | renderer = this._renderer; 41 | if(!renderer){ 42 | var keyArgs; 43 | var colorAxis = this.colorAxis; 44 | if(colorAxis){ 45 | keyArgs = { 46 | drawRule: colorAxis.option('LegendDrawLine' ), 47 | drawMarker: colorAxis.option('LegendDrawMarker'), 48 | markerShape: colorAxis.option('LegendShape') 49 | }; 50 | } 51 | 52 | renderer = new pvc.visual.legend.BulletItemDefaultRenderer(keyArgs); 53 | this._renderer = renderer; 54 | } 55 | } 56 | 57 | return renderer; 58 | }, 59 | 60 | itemSceneType: function(){ 61 | var ItemType = this._itemSceneType; 62 | if(!ItemType){ 63 | ItemType = def.type(pvc.visual.legend.BulletItemScene); 64 | 65 | // Mixin behavior depending on click mode 66 | var clickMode = this.clickMode; 67 | switch(clickMode){ 68 | case 'toggleSelected': 69 | ItemType.add(pvc.visual.legend.BulletItemSceneSelection); 70 | break; 71 | 72 | case 'toggleVisible': 73 | ItemType.add(pvc.visual.legend.BulletItemSceneVisibility); 74 | break; 75 | } 76 | 77 | // Apply legend item scene extensions 78 | this.panel()._extendSceneType('item', ItemType, ['isOn', 'isClickable', 'click']); 79 | 80 | this._itemSceneType = ItemType; 81 | } 82 | 83 | return ItemType; 84 | }, 85 | 86 | createItem: function(keyArgs){ 87 | var ItemType = this.itemSceneType(); 88 | return new ItemType(this, keyArgs); 89 | } 90 | }); -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/Atom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Initializes an atom instance. 3 | * 4 | * @name pvc.data.Atom 5 | * 6 | * @class An atom represents a unit of information. 7 | * 8 | *

9 | * To create an atom, 10 | * call the corresponding dimension's 11 | * {@link pvc.data.Dimension#intern} method. 12 | * 13 | * Usually this is done by a {@link pvc.data.TranslationOper}. 14 | *

15 | * 16 | * @property {pvc.data.Dimension} dimension The owner dimension. 17 | * 18 | * @property {number} id 19 | * A unique object identifier. 20 | * 21 | * @property {any} rawValue The raw value from which {@link #value} is derived. 22 | *

23 | * It is not always defined. 24 | * Values may be the result of 25 | * combining multiple source values. 26 | * 27 | * Values may even be constant 28 | * and, as such, 29 | * not be derived from 30 | * any of the source values. 31 | *

32 | * 33 | * @property {any} value The typed value of the atom. 34 | * It must be consistent with the corresponding {@link pvc.data.DimensionType#valueType}. 35 | * 36 | * @property {string} label The formatted value. 37 | *

38 | * Only the null atom can have a empty label. 39 | *

40 | * 41 | * @property {string} key The value of the atom expressed as a 42 | * string in a way that is unique amongst all atoms of its dimension. 43 | *

44 | * Only the null atom has a key equal to "". 45 | *

46 | * @property {string} globalKey A semantic key that is unique across atoms of every dimensions. 47 | * 48 | * @constructor 49 | * @private 50 | * @param {pvc.data.Dimension} dimension The dimension that the atom belongs to. 51 | * @param {any} value The typed value. 52 | * @param {string} label The formatted value. 53 | * @param {any} rawValue The source value. 54 | * @param {string} key The key. 55 | */ 56 | def.type('pvc.data.Atom') 57 | .init( 58 | function(dimension, value, label, rawValue, key) { 59 | this.dimension = dimension; 60 | this.id = (value == null ? -def.nextId() : def.nextId()); // Ensure null sorts first, when sorted by id 61 | this.value = value; 62 | this.label = label; 63 | if(rawValue !== undefined){ 64 | this.rawValue = rawValue; 65 | } 66 | this.key = key; 67 | }) 68 | .add( /** @lends pvc.data.Atom */{ 69 | isVirtual: false, 70 | 71 | rawValue: undefined, 72 | 73 | /** 74 | * Obtains the label of the atom. 75 | */ 76 | toString: function(){ 77 | var label = this.label; 78 | if(label != null){ 79 | return label; 80 | } 81 | 82 | label = this.value; 83 | return label != null ? ("" + label) : ""; 84 | } 85 | }); 86 | 87 | 88 | /** 89 | * Comparer for atom according to their id. 90 | */ 91 | function atom_idComparer(a, b) { 92 | return a.id - b.id; // works for numbers... 93 | } 94 | 95 | /** 96 | * Reverse comparer for atom according to their id. 97 | */ 98 | function atom_idComparerReverse(a, b) { 99 | return b.id - a.id; // works for numbers... 100 | } -------------------------------------------------------------------------------- /quantum/modevlib/gui/accordion.js: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // This Source Code Form is subject to the terms of the Mozilla Public 3 | // License, v. 2.0. If a copy of the MPL was not distributed with this 4 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 | //////////////////////////////////////////////////////////////////////////////// 6 | // Author: Kyle Lahnakoski (kyle@lahnakoski.com) 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | importScript("../../lib/jquery.js"); 10 | 11 | /////////////////////////////////////////////////////////////////////////////// 12 | // DROP-DOWN ACCORDIONS 13 | // 14 | // MARKUP DOM ELEMENTS WITH class="accordion_header" TO USE THIS LIBRARY 15 | // 16 | // class="accordion_header_open" - WHEN BODY IS OPEN 17 | // class="accordion_header_closed" - WHEN BODY IS CLOSED (ASSIGNED IMMEDIATELY) 18 | // accordion_id - POINTS TO THE ID OF ELEMENT TO EXPAND/CONTRACT 19 | // accordion_group - ONLY ONE MEMBER OF THE GROUP CAN STAY OPEN 20 | // 21 | // jquery is extended with updateAccordion() TO RESIZE THE BODY 22 | // 23 | /////////////////////////////////////////////////////////////////////////////// 24 | 25 | 26 | $(document).ready(function () { 27 | function close(e) { 28 | return e.animate({"height": 0}, 500); 29 | } 30 | 31 | function open(e) { 32 | var height=0; 33 | e.children().each(function(){ 34 | var oh=$(this).outerHeight(); 35 | height+=oh; 36 | }); 37 | e.css({"display":"block"}); 38 | e.animate({"height": height+"px"}, 500); 39 | } 40 | 41 | //MAKE SURE OPEN DIV RESIZE TO FULL 42 | $.fn.updateAccordion = function update(){ 43 | var self=$(this); 44 | $(".accordion_header_open[accordion_id='" + self.attr("id") + "']").each(function(){ 45 | open(self); 46 | }); 47 | return this; 48 | }; 49 | 50 | $(".accordion_header, .accordion_header_open, .accordion_header_closed") 51 | .click(function (e) { 52 | var self = $(this); 53 | var group=self.attr("accordion_group"); 54 | //CLOSE THE OTHERS 55 | $(".accordion_header_open[accordion_group='" + group + "']").each(function () { 56 | var other=$(this); 57 | if (self.get(0) !== other.get(0)) { 58 | other.addClass("accordion_header_closed").removeClass("accordion_header_open"); 59 | close($("#" + other.attr("accordion_id"))); 60 | }//endif 61 | }); 62 | //TOGGLE THIS' STATE 63 | if (["accordion_header_open"].contains(self.attr("class"))) { 64 | self.addClass("accordion_header_closed").removeClass("accordion_header_open"); 65 | close($("#" + self.attr("accordion_id"))); 66 | } else { 67 | self.addClass("accordion_header_open").removeClass("accordion_header_closed"); 68 | open($("#" + self.attr("accordion_id"))); 69 | }//endif 70 | }) 71 | .each(function () { 72 | var self = $(this); 73 | var body = $("#" + self.attr("accordion_id")); 74 | body.addClass("accordion_body"); 75 | 76 | if (self.attr("class") == "accordion_header") { 77 | //DEFAULT IS CLOSED 78 | self.addClass("accordion_header_closed"); 79 | self.removeClass("accordion_header"); 80 | body.css({"display":"none"}); 81 | close(body); 82 | }else if (self.attr("class") == "accordion_header_closed") { 83 | body.css({"display":"none"}); 84 | close(body); 85 | }//endif 86 | }); 87 | }); 88 | 89 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/charts/bar_test.js: -------------------------------------------------------------------------------- 1 | var target = '#qunit-fixture', 2 | defaults; 3 | 4 | module('bar', { 5 | setup: function() { 6 | defaults = { 7 | target: target, 8 | chart_type: 'bar', 9 | x_accessor: 'value', 10 | y_accessor: 'label', 11 | transition_on_update: false, 12 | data: [{ 13 | label: 'Bar 1', 14 | value: 100 15 | },{ 16 | label: 'Bar 2', 17 | value: 200 18 | },{ 19 | label: 'Bar 3', 20 | value: 300 21 | }] 22 | }; 23 | } 24 | }); 25 | 26 | test('Correct number of bars are added', function() { 27 | expect(1); 28 | MG.data_graphic(defaults); 29 | equal(document.querySelectorAll('.mg-bar').length, 3, 'Should have 3 bars'); 30 | }); 31 | 32 | test('Triggers callbacks when provided', function() { 33 | var mouseoverCalled = false, 34 | mousemoveCalled = false, 35 | mouseoutCalled = false, 36 | 37 | params = extend(defaults, { 38 | mouseover: function() { 39 | mouseoverCalled = true; 40 | }, 41 | mousemove: function() { 42 | mousemoveCalled = true; 43 | }, 44 | mouseout: function() { 45 | mouseoutCalled = true; 46 | } 47 | }); 48 | 49 | MG.data_graphic(params); 50 | 51 | var bar = document.getElementsByClassName('mg-bar-rollover')[0]; 52 | 53 | bar.dispatchEvent(generateMouseEvent('mouseover')); 54 | equal(mouseoverCalled, true, 'mouseover was called'); 55 | 56 | bar.dispatchEvent(generateMouseEvent('mousemove')); 57 | equal(mousemoveCalled, true, 'mousemove was called'); 58 | 59 | bar.dispatchEvent(generateMouseEvent('mouseout')); 60 | equal(mouseoutCalled, true, 'mouseout was called'); 61 | }); 62 | 63 | // test('When updating', function() { 64 | // var bars = [{ 65 | // label: 'Bar 1', 66 | // value: 100, 67 | // predictor: 75, 68 | // baseline: 50 69 | // }]; 70 | 71 | // var params = extend(defaults, { 72 | // data: bars, 73 | // height: 100, 74 | // width: 300, 75 | // orientation: 'vertical', 76 | // predictor_accessor: 'predictor', 77 | // baseline_accessor: 'baseline', 78 | // animate_on_load: false, 79 | // transition_on_update: false 80 | // }); 81 | 82 | // MG.data_graphic(params); 83 | // equal(164, d3.select(target).select('.mg-barplot .mg-bar').attr('width'), 'initial bar size is correct'); 84 | // equal(123, d3.select(target).select('.mg-barplot .mg-bar-prediction').attr('width'), 'initial predictor size is correct'); 85 | // equal(160, d3.select(target).select('.mg-barplot .mg-bar-baseline').attr('x1'), 'initial baseline position is correct'); 86 | 87 | // params.data[0][0].value = 50; 88 | // params.data[0][0].predictor = 100; 89 | // params.data[0][0].baseline = 75; 90 | 91 | // MG.data_graphic(params); 92 | // equal(82, d3.select(target).select('.mg-barplot .mg-bar').attr('width'), 'the bars are redrawn with correct sizes'); 93 | // equal(164, d3.select(target).select('.mg-barplot .mg-bar-prediction').attr('width'), 'the predictors are redrawn with correct sizes'); 94 | // equal(201, d3.select(target).select('.mg-barplot .mg-bar-baseline').attr('x1'), 'the baseline is redrawn in the correct position'); 95 | // }); 96 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/pvcBarChart.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * BarChart is the main class for generating... bar charts (another surprise!). 4 | */ 5 | def 6 | .type('pvc.BarChart', pvc.BarAbstract) 7 | .add({ 8 | 9 | _allowV1SecondAxis: true, 10 | 11 | _initPlotsCore: function(hasMultiRole){ 12 | var options = this.options; 13 | 14 | var barPlot = new pvc.visual.BarPlot(this); 15 | var trend = barPlot.option('Trend'); 16 | 17 | if(options.plot2){ 18 | // Line Plot 19 | var plot2Plot = new pvc.visual.PointPlot(this, { 20 | name: 'plot2', 21 | fixed: { 22 | DataPart: '1' 23 | }, 24 | defaults: { 25 | ColorAxis: 2, 26 | LinesVisible: true, 27 | DotsVisible: true 28 | }}); 29 | 30 | if(!trend){ 31 | trend = plot2Plot.option('Trend'); 32 | } 33 | } 34 | 35 | if(trend){ 36 | // Trend Plot 37 | new pvc.visual.PointPlot(this, { 38 | name: 'trend', 39 | fixed: { 40 | DataPart: 'trend', 41 | TrendType: 'none', 42 | ColorRole: 'series', // one trend per series 43 | NullInterpolatioMode: 'none' 44 | }, 45 | defaults: { 46 | ColorAxis: 2, 47 | LinesVisible: true, 48 | DotsVisible: false 49 | } 50 | }); 51 | } 52 | }, 53 | 54 | _hasDataPartRole: function(){ 55 | return true; 56 | }, 57 | 58 | /** 59 | * @override 60 | */ 61 | _createPlotPanels: function(parentPanel, baseOptions){ 62 | var plots = this.plots; 63 | 64 | var barPlot = plots.bar; 65 | var barPanel = new pvc.BarPanel( 66 | this, 67 | parentPanel, 68 | barPlot, 69 | Object.create(baseOptions)); 70 | 71 | // legacy field 72 | this.barChartPanel = barPanel; 73 | 74 | var plot2Plot = plots.plot2; 75 | if(plot2Plot){ 76 | if(pvc.debug >= 3){ 77 | this._log("Creating Point panel."); 78 | } 79 | 80 | var pointPanel = new pvc.PointPanel( 81 | this, 82 | parentPanel, 83 | plot2Plot, 84 | Object.create(baseOptions)); 85 | 86 | // Legacy fields 87 | barPanel.pvSecondLine = pointPanel.pvLine; 88 | barPanel.pvSecondDot = pointPanel.pvDot; 89 | 90 | pointPanel._applyV1BarSecondExtensions = true; 91 | } 92 | 93 | var trendPlot = plots.trend; 94 | if(trendPlot){ 95 | if(pvc.debug >= 3){ 96 | this._log("Creating Trends Point panel."); 97 | } 98 | 99 | new pvc.PointPanel( 100 | this, 101 | parentPanel, 102 | trendPlot, 103 | Object.create(baseOptions)); 104 | } 105 | } 106 | }); 107 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/tests/charts/missing_test.js: -------------------------------------------------------------------------------- 1 | module('missing'); 2 | 3 | test('Missing chart\'s text matches specified missing_text', function() { 4 | var params = { 5 | target: '#qunit-fixture', 6 | chart_type: 'missing-data', 7 | missing_text: 'In an astral plane that was never meant to fly...' 8 | }; 9 | 10 | MG.data_graphic(params); 11 | equal(document.querySelector('.mg-missing-text').textContent, 12 | params.missing_text, 13 | 'Missing chart\'s text matches missing_text'); 14 | }); 15 | 16 | test('Only one mg-missing-pane on multiple calls to the same target element', function() { 17 | var params = { 18 | target: '#qunit-fixture', 19 | chart_type: 'missing-data', 20 | missing_text: 'In an astral plane that was never meant to fly...' 21 | }; 22 | 23 | MG.data_graphic(params); 24 | MG.data_graphic(MG.clone(params)); 25 | 26 | equal(document.querySelectorAll(params.target + ' .mg-missing-pane').length, 1, 'We only have one mg-missing-pane'); 27 | }); 28 | 29 | test('Only one mg-missing-text on multiple calls to the same target element', function() { 30 | var params = { 31 | target: '#qunit-fixture', 32 | chart_type: 'missing-data', 33 | missing_text: 'In an astral plane that was never meant to fly...' 34 | }; 35 | 36 | MG.data_graphic(params); 37 | MG.data_graphic(MG.clone(params)); 38 | 39 | equal(document.querySelectorAll(params.target + ' .mg-missing-text').length, 1, 'We only have one mg-missing-text'); 40 | }); 41 | 42 | test('missing chart obeys full_width: true', function() { 43 | var params = { 44 | target: '#qunit-fixture', 45 | chart_type: 'missing-data', 46 | full_width: true, 47 | missing_text: 'In an astral plane that was never meant to fly...' 48 | }; 49 | document.querySelector('#qunit-fixture').style.width='700px'; 50 | 51 | MG.data_graphic(params); 52 | 53 | equal(document.querySelector('#qunit-fixture svg').getAttribute('width'), 700, 'The missing chart svg has same width as parent element.'); 54 | }); 55 | 56 | test('missing chart obeys full_height: true', function() { 57 | var params = { 58 | target: '#qunit-fixture', 59 | chart_type: 'missing-data', 60 | full_height: true, 61 | missing_text: 'In an astral plane that was never meant to fly...' 62 | }; 63 | document.querySelector('#qunit-fixture').style.height='700px'; 64 | 65 | MG.data_graphic(params); 66 | 67 | equal(document.querySelector('#qunit-fixture svg').getAttribute('height'), 700, 'The missing chart svg has same width as parent element.'); 68 | }); 69 | 70 | test('Missing chart\'s width is set correctly on subsequent calls to existing chart', function() { 71 | var params_0 = { 72 | target: '#qunit-fixture', 73 | chart_type: 'missing-data', 74 | missing_text: 'In an astral plane that was never meant to fly...' 75 | }; 76 | 77 | var params = { 78 | target: '#qunit-fixture', 79 | chart_type: 'missing-data', 80 | missing_text: 'In an astral plane that was never meant to fly...', 81 | width: 200, 82 | height: 100, 83 | }; 84 | 85 | MG.data_graphic(params_0); 86 | MG.data_graphic(params); 87 | 88 | var width = document.querySelector(params.target + ' svg').clientWidth; 89 | ok(width == 200, 'SVG\'s width matches latest specified width'); 90 | }); 91 | -------------------------------------------------------------------------------- /quantum/lib/ccc/data/dt.js: -------------------------------------------------------------------------------- 1 | 2 | var datTreeTestStructure_01 = { 3 | "resultset": [ 4 | ["A1", "Profit", "winst", "sum", "B1 B2"], 5 | ["B1", "Contribution-margin", "bijdrage", "sum", ""], 6 | ["B2 ", "Cost", "kosten", "sum", ""] 7 | ], 8 | "metadata": [{ 9 | "colIndex": 0, 10 | "colType": "String", 11 | "colName": "box_id" 12 | }, { 13 | "colIndex": 1, 14 | "colType": "String", 15 | "colName": "label" 16 | }, { 17 | "colIndex": 2, 18 | "colType": "String", 19 | "colName": "selector" 20 | }, { 21 | "colIndex": 3, 22 | "colType": "String", 23 | "colName": "aggregation" 24 | }, { 25 | "colIndex": 4, 26 | "colType": "String", 27 | "colName": "children" 28 | } 29 | ] 30 | }; 31 | 32 | var datTreeTestData_01 = { 33 | "resultset": [ 34 | ["winst", "_p5", 10], 35 | ["winst", "_p25", 30], 36 | ["winst", "_p50", 35], 37 | ["winst", "_p75", 40], 38 | ["winst", "_p95", 50], 39 | ["winst", "team A", 45], 40 | ["winst", "team B", 17], 41 | 42 | ["bijdrage", "_p5", 10], 43 | ["bijdrage", "_p25", 30], 44 | ["bijdrage", "_p50", 60], 45 | ["bijdrage", "_p75", 80], 46 | ["bijdrage", "_p95", 95], 47 | ["bijdrage", "team A", 55], 48 | ["bijdrage", "team B", 77], 49 | 50 | ["kosten", "_p5", 3], 51 | ["kosten", "_p25", 20], 52 | ["kosten", "_p50", 50], 53 | ["kosten", "_p75", 60], 54 | ["kosten", "_p95", 80], 55 | ["kosten", "team A", 10], 56 | ["kosten", "team B", 60] 57 | ], 58 | "metadata": [{ 59 | "colIndex": 0, 60 | "colType": "String", 61 | "colName": "selector" 62 | }, { 63 | "colIndex": 1, 64 | "colType": "String", 65 | "colName": "category" 66 | }, { 67 | "colIndex": 2, 68 | "colType": "Numeric", 69 | "colName": "value" 70 | } 71 | ] 72 | }; 73 | 74 | var datTreeTestStructure_02 = { 75 | "resultset": [ 76 | ["A1", "Winst", "winst", "sum", "B1 B2", 100, 70], 77 | ["B1", "Bijdrage", "bijdrage", "sum", "", 300, 100], 78 | ["B2 ", "Kosten", "kosten", "sum", "", 20, 200] 79 | ], 80 | "metadata": [{ 81 | "colIndex": 0, 82 | "colType": "String", 83 | "colName": "box_id" 84 | }, { 85 | "colIndex": 1, 86 | "colType": "String", 87 | "colName": "label" 88 | }, { 89 | "colIndex": 2, 90 | "colType": "String", 91 | "colName": "selector" 92 | }, { 93 | "colIndex": 3, 94 | "colType": "String", 95 | "colName": "aggregation" 96 | }, { 97 | "colIndex": 4, 98 | "colType": "String", 99 | "colName": "children" 100 | }, { 101 | "colIndex": 5, 102 | "colType": "Integer", 103 | "colName": "bottom" 104 | }, { 105 | "colIndex": 6, 106 | "colType": "Integer", 107 | "colName": "height" 108 | } 109 | ] 110 | }; 111 | 112 | -------------------------------------------------------------------------------- /quantum/lib/metrics-graphics/examples/css/highlightjs-default.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Original style from softwaremaniacs.org (c) Ivan Sagalaev 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #f0f0f0; 12 | -webkit-text-size-adjust: none; 13 | } 14 | 15 | .hljs, 16 | .hljs-subst, 17 | .hljs-tag .hljs-title, 18 | .nginx .hljs-title { 19 | color: black; 20 | } 21 | 22 | .hljs-string, 23 | .hljs-title, 24 | .hljs-constant, 25 | .hljs-parent, 26 | .hljs-tag .hljs-value, 27 | .hljs-rules .hljs-value, 28 | .hljs-preprocessor, 29 | .hljs-pragma, 30 | .haml .hljs-symbol, 31 | .ruby .hljs-symbol, 32 | .ruby .hljs-symbol .hljs-string, 33 | .hljs-template_tag, 34 | .django .hljs-variable, 35 | .smalltalk .hljs-class, 36 | .hljs-addition, 37 | .hljs-flow, 38 | .hljs-stream, 39 | .bash .hljs-variable, 40 | .apache .hljs-tag, 41 | .apache .hljs-cbracket, 42 | .tex .hljs-command, 43 | .tex .hljs-special, 44 | .erlang_repl .hljs-function_or_atom, 45 | .asciidoc .hljs-header, 46 | .markdown .hljs-header, 47 | .coffeescript .hljs-attribute { 48 | color: #e6337c; 49 | } 50 | 51 | .smartquote, 52 | .hljs-comment, 53 | .hljs-annotation, 54 | .hljs-template_comment, 55 | .diff .hljs-header, 56 | .hljs-chunk, 57 | .asciidoc .hljs-blockquote, 58 | .markdown .hljs-blockquote { 59 | color: #888; 60 | } 61 | 62 | .hljs-number, 63 | .hljs-date, 64 | .hljs-regexp, 65 | .hljs-literal, 66 | .hljs-hexcolor, 67 | .smalltalk .hljs-symbol, 68 | .smalltalk .hljs-char, 69 | .go .hljs-constant, 70 | .hljs-change, 71 | .lasso .hljs-variable, 72 | .makefile .hljs-variable, 73 | .asciidoc .hljs-bullet, 74 | .markdown .hljs-bullet, 75 | .asciidoc .hljs-link_url, 76 | .markdown .hljs-link_url { 77 | color: #366797; 78 | } 79 | 80 | .hljs-label, 81 | .hljs-javadoc, 82 | .ruby .hljs-string, 83 | .hljs-decorator, 84 | .hljs-filter .hljs-argument, 85 | .hljs-localvars, 86 | .hljs-array, 87 | .hljs-attr_selector, 88 | .hljs-important, 89 | .hljs-pseudo, 90 | .hljs-pi, 91 | .haml .hljs-bullet, 92 | .hljs-doctype, 93 | .hljs-deletion, 94 | .hljs-envvar, 95 | .hljs-shebang, 96 | .apache .hljs-sqbracket, 97 | .nginx .hljs-built_in, 98 | .tex .hljs-formula, 99 | .erlang_repl .hljs-reserved, 100 | .hljs-prompt, 101 | .asciidoc .hljs-link_label, 102 | .markdown .hljs-link_label, 103 | .vhdl .hljs-attribute, 104 | .clojure .hljs-attribute, 105 | .asciidoc .hljs-attribute, 106 | .lasso .hljs-attribute, 107 | .coffeescript .hljs-property, 108 | .hljs-phony { 109 | color: #88f; 110 | } 111 | 112 | .hljs-keyword, 113 | .hljs-id, 114 | .hljs-title, 115 | .hljs-built_in, 116 | .css .hljs-tag, 117 | .hljs-javadoctag, 118 | .hljs-phpdoc, 119 | .hljs-dartdoc, 120 | .hljs-yardoctag, 121 | .smalltalk .hljs-class, 122 | .hljs-winutils, 123 | .bash .hljs-variable, 124 | .apache .hljs-tag, 125 | .hljs-type, 126 | .hljs-typename, 127 | .tex .hljs-command, 128 | .asciidoc .hljs-strong, 129 | .markdown .hljs-strong, 130 | .hljs-request, 131 | .hljs-status { 132 | font-weight: bold; 133 | } 134 | 135 | .asciidoc .hljs-emphasis, 136 | .markdown .hljs-emphasis { 137 | font-style: italic; 138 | } 139 | 140 | .nginx .hljs-built_in { 141 | font-weight: normal; 142 | } 143 | 144 | .coffeescript .javascript, 145 | .javascript .xml, 146 | .lasso .markup, 147 | .tex .hljs-formula, 148 | .xml .javascript, 149 | .xml .vbscript, 150 | .xml .css, 151 | .xml .hljs-cdata { 152 | opacity: 0.5; 153 | } 154 | -------------------------------------------------------------------------------- /quantum/lib/ccc/pvc/data/translation/MetricPointChartTranslationOper.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * @name pvc.data.MetricPointChartTranslationOper 4 | * 5 | * @class The translation mixin of the Metric XY charts. 6 | * 7 | *

8 | * The default format is: 9 | *

10 | *
11 |  * +----------+----------+----------+----------+----------+
12 |  * | 0        | 1        | 2        | 3        | 4        |
13 |  * +----------+----------+----------+----------+----------+
14 |  * | series   | x        | y        | color    | size     |
15 |  * +----------+----------+----------+----------+----------+
16 |  * | discrete | number   | number   | num/disc | number   |
17 |  * +----------+----------+----------+----------+----------+
18 |  * 
19 | * 20 | *

21 | * Color dimensions will be continuous by default. 22 | * If that is not the case, 23 | * an explicit dimension valueType definition must be provided. 24 | *

25 | * 26 | * @extends pvc.data.MatrixTranslationOper 27 | */ 28 | def.type('pvc.data.MetricPointChartTranslationOper') 29 | .add(/** @lends pvc.data.MetricPointChartTranslationOper# */{ 30 | 31 | _meaLayoutRoles: ['x', 'y', 'color', 'size'], 32 | 33 | configureType: function(){ 34 | var itemTypes = this._itemTypes; 35 | 36 | var V = itemTypes.length; 37 | 38 | // VItem Indexes of continuous columns not yet being read 39 | var freeMeaIndexes = []; 40 | 41 | // Idem, but for discrete columns 42 | var freeDisIndexes = []; 43 | 44 | def 45 | .range(0, V) 46 | .each(function(j){ 47 | if(!this._userUsedIndexes[j]){ 48 | if(itemTypes[j] === 1){ 49 | freeMeaIndexes.push(j); 50 | } else { 51 | freeDisIndexes.push(j); 52 | } 53 | } 54 | }, this); 55 | 56 | // Distribute free measure columns by unbound measure roles 57 | var N; 58 | var autoDimNames = []; 59 | var F = freeMeaIndexes.length; 60 | if(F > 0){ 61 | // Collect the default dimension names of the 62 | // first F unbound roles 63 | var R = this._meaLayoutRoles.length; 64 | var i = 0; 65 | while(i < R && autoDimNames.length < F){ 66 | // If the measure role is unbound and has a default dimension, 67 | // the next unused dimension of the default dimension group name 68 | // is placed in autoDimNames. 69 | // If any, this dimension will be fed with the next freeMeaIndexes 70 | this._getUnboundRoleDefaultDimNames(this._meaLayoutRoles[i], 1, autoDimNames); 71 | i++; 72 | } 73 | 74 | N = autoDimNames.length; 75 | if(N > 0){ 76 | freeMeaIndexes.length = N; 77 | this.defReader({names: autoDimNames, indexes: freeMeaIndexes}); 78 | } 79 | } 80 | 81 | // All discrete columns go to series dimensions 82 | F = freeDisIndexes.length; 83 | if(F > 0){ 84 | autoDimNames.length = 0; 85 | this._getUnboundRoleDefaultDimNames('series', F, autoDimNames); 86 | 87 | N = autoDimNames.length; 88 | if(N > 0){ 89 | freeDisIndexes.length = N; 90 | this.defReader({names: autoDimNames, indexes: freeDisIndexes}); 91 | } 92 | } 93 | } 94 | }); --------------------------------------------------------------------------------