mirror of https://github.com/apache/cloudstack.git
Update jquery and related libraries (#3069)
* Update jquery, jquery ui, jquery validate and flot to current versions update jquery to 3.3.1 update jqueryui to 1.12.1 update jquery validate to 1.17.0 update jquery flot to 0.8.3 * Replace deprecated removed jquery functions * Fix initial tab content loading in detailView * Fix logout for new jquery version * Fix tooltip detail displaying for new JQuery version * Fix view all trigger in detailView for new JQuery version * Fix breadcrumb click event handler for JQuery update * Fix displaying of preselected zone in instanceWizard for new jQuery verion
This commit is contained in:
parent
ac73e7e671
commit
093ab722b3
|
|
@ -102,7 +102,7 @@
|
||||||
<p><translate key="message.select.a.zone"/></p>
|
<p><translate key="message.select.a.zone"/></p>
|
||||||
<div class="select-area">
|
<div class="select-area">
|
||||||
<div class="desc"></div>
|
<div class="desc"></div>
|
||||||
<select name="zoneid" class="required">
|
<select name="zoneid" class="required" required>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -18,162 +18,163 @@
|
||||||
*
|
*
|
||||||
* V. 1.1: Fix error handling so e.g. parsing an empty string does
|
* V. 1.1: Fix error handling so e.g. parsing an empty string does
|
||||||
* produce a color rather than just crashing.
|
* produce a color rather than just crashing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$.color = {};
|
$.color = {};
|
||||||
|
|
||||||
// construct color object with some convenient chainable helpers
|
// construct color object with some convenient chainable helpers
|
||||||
$.color.make = function (r, g, b, a) {
|
$.color.make = function (r, g, b, a) {
|
||||||
var o = {};
|
var o = {};
|
||||||
o.r = r || 0;
|
o.r = r || 0;
|
||||||
o.g = g || 0;
|
o.g = g || 0;
|
||||||
o.b = b || 0;
|
o.b = b || 0;
|
||||||
o.a = a != null ? a : 1;
|
o.a = a != null ? a : 1;
|
||||||
|
|
||||||
o.add = function (c, d) {
|
o.add = function (c, d) {
|
||||||
for (var i = 0; i < c.length; ++i)
|
for (var i = 0; i < c.length; ++i)
|
||||||
o[c.charAt(i)] += d;
|
o[c.charAt(i)] += d;
|
||||||
return o.normalize();
|
return o.normalize();
|
||||||
};
|
|
||||||
|
|
||||||
o.scale = function (c, f) {
|
|
||||||
for (var i = 0; i < c.length; ++i)
|
|
||||||
o[c.charAt(i)] *= f;
|
|
||||||
return o.normalize();
|
|
||||||
};
|
|
||||||
|
|
||||||
o.toString = function () {
|
|
||||||
if (o.a >= 1.0) {
|
|
||||||
return "rgb("+[o.r, o.g, o.b].join(",")+")";
|
|
||||||
} else {
|
|
||||||
return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
o.normalize = function () {
|
|
||||||
function clamp(min, value, max) {
|
|
||||||
return value < min ? min: (value > max ? max: value);
|
|
||||||
}
|
|
||||||
|
|
||||||
o.r = clamp(0, parseInt(o.r), 255);
|
|
||||||
o.g = clamp(0, parseInt(o.g), 255);
|
|
||||||
o.b = clamp(0, parseInt(o.b), 255);
|
|
||||||
o.a = clamp(0, o.a, 1);
|
|
||||||
return o;
|
|
||||||
};
|
|
||||||
|
|
||||||
o.clone = function () {
|
|
||||||
return $.color.make(o.r, o.b, o.g, o.a);
|
|
||||||
};
|
|
||||||
|
|
||||||
return o.normalize();
|
|
||||||
}
|
|
||||||
|
|
||||||
// extract CSS color property from element, going up in the DOM
|
|
||||||
// if it's "transparent"
|
|
||||||
$.color.extract = function (elem, css) {
|
|
||||||
var c;
|
|
||||||
do {
|
|
||||||
c = elem.css(css).toLowerCase();
|
|
||||||
// keep going until we find an element that has color, or
|
|
||||||
// we hit the body
|
|
||||||
if (c != '' && c != 'transparent')
|
|
||||||
break;
|
|
||||||
elem = elem.parent();
|
|
||||||
} while (!$.nodeName(elem.get(0), "body"));
|
|
||||||
|
|
||||||
// catch Safari's way of signalling transparent
|
|
||||||
if (c == "rgba(0, 0, 0, 0)")
|
|
||||||
c = "transparent";
|
|
||||||
|
|
||||||
return $.color.parse(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
|
|
||||||
// returns color object, if parsing failed, you get black (0, 0,
|
|
||||||
// 0) out
|
|
||||||
$.color.parse = function (str) {
|
|
||||||
var res, m = $.color.make;
|
|
||||||
|
|
||||||
// Look for rgb(num,num,num)
|
|
||||||
if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
|
|
||||||
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
|
|
||||||
|
|
||||||
// Look for rgba(num,num,num,num)
|
|
||||||
if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
|
||||||
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
|
|
||||||
|
|
||||||
// Look for rgb(num%,num%,num%)
|
|
||||||
if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
|
|
||||||
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
|
|
||||||
|
|
||||||
// Look for rgba(num%,num%,num%,num)
|
|
||||||
if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
|
||||||
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
|
|
||||||
|
|
||||||
// Look for #a0b1c2
|
|
||||||
if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
|
|
||||||
return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
|
|
||||||
|
|
||||||
// Look for #fff
|
|
||||||
if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
|
|
||||||
return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
|
|
||||||
|
|
||||||
// Otherwise, we're most likely dealing with a named color
|
|
||||||
var name = $.trim(str).toLowerCase();
|
|
||||||
if (name == "transparent")
|
|
||||||
return m(255, 255, 255, 0);
|
|
||||||
else {
|
|
||||||
// default to black
|
|
||||||
res = lookupColors[name] || [0, 0, 0];
|
|
||||||
return m(res[0], res[1], res[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var lookupColors = {
|
|
||||||
aqua:[0,255,255],
|
|
||||||
azure:[240,255,255],
|
|
||||||
beige:[245,245,220],
|
|
||||||
black:[0,0,0],
|
|
||||||
blue:[0,0,255],
|
|
||||||
brown:[165,42,42],
|
|
||||||
cyan:[0,255,255],
|
|
||||||
darkblue:[0,0,139],
|
|
||||||
darkcyan:[0,139,139],
|
|
||||||
darkgrey:[169,169,169],
|
|
||||||
darkgreen:[0,100,0],
|
|
||||||
darkkhaki:[189,183,107],
|
|
||||||
darkmagenta:[139,0,139],
|
|
||||||
darkolivegreen:[85,107,47],
|
|
||||||
darkorange:[255,140,0],
|
|
||||||
darkorchid:[153,50,204],
|
|
||||||
darkred:[139,0,0],
|
|
||||||
darksalmon:[233,150,122],
|
|
||||||
darkviolet:[148,0,211],
|
|
||||||
fuchsia:[255,0,255],
|
|
||||||
gold:[255,215,0],
|
|
||||||
green:[0,128,0],
|
|
||||||
indigo:[75,0,130],
|
|
||||||
khaki:[240,230,140],
|
|
||||||
lightblue:[173,216,230],
|
|
||||||
lightcyan:[224,255,255],
|
|
||||||
lightgreen:[144,238,144],
|
|
||||||
lightgrey:[211,211,211],
|
|
||||||
lightpink:[255,182,193],
|
|
||||||
lightyellow:[255,255,224],
|
|
||||||
lime:[0,255,0],
|
|
||||||
magenta:[255,0,255],
|
|
||||||
maroon:[128,0,0],
|
|
||||||
navy:[0,0,128],
|
|
||||||
olive:[128,128,0],
|
|
||||||
orange:[255,165,0],
|
|
||||||
pink:[255,192,203],
|
|
||||||
purple:[128,0,128],
|
|
||||||
violet:[128,0,128],
|
|
||||||
red:[255,0,0],
|
|
||||||
silver:[192,192,192],
|
|
||||||
white:[255,255,255],
|
|
||||||
yellow:[255,255,0]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
o.scale = function (c, f) {
|
||||||
|
for (var i = 0; i < c.length; ++i)
|
||||||
|
o[c.charAt(i)] *= f;
|
||||||
|
return o.normalize();
|
||||||
|
};
|
||||||
|
|
||||||
|
o.toString = function () {
|
||||||
|
if (o.a >= 1.0) {
|
||||||
|
return "rgb("+[o.r, o.g, o.b].join(",")+")";
|
||||||
|
} else {
|
||||||
|
return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
o.normalize = function () {
|
||||||
|
function clamp(min, value, max) {
|
||||||
|
return value < min ? min: (value > max ? max: value);
|
||||||
|
}
|
||||||
|
|
||||||
|
o.r = clamp(0, parseInt(o.r), 255);
|
||||||
|
o.g = clamp(0, parseInt(o.g), 255);
|
||||||
|
o.b = clamp(0, parseInt(o.b), 255);
|
||||||
|
o.a = clamp(0, o.a, 1);
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
|
||||||
|
o.clone = function () {
|
||||||
|
return $.color.make(o.r, o.b, o.g, o.a);
|
||||||
|
};
|
||||||
|
|
||||||
|
return o.normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract CSS color property from element, going up in the DOM
|
||||||
|
// if it's "transparent"
|
||||||
|
$.color.extract = function (elem, css) {
|
||||||
|
var c;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = elem.css(css).toLowerCase();
|
||||||
|
// keep going until we find an element that has color, or
|
||||||
|
// we hit the body or root (have no parent)
|
||||||
|
if (c != '' && c != 'transparent')
|
||||||
|
break;
|
||||||
|
elem = elem.parent();
|
||||||
|
} while (elem.length && !$.nodeName(elem.get(0), "body"));
|
||||||
|
|
||||||
|
// catch Safari's way of signalling transparent
|
||||||
|
if (c == "rgba(0, 0, 0, 0)")
|
||||||
|
c = "transparent";
|
||||||
|
|
||||||
|
return $.color.parse(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
|
||||||
|
// returns color object, if parsing failed, you get black (0, 0,
|
||||||
|
// 0) out
|
||||||
|
$.color.parse = function (str) {
|
||||||
|
var res, m = $.color.make;
|
||||||
|
|
||||||
|
// Look for rgb(num,num,num)
|
||||||
|
if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
|
||||||
|
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
|
||||||
|
|
||||||
|
// Look for rgba(num,num,num,num)
|
||||||
|
if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
||||||
|
return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
|
||||||
|
|
||||||
|
// Look for rgb(num%,num%,num%)
|
||||||
|
if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
|
||||||
|
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
|
||||||
|
|
||||||
|
// Look for rgba(num%,num%,num%,num)
|
||||||
|
if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
|
||||||
|
return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
|
||||||
|
|
||||||
|
// Look for #a0b1c2
|
||||||
|
if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
|
||||||
|
return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
|
||||||
|
|
||||||
|
// Look for #fff
|
||||||
|
if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
|
||||||
|
return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
|
||||||
|
|
||||||
|
// Otherwise, we're most likely dealing with a named color
|
||||||
|
var name = $.trim(str).toLowerCase();
|
||||||
|
if (name == "transparent")
|
||||||
|
return m(255, 255, 255, 0);
|
||||||
|
else {
|
||||||
|
// default to black
|
||||||
|
res = lookupColors[name] || [0, 0, 0];
|
||||||
|
return m(res[0], res[1], res[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var lookupColors = {
|
||||||
|
aqua:[0,255,255],
|
||||||
|
azure:[240,255,255],
|
||||||
|
beige:[245,245,220],
|
||||||
|
black:[0,0,0],
|
||||||
|
blue:[0,0,255],
|
||||||
|
brown:[165,42,42],
|
||||||
|
cyan:[0,255,255],
|
||||||
|
darkblue:[0,0,139],
|
||||||
|
darkcyan:[0,139,139],
|
||||||
|
darkgrey:[169,169,169],
|
||||||
|
darkgreen:[0,100,0],
|
||||||
|
darkkhaki:[189,183,107],
|
||||||
|
darkmagenta:[139,0,139],
|
||||||
|
darkolivegreen:[85,107,47],
|
||||||
|
darkorange:[255,140,0],
|
||||||
|
darkorchid:[153,50,204],
|
||||||
|
darkred:[139,0,0],
|
||||||
|
darksalmon:[233,150,122],
|
||||||
|
darkviolet:[148,0,211],
|
||||||
|
fuchsia:[255,0,255],
|
||||||
|
gold:[255,215,0],
|
||||||
|
green:[0,128,0],
|
||||||
|
indigo:[75,0,130],
|
||||||
|
khaki:[240,230,140],
|
||||||
|
lightblue:[173,216,230],
|
||||||
|
lightcyan:[224,255,255],
|
||||||
|
lightgreen:[144,238,144],
|
||||||
|
lightgrey:[211,211,211],
|
||||||
|
lightpink:[255,182,193],
|
||||||
|
lightyellow:[255,255,224],
|
||||||
|
lime:[0,255,0],
|
||||||
|
magenta:[255,0,255],
|
||||||
|
maroon:[128,0,0],
|
||||||
|
navy:[0,0,128],
|
||||||
|
olive:[128,128,0],
|
||||||
|
orange:[255,165,0],
|
||||||
|
pink:[255,192,203],
|
||||||
|
purple:[128,0,128],
|
||||||
|
violet:[128,0,128],
|
||||||
|
red:[255,0,0],
|
||||||
|
silver:[192,192,192],
|
||||||
|
white:[255,255,255],
|
||||||
|
yellow:[255,255,0]
|
||||||
|
};
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,31 @@
|
||||||
/*
|
/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
|
||||||
Flot plugin for showing crosshairs, thin lines, when the mouse hovers
|
|
||||||
over the plot.
|
|
||||||
|
|
||||||
crosshair: {
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
mode: null or "x" or "y" or "xy"
|
Licensed under the MIT license.
|
||||||
color: color
|
|
||||||
lineWidth: number
|
|
||||||
}
|
|
||||||
|
|
||||||
Set the mode to one of "x", "y" or "xy". The "x" mode enables a
|
The plugin supports these options:
|
||||||
vertical crosshair that lets you trace the values on the x axis, "y"
|
|
||||||
enables a horizontal crosshair and "xy" enables them both. "color" is
|
crosshair: {
|
||||||
the color of the crosshair (default is "rgba(170, 0, 0, 0.80)"),
|
mode: null or "x" or "y" or "xy"
|
||||||
"lineWidth" is the width of the drawn lines (default is 1).
|
color: color
|
||||||
|
lineWidth: number
|
||||||
|
}
|
||||||
|
|
||||||
|
Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
|
||||||
|
crosshair that lets you trace the values on the x axis, "y" enables a
|
||||||
|
horizontal crosshair and "xy" enables them both. "color" is the color of the
|
||||||
|
crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
|
||||||
|
the drawn lines (default is 1).
|
||||||
|
|
||||||
The plugin also adds four public methods:
|
The plugin also adds four public methods:
|
||||||
|
|
||||||
- setCrosshair(pos)
|
- setCrosshair( pos )
|
||||||
|
|
||||||
Set the position of the crosshair. Note that this is cleared if
|
Set the position of the crosshair. Note that this is cleared if the user
|
||||||
the user moves the mouse. "pos" is in coordinates of the plot and
|
moves the mouse. "pos" is in coordinates of the plot and should be on the
|
||||||
should be on the form { x: xpos, y: ypos } (you can use x2/x3/...
|
form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
|
||||||
if you're using multiple axes), which is coincidentally the same
|
axes), which is coincidentally the same format as what you get from a
|
||||||
format as what you get from a "plothover" event. If "pos" is null,
|
"plothover" event. If "pos" is null, the crosshair is cleared.
|
||||||
the crosshair is cleared.
|
|
||||||
|
|
||||||
- clearCrosshair()
|
- clearCrosshair()
|
||||||
|
|
||||||
|
|
@ -31,22 +33,25 @@ The plugin also adds four public methods:
|
||||||
|
|
||||||
- lockCrosshair(pos)
|
- lockCrosshair(pos)
|
||||||
|
|
||||||
Cause the crosshair to lock to the current location, no longer
|
Cause the crosshair to lock to the current location, no longer updating if
|
||||||
updating if the user moves the mouse. Optionally supply a position
|
the user moves the mouse. Optionally supply a position (passed on to
|
||||||
(passed on to setCrosshair()) to move it to.
|
setCrosshair()) to move it to.
|
||||||
|
|
||||||
Example usage:
|
Example usage:
|
||||||
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
|
|
||||||
$("#graph").bind("plothover", function (evt, position, item) {
|
var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
|
||||||
if (item) {
|
$("#graph").bind( "plothover", function ( evt, position, item ) {
|
||||||
// Lock the crosshair to the data point being hovered
|
if ( item ) {
|
||||||
myFlot.lockCrosshair({ x: item.datapoint[0], y: item.datapoint[1] });
|
// Lock the crosshair to the data point being hovered
|
||||||
}
|
myFlot.lockCrosshair({
|
||||||
else {
|
x: item.datapoint[ 0 ],
|
||||||
// Return normal crosshair operation
|
y: item.datapoint[ 1 ]
|
||||||
myFlot.unlockCrosshair();
|
});
|
||||||
}
|
} else {
|
||||||
});
|
// Return normal crosshair operation
|
||||||
|
myFlot.unlockCrosshair();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
- unlockCrosshair()
|
- unlockCrosshair()
|
||||||
|
|
||||||
|
|
@ -54,114 +59,118 @@ The plugin also adds four public methods:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = {
|
var options = {
|
||||||
crosshair: {
|
crosshair: {
|
||||||
mode: null, // one of null, "x", "y" or "xy",
|
mode: null, // one of null, "x", "y" or "xy",
|
||||||
color: "rgba(170, 0, 0, 0.80)",
|
color: "rgba(170, 0, 0, 0.80)",
|
||||||
lineWidth: 1
|
lineWidth: 1
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
// position of crosshair in pixels
|
|
||||||
var crosshair = { x: -1, y: -1, locked: false };
|
|
||||||
|
|
||||||
plot.setCrosshair = function setCrosshair(pos) {
|
|
||||||
if (!pos)
|
|
||||||
crosshair.x = -1;
|
|
||||||
else {
|
|
||||||
var o = plot.p2c(pos);
|
|
||||||
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
|
|
||||||
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
};
|
|
||||||
|
|
||||||
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
|
|
||||||
|
|
||||||
plot.lockCrosshair = function lockCrosshair(pos) {
|
|
||||||
if (pos)
|
|
||||||
plot.setCrosshair(pos);
|
|
||||||
crosshair.locked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.unlockCrosshair = function unlockCrosshair() {
|
|
||||||
crosshair.locked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseOut(e) {
|
|
||||||
if (crosshair.locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (crosshair.x != -1) {
|
|
||||||
crosshair.x = -1;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseMove(e) {
|
|
||||||
if (crosshair.locked)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (plot.getSelection && plot.getSelection()) {
|
|
||||||
crosshair.x = -1; // hide the crosshair while selecting
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = plot.offset();
|
|
||||||
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
|
|
||||||
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(function (plot, eventHolder) {
|
|
||||||
if (!plot.getOptions().crosshair.mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
eventHolder.mouseout(onMouseOut);
|
|
||||||
eventHolder.mousemove(onMouseMove);
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
|
||||||
var c = plot.getOptions().crosshair;
|
|
||||||
if (!c.mode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(plotOffset.left, plotOffset.top);
|
|
||||||
|
|
||||||
if (crosshair.x != -1) {
|
|
||||||
ctx.strokeStyle = c.color;
|
|
||||||
ctx.lineWidth = c.lineWidth;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
|
|
||||||
ctx.beginPath();
|
|
||||||
if (c.mode.indexOf("x") != -1) {
|
|
||||||
ctx.moveTo(crosshair.x, 0);
|
|
||||||
ctx.lineTo(crosshair.x, plot.height());
|
|
||||||
}
|
|
||||||
if (c.mode.indexOf("y") != -1) {
|
|
||||||
ctx.moveTo(0, crosshair.y);
|
|
||||||
ctx.lineTo(plot.width(), crosshair.y);
|
|
||||||
}
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
ctx.restore();
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
|
||||||
eventHolder.unbind("mouseout", onMouseOut);
|
|
||||||
eventHolder.unbind("mousemove", onMouseMove);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
function init(plot) {
|
||||||
options: options,
|
// position of crosshair in pixels
|
||||||
name: 'crosshair',
|
var crosshair = { x: -1, y: -1, locked: false };
|
||||||
version: '1.0'
|
|
||||||
|
plot.setCrosshair = function setCrosshair(pos) {
|
||||||
|
if (!pos)
|
||||||
|
crosshair.x = -1;
|
||||||
|
else {
|
||||||
|
var o = plot.p2c(pos);
|
||||||
|
crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
|
||||||
|
crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
};
|
||||||
|
|
||||||
|
plot.clearCrosshair = plot.setCrosshair; // passes null for pos
|
||||||
|
|
||||||
|
plot.lockCrosshair = function lockCrosshair(pos) {
|
||||||
|
if (pos)
|
||||||
|
plot.setCrosshair(pos);
|
||||||
|
crosshair.locked = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
plot.unlockCrosshair = function unlockCrosshair() {
|
||||||
|
crosshair.locked = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
function onMouseOut(e) {
|
||||||
|
if (crosshair.locked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (crosshair.x != -1) {
|
||||||
|
crosshair.x = -1;
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseMove(e) {
|
||||||
|
if (crosshair.locked)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (plot.getSelection && plot.getSelection()) {
|
||||||
|
crosshair.x = -1; // hide the crosshair while selecting
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = plot.offset();
|
||||||
|
crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
|
||||||
|
crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.bindEvents.push(function (plot, eventHolder) {
|
||||||
|
if (!plot.getOptions().crosshair.mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
eventHolder.mouseout(onMouseOut);
|
||||||
|
eventHolder.mousemove(onMouseMove);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
||||||
|
var c = plot.getOptions().crosshair;
|
||||||
|
if (!c.mode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var plotOffset = plot.getPlotOffset();
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(plotOffset.left, plotOffset.top);
|
||||||
|
|
||||||
|
if (crosshair.x != -1) {
|
||||||
|
var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
|
||||||
|
|
||||||
|
ctx.strokeStyle = c.color;
|
||||||
|
ctx.lineWidth = c.lineWidth;
|
||||||
|
ctx.lineJoin = "round";
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
if (c.mode.indexOf("x") != -1) {
|
||||||
|
var drawX = Math.floor(crosshair.x) + adj;
|
||||||
|
ctx.moveTo(drawX, 0);
|
||||||
|
ctx.lineTo(drawX, plot.height());
|
||||||
|
}
|
||||||
|
if (c.mode.indexOf("y") != -1) {
|
||||||
|
var drawY = Math.floor(crosshair.y) + adj;
|
||||||
|
ctx.moveTo(0, drawY);
|
||||||
|
ctx.lineTo(plot.width(), drawY);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
});
|
||||||
|
|
||||||
|
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
||||||
|
eventHolder.unbind("mouseout", onMouseOut);
|
||||||
|
eventHolder.unbind("mousemove", onMouseMove);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'crosshair',
|
||||||
|
version: '1.0'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,183 +1,226 @@
|
||||||
/*
|
/* Flot plugin for computing bottoms for filled line and bar charts.
|
||||||
Flot plugin for computing bottoms for filled line and bar charts.
|
|
||||||
|
|
||||||
The case: you've got two series that you want to fill the area
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
between. In Flot terms, you need to use one as the fill bottom of the
|
Licensed under the MIT license.
|
||||||
other. You can specify the bottom of each data point as the third
|
|
||||||
coordinate manually, or you can use this plugin to compute it for you.
|
|
||||||
|
|
||||||
In order to name the other series, you need to give it an id, like this
|
The case: you've got two series that you want to fill the area between. In Flot
|
||||||
|
terms, you need to use one as the fill bottom of the other. You can specify the
|
||||||
|
bottom of each data point as the third coordinate manually, or you can use this
|
||||||
|
plugin to compute it for you.
|
||||||
|
|
||||||
var dataset = [
|
In order to name the other series, you need to give it an id, like this:
|
||||||
{ data: [ ... ], id: "foo" } , // use default bottom
|
|
||||||
{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
|
|
||||||
];
|
|
||||||
|
|
||||||
$.plot($("#placeholder"), dataset, { line: { show: true, fill: true }});
|
var dataset = [
|
||||||
|
{ data: [ ... ], id: "foo" } , // use default bottom
|
||||||
|
{ data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
|
||||||
|
];
|
||||||
|
|
||||||
|
$.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
|
||||||
|
|
||||||
|
As a convenience, if the id given is a number that doesn't appear as an id in
|
||||||
|
the series, it is interpreted as the index in the array instead (so fillBetween:
|
||||||
|
0 can also mean the first series).
|
||||||
|
|
||||||
|
Internally, the plugin modifies the datapoints in each series. For line series,
|
||||||
|
extra data points might be inserted through interpolation. Note that at points
|
||||||
|
where the bottom line is not defined (due to a null point or start/end of line),
|
||||||
|
the current line will show a gap too. The algorithm comes from the
|
||||||
|
jquery.flot.stack.js plugin, possibly some code could be shared.
|
||||||
|
|
||||||
As a convenience, if the id given is a number that doesn't appear as
|
|
||||||
an id in the series, it is interpreted as the index in the array
|
|
||||||
instead (so fillBetween: 0 can also mean the first series).
|
|
||||||
|
|
||||||
Internally, the plugin modifies the datapoints in each series. For
|
|
||||||
line series, extra data points might be inserted through
|
|
||||||
interpolation. Note that at points where the bottom line is not
|
|
||||||
defined (due to a null point or start/end of line), the current line
|
|
||||||
will show a gap too. The algorithm comes from the jquery.flot.stack.js
|
|
||||||
plugin, possibly some code could be shared.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ( $ ) {
|
||||||
var options = {
|
|
||||||
series: { fillBetween: null } // or number
|
|
||||||
};
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function findBottomSeries(s, allseries) {
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < allseries.length; ++i) {
|
|
||||||
if (allseries[i].id == s.fillBetween)
|
|
||||||
return allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof s.fillBetween == "number") {
|
var options = {
|
||||||
i = s.fillBetween;
|
series: {
|
||||||
|
fillBetween: null // or number
|
||||||
if (i < 0 || i >= allseries.length)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function computeFillBottoms(plot, s, datapoints) {
|
|
||||||
if (s.fillBetween == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var other = findBottomSeries(s, plot.getData());
|
|
||||||
if (!other)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ps = datapoints.pointsize,
|
|
||||||
points = datapoints.points,
|
|
||||||
otherps = other.datapoints.pointsize,
|
|
||||||
otherpoints = other.datapoints.points,
|
|
||||||
newpoints = [],
|
|
||||||
px, py, intery, qx, qy, bottom,
|
|
||||||
withlines = s.lines.show,
|
|
||||||
withbottom = ps > 2 && datapoints.format[2].y,
|
|
||||||
withsteps = withlines && s.lines.steps,
|
|
||||||
fromgap = true,
|
|
||||||
i = 0, j = 0, l;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (i >= points.length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
l = newpoints.length;
|
|
||||||
|
|
||||||
if (points[i] == null) {
|
|
||||||
// copy gaps
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (j >= otherpoints.length) {
|
|
||||||
// for lines, we can't use the rest of the points
|
|
||||||
if (!withlines) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
}
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (otherpoints[j] == null) {
|
|
||||||
// oops, got a gap
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(null);
|
|
||||||
fromgap = true;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// cases where we actually got two points
|
|
||||||
px = points[i];
|
|
||||||
py = points[i + 1];
|
|
||||||
qx = otherpoints[j];
|
|
||||||
qy = otherpoints[j + 1];
|
|
||||||
bottom = 0;
|
|
||||||
|
|
||||||
if (px == qx) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
//newpoints[l + 1] += qy;
|
|
||||||
bottom = qy;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else if (px > qx) {
|
|
||||||
// we got past point below, might need to
|
|
||||||
// insert interpolated extra point
|
|
||||||
if (withlines && i > 0 && points[i - ps] != null) {
|
|
||||||
intery = py + (points[i - ps + 1] - py) * (qx - px) / (points[i - ps] - px);
|
|
||||||
newpoints.push(qx);
|
|
||||||
newpoints.push(intery)
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
bottom = qy;
|
|
||||||
}
|
|
||||||
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else { // px < qx
|
|
||||||
if (fromgap && withlines) {
|
|
||||||
// if we come from a gap, we just skip this point
|
|
||||||
i += ps;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
// we might be able to interpolate a point below,
|
|
||||||
// this can give us a better y
|
|
||||||
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
|
||||||
bottom = qy + (otherpoints[j - otherps + 1] - qy) * (px - qx) / (otherpoints[j - otherps] - qx);
|
|
||||||
|
|
||||||
//newpoints[l + 1] += bottom;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromgap = false;
|
|
||||||
|
|
||||||
if (l != newpoints.length && withbottom)
|
|
||||||
newpoints[l + 2] = bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maintain the line steps invariant
|
|
||||||
if (withsteps && l != newpoints.length && l > 0
|
|
||||||
&& newpoints[l] != null
|
|
||||||
&& newpoints[l] != newpoints[l - ps]
|
|
||||||
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints[l + ps + m] = newpoints[l + m];
|
|
||||||
newpoints[l + 1] = newpoints[l - ps + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(computeFillBottoms);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
function init( plot ) {
|
||||||
options: options,
|
|
||||||
name: 'fillbetween',
|
function findBottomSeries( s, allseries ) {
|
||||||
version: '1.0'
|
|
||||||
});
|
var i;
|
||||||
|
|
||||||
|
for ( i = 0; i < allseries.length; ++i ) {
|
||||||
|
if ( allseries[ i ].id === s.fillBetween ) {
|
||||||
|
return allseries[ i ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( typeof s.fillBetween === "number" ) {
|
||||||
|
if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return allseries[ s.fillBetween ];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeFillBottoms( plot, s, datapoints ) {
|
||||||
|
|
||||||
|
if ( s.fillBetween == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var other = findBottomSeries( s, plot.getData() );
|
||||||
|
|
||||||
|
if ( !other ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ps = datapoints.pointsize,
|
||||||
|
points = datapoints.points,
|
||||||
|
otherps = other.datapoints.pointsize,
|
||||||
|
otherpoints = other.datapoints.points,
|
||||||
|
newpoints = [],
|
||||||
|
px, py, intery, qx, qy, bottom,
|
||||||
|
withlines = s.lines.show,
|
||||||
|
withbottom = ps > 2 && datapoints.format[2].y,
|
||||||
|
withsteps = withlines && s.lines.steps,
|
||||||
|
fromgap = true,
|
||||||
|
i = 0,
|
||||||
|
j = 0,
|
||||||
|
l, m;
|
||||||
|
|
||||||
|
while ( true ) {
|
||||||
|
|
||||||
|
if ( i >= points.length ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = newpoints.length;
|
||||||
|
|
||||||
|
if ( points[ i ] == null ) {
|
||||||
|
|
||||||
|
// copy gaps
|
||||||
|
|
||||||
|
for ( m = 0; m < ps; ++m ) {
|
||||||
|
newpoints.push( points[ i + m ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
|
||||||
|
} else if ( j >= otherpoints.length ) {
|
||||||
|
|
||||||
|
// for lines, we can't use the rest of the points
|
||||||
|
|
||||||
|
if ( !withlines ) {
|
||||||
|
for ( m = 0; m < ps; ++m ) {
|
||||||
|
newpoints.push( points[ i + m ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
|
||||||
|
} else if ( otherpoints[ j ] == null ) {
|
||||||
|
|
||||||
|
// oops, got a gap
|
||||||
|
|
||||||
|
for ( m = 0; m < ps; ++m ) {
|
||||||
|
newpoints.push( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
fromgap = true;
|
||||||
|
j += otherps;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// cases where we actually got two points
|
||||||
|
|
||||||
|
px = points[ i ];
|
||||||
|
py = points[ i + 1 ];
|
||||||
|
qx = otherpoints[ j ];
|
||||||
|
qy = otherpoints[ j + 1 ];
|
||||||
|
bottom = 0;
|
||||||
|
|
||||||
|
if ( px === qx ) {
|
||||||
|
|
||||||
|
for ( m = 0; m < ps; ++m ) {
|
||||||
|
newpoints.push( points[ i + m ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
//newpoints[ l + 1 ] += qy;
|
||||||
|
bottom = qy;
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
j += otherps;
|
||||||
|
|
||||||
|
} else if ( px > qx ) {
|
||||||
|
|
||||||
|
// we got past point below, might need to
|
||||||
|
// insert interpolated extra point
|
||||||
|
|
||||||
|
if ( withlines && i > 0 && points[ i - ps ] != null ) {
|
||||||
|
intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
|
||||||
|
newpoints.push( qx );
|
||||||
|
newpoints.push( intery );
|
||||||
|
for ( m = 2; m < ps; ++m ) {
|
||||||
|
newpoints.push( points[ i + m ] );
|
||||||
|
}
|
||||||
|
bottom = qy;
|
||||||
|
}
|
||||||
|
|
||||||
|
j += otherps;
|
||||||
|
|
||||||
|
} else { // px < qx
|
||||||
|
|
||||||
|
// if we come from a gap, we just skip this point
|
||||||
|
|
||||||
|
if ( fromgap && withlines ) {
|
||||||
|
i += ps;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( m = 0; m < ps; ++m ) {
|
||||||
|
newpoints.push( points[ i + m ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// we might be able to interpolate a point below,
|
||||||
|
// this can give us a better y
|
||||||
|
|
||||||
|
if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
|
||||||
|
bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
|
||||||
|
}
|
||||||
|
|
||||||
|
//newpoints[l + 1] += bottom;
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromgap = false;
|
||||||
|
|
||||||
|
if ( l !== newpoints.length && withbottom ) {
|
||||||
|
newpoints[ l + 2 ] = bottom;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// maintain the line steps invariant
|
||||||
|
|
||||||
|
if ( withsteps && l !== newpoints.length && l > 0 &&
|
||||||
|
newpoints[ l ] !== null &&
|
||||||
|
newpoints[ l ] !== newpoints[ l - ps ] &&
|
||||||
|
newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
|
||||||
|
for (m = 0; m < ps; ++m) {
|
||||||
|
newpoints[ l + ps + m ] = newpoints[ l + m ];
|
||||||
|
}
|
||||||
|
newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datapoints.points = newpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.processDatapoints.push( computeFillBottoms );
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: "fillbetween",
|
||||||
|
version: "1.0"
|
||||||
|
});
|
||||||
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,238 +1,241 @@
|
||||||
/*
|
/* Flot plugin for plotting images.
|
||||||
Flot plugin for plotting images, e.g. useful for putting ticks on a
|
|
||||||
prerendered complex visualization.
|
|
||||||
|
|
||||||
The data syntax is [[image, x1, y1, x2, y2], ...] where (x1, y1) and
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
(x2, y2) are where you intend the two opposite corners of the image to
|
Licensed under the MIT license.
|
||||||
end up in the plot. Image must be a fully loaded Javascript image (you
|
|
||||||
can make one with new Image()). If the image is not complete, it's
|
|
||||||
skipped when plotting.
|
|
||||||
|
|
||||||
There are two helpers included for retrieving images. The easiest work
|
The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
|
||||||
the way that you put in URLs instead of images in the data (like
|
(x2, y2) are where you intend the two opposite corners of the image to end up
|
||||||
["myimage.png", 0, 0, 10, 10]), then call $.plot.image.loadData(data,
|
in the plot. Image must be a fully loaded Javascript image (you can make one
|
||||||
options, callback) where data and options are the same as you pass in
|
with new Image()). If the image is not complete, it's skipped when plotting.
|
||||||
to $.plot. This loads the images, replaces the URLs in the data with
|
|
||||||
the corresponding images and calls "callback" when all images are
|
|
||||||
loaded (or failed loading). In the callback, you can then call $.plot
|
|
||||||
with the data set. See the included example.
|
|
||||||
|
|
||||||
A more low-level helper, $.plot.image.load(urls, callback) is also
|
There are two helpers included for retrieving images. The easiest work the way
|
||||||
included. Given a list of URLs, it calls callback with an object
|
that you put in URLs instead of images in the data, like this:
|
||||||
mapping from URL to Image object when all images are loaded or have
|
|
||||||
failed loading.
|
|
||||||
|
|
||||||
Options for the plugin are
|
[ "myimage.png", 0, 0, 10, 10 ]
|
||||||
|
|
||||||
series: {
|
Then call $.plot.image.loadData( data, options, callback ) where data and
|
||||||
images: {
|
options are the same as you pass in to $.plot. This loads the images, replaces
|
||||||
show: boolean
|
the URLs in the data with the corresponding images and calls "callback" when
|
||||||
anchor: "corner" or "center"
|
all images are loaded (or failed loading). In the callback, you can then call
|
||||||
alpha: [0,1]
|
$.plot with the data set. See the included example.
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
which can be specified for a specific series
|
A more low-level helper, $.plot.image.load(urls, callback) is also included.
|
||||||
|
Given a list of URLs, it calls callback with an object mapping from URL to
|
||||||
|
Image object when all images are loaded or have failed loading.
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], images: { ... } ])
|
The plugin supports these options:
|
||||||
|
|
||||||
Note that because the data format is different from usual data points,
|
series: {
|
||||||
you can't use images with anything else in a specific data series.
|
images: {
|
||||||
|
show: boolean
|
||||||
|
anchor: "corner" or "center"
|
||||||
|
alpha: [ 0, 1 ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Setting "anchor" to "center" causes the pixels in the image to be
|
They can be specified for a specific series:
|
||||||
anchored at the corner pixel centers inside of at the pixel corners,
|
|
||||||
effectively letting half a pixel stick out to each side in the plot.
|
|
||||||
|
|
||||||
|
$.plot( $("#placeholder"), [{
|
||||||
|
data: [ ... ],
|
||||||
|
images: { ... }
|
||||||
|
])
|
||||||
|
|
||||||
A possible future direction could be support for tiling for large
|
Note that because the data format is different from usual data points, you
|
||||||
images (like Google Maps).
|
can't use images with anything else in a specific data series.
|
||||||
|
|
||||||
|
Setting "anchor" to "center" causes the pixels in the image to be anchored at
|
||||||
|
the corner pixel centers inside of at the pixel corners, effectively letting
|
||||||
|
half a pixel stick out to each side in the plot.
|
||||||
|
|
||||||
|
A possible future direction could be support for tiling for large images (like
|
||||||
|
Google Maps).
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = {
|
var options = {
|
||||||
series: {
|
series: {
|
||||||
images: {
|
images: {
|
||||||
show: false,
|
show: false,
|
||||||
alpha: 1,
|
alpha: 1,
|
||||||
anchor: "corner" // or "center"
|
anchor: "corner" // or "center"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.plot.image = {};
|
||||||
|
|
||||||
|
$.plot.image.loadDataImages = function (series, options, callback) {
|
||||||
|
var urls = [], points = [];
|
||||||
|
|
||||||
|
var defaultShow = options.series.images.show;
|
||||||
|
|
||||||
|
$.each(series, function (i, s) {
|
||||||
|
if (!(defaultShow || s.images.show))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (s.data)
|
||||||
|
s = s.data;
|
||||||
|
|
||||||
|
$.each(s, function (i, p) {
|
||||||
|
if (typeof p[0] == "string") {
|
||||||
|
urls.push(p[0]);
|
||||||
|
points.push(p);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
|
|
||||||
$.plot.image = {};
|
|
||||||
|
|
||||||
$.plot.image.loadDataImages = function (series, options, callback) {
|
|
||||||
var urls = [], points = [];
|
|
||||||
|
|
||||||
var defaultShow = options.series.images.show;
|
|
||||||
|
|
||||||
$.each(series, function (i, s) {
|
|
||||||
if (!(defaultShow || s.images.show))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (s.data)
|
|
||||||
s = s.data;
|
|
||||||
|
|
||||||
$.each(s, function (i, p) {
|
|
||||||
if (typeof p[0] == "string") {
|
|
||||||
urls.push(p[0]);
|
|
||||||
points.push(p);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$.plot.image.load(urls, function (loadedImages) {
|
|
||||||
$.each(points, function (i, p) {
|
|
||||||
var url = p[0];
|
|
||||||
if (loadedImages[url])
|
|
||||||
p[0] = loadedImages[url];
|
|
||||||
});
|
|
||||||
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.image.load = function (urls, callback) {
|
|
||||||
var missing = urls.length, loaded = {};
|
|
||||||
if (missing == 0)
|
|
||||||
callback({});
|
|
||||||
|
|
||||||
$.each(urls, function (i, url) {
|
|
||||||
var handler = function () {
|
|
||||||
--missing;
|
|
||||||
|
|
||||||
loaded[url] = this;
|
|
||||||
|
|
||||||
if (missing == 0)
|
|
||||||
callback(loaded);
|
|
||||||
};
|
|
||||||
|
|
||||||
$('<img />').load(handler).error(handler).attr('src', url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawSeries(plot, ctx, series) {
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
|
|
||||||
if (!series.images || !series.images.show)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var points = series.datapoints.points,
|
|
||||||
ps = series.datapoints.pointsize;
|
|
||||||
|
|
||||||
for (var i = 0; i < points.length; i += ps) {
|
|
||||||
var img = points[i],
|
|
||||||
x1 = points[i + 1], y1 = points[i + 2],
|
|
||||||
x2 = points[i + 3], y2 = points[i + 4],
|
|
||||||
xaxis = series.xaxis, yaxis = series.yaxis,
|
|
||||||
tmp;
|
|
||||||
|
|
||||||
// actually we should check img.complete, but it
|
|
||||||
// appears to be a somewhat unreliable indicator in
|
|
||||||
// IE6 (false even after load event)
|
|
||||||
if (!img || img.width <= 0 || img.height <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (x1 > x2) {
|
|
||||||
tmp = x2;
|
|
||||||
x2 = x1;
|
|
||||||
x1 = tmp;
|
|
||||||
}
|
|
||||||
if (y1 > y2) {
|
|
||||||
tmp = y2;
|
|
||||||
y2 = y1;
|
|
||||||
y1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the anchor is at the center of the pixel, expand the
|
|
||||||
// image by 1/2 pixel in each direction
|
|
||||||
if (series.images.anchor == "center") {
|
|
||||||
tmp = 0.5 * (x2-x1) / (img.width - 1);
|
|
||||||
x1 -= tmp;
|
|
||||||
x2 += tmp;
|
|
||||||
tmp = 0.5 * (y2-y1) / (img.height - 1);
|
|
||||||
y1 -= tmp;
|
|
||||||
y2 += tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clip
|
|
||||||
if (x1 == x2 || y1 == y2 ||
|
|
||||||
x1 >= xaxis.max || x2 <= xaxis.min ||
|
|
||||||
y1 >= yaxis.max || y2 <= yaxis.min)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
|
|
||||||
if (x1 < xaxis.min) {
|
|
||||||
sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
|
|
||||||
x1 = xaxis.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x2 > xaxis.max) {
|
|
||||||
sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
|
|
||||||
x2 = xaxis.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y1 < yaxis.min) {
|
|
||||||
sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
|
|
||||||
y1 = yaxis.min;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y2 > yaxis.max) {
|
|
||||||
sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
|
|
||||||
y2 = yaxis.max;
|
|
||||||
}
|
|
||||||
|
|
||||||
x1 = xaxis.p2c(x1);
|
|
||||||
x2 = xaxis.p2c(x2);
|
|
||||||
y1 = yaxis.p2c(y1);
|
|
||||||
y2 = yaxis.p2c(y2);
|
|
||||||
|
|
||||||
// the transformation may have swapped us
|
|
||||||
if (x1 > x2) {
|
|
||||||
tmp = x2;
|
|
||||||
x2 = x1;
|
|
||||||
x1 = tmp;
|
|
||||||
}
|
|
||||||
if (y1 > y2) {
|
|
||||||
tmp = y2;
|
|
||||||
y2 = y1;
|
|
||||||
y1 = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = ctx.globalAlpha;
|
|
||||||
ctx.globalAlpha *= series.images.alpha;
|
|
||||||
ctx.drawImage(img,
|
|
||||||
sx1, sy1, sx2 - sx1, sy2 - sy1,
|
|
||||||
x1 + plotOffset.left, y1 + plotOffset.top,
|
|
||||||
x2 - x1, y2 - y1);
|
|
||||||
ctx.globalAlpha = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function processRawData(plot, series, data, datapoints) {
|
|
||||||
if (!series.images.show)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// format is Image, x1, y1, x2, y2 (opposite corners)
|
|
||||||
datapoints.format = [
|
|
||||||
{ required: true },
|
|
||||||
{ x: true, number: true, required: true },
|
|
||||||
{ y: true, number: true, required: true },
|
|
||||||
{ x: true, number: true, required: true },
|
|
||||||
{ y: true, number: true, required: true }
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
plot.hooks.processRawData.push(processRawData);
|
|
||||||
plot.hooks.drawSeries.push(drawSeries);
|
|
||||||
}
|
|
||||||
|
|
||||||
$.plot.plugins.push({
|
|
||||||
init: init,
|
|
||||||
options: options,
|
|
||||||
name: 'image',
|
|
||||||
version: '1.1'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$.plot.image.load(urls, function (loadedImages) {
|
||||||
|
$.each(points, function (i, p) {
|
||||||
|
var url = p[0];
|
||||||
|
if (loadedImages[url])
|
||||||
|
p[0] = loadedImages[url];
|
||||||
|
});
|
||||||
|
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.image.load = function (urls, callback) {
|
||||||
|
var missing = urls.length, loaded = {};
|
||||||
|
if (missing == 0)
|
||||||
|
callback({});
|
||||||
|
|
||||||
|
$.each(urls, function (i, url) {
|
||||||
|
var handler = function () {
|
||||||
|
--missing;
|
||||||
|
|
||||||
|
loaded[url] = this;
|
||||||
|
|
||||||
|
if (missing == 0)
|
||||||
|
callback(loaded);
|
||||||
|
};
|
||||||
|
|
||||||
|
$('<img />').load(handler).error(handler).attr('src', url);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function drawSeries(plot, ctx, series) {
|
||||||
|
var plotOffset = plot.getPlotOffset();
|
||||||
|
|
||||||
|
if (!series.images || !series.images.show)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var points = series.datapoints.points,
|
||||||
|
ps = series.datapoints.pointsize;
|
||||||
|
|
||||||
|
for (var i = 0; i < points.length; i += ps) {
|
||||||
|
var img = points[i],
|
||||||
|
x1 = points[i + 1], y1 = points[i + 2],
|
||||||
|
x2 = points[i + 3], y2 = points[i + 4],
|
||||||
|
xaxis = series.xaxis, yaxis = series.yaxis,
|
||||||
|
tmp;
|
||||||
|
|
||||||
|
// actually we should check img.complete, but it
|
||||||
|
// appears to be a somewhat unreliable indicator in
|
||||||
|
// IE6 (false even after load event)
|
||||||
|
if (!img || img.width <= 0 || img.height <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (x1 > x2) {
|
||||||
|
tmp = x2;
|
||||||
|
x2 = x1;
|
||||||
|
x1 = tmp;
|
||||||
|
}
|
||||||
|
if (y1 > y2) {
|
||||||
|
tmp = y2;
|
||||||
|
y2 = y1;
|
||||||
|
y1 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the anchor is at the center of the pixel, expand the
|
||||||
|
// image by 1/2 pixel in each direction
|
||||||
|
if (series.images.anchor == "center") {
|
||||||
|
tmp = 0.5 * (x2-x1) / (img.width - 1);
|
||||||
|
x1 -= tmp;
|
||||||
|
x2 += tmp;
|
||||||
|
tmp = 0.5 * (y2-y1) / (img.height - 1);
|
||||||
|
y1 -= tmp;
|
||||||
|
y2 += tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clip
|
||||||
|
if (x1 == x2 || y1 == y2 ||
|
||||||
|
x1 >= xaxis.max || x2 <= xaxis.min ||
|
||||||
|
y1 >= yaxis.max || y2 <= yaxis.min)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
|
||||||
|
if (x1 < xaxis.min) {
|
||||||
|
sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
|
||||||
|
x1 = xaxis.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x2 > xaxis.max) {
|
||||||
|
sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
|
||||||
|
x2 = xaxis.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y1 < yaxis.min) {
|
||||||
|
sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
|
||||||
|
y1 = yaxis.min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y2 > yaxis.max) {
|
||||||
|
sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
|
||||||
|
y2 = yaxis.max;
|
||||||
|
}
|
||||||
|
|
||||||
|
x1 = xaxis.p2c(x1);
|
||||||
|
x2 = xaxis.p2c(x2);
|
||||||
|
y1 = yaxis.p2c(y1);
|
||||||
|
y2 = yaxis.p2c(y2);
|
||||||
|
|
||||||
|
// the transformation may have swapped us
|
||||||
|
if (x1 > x2) {
|
||||||
|
tmp = x2;
|
||||||
|
x2 = x1;
|
||||||
|
x1 = tmp;
|
||||||
|
}
|
||||||
|
if (y1 > y2) {
|
||||||
|
tmp = y2;
|
||||||
|
y2 = y1;
|
||||||
|
y1 = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = ctx.globalAlpha;
|
||||||
|
ctx.globalAlpha *= series.images.alpha;
|
||||||
|
ctx.drawImage(img,
|
||||||
|
sx1, sy1, sx2 - sx1, sy2 - sy1,
|
||||||
|
x1 + plotOffset.left, y1 + plotOffset.top,
|
||||||
|
x2 - x1, y2 - y1);
|
||||||
|
ctx.globalAlpha = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function processRawData(plot, series, data, datapoints) {
|
||||||
|
if (!series.images.show)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// format is Image, x1, y1, x2, y2 (opposite corners)
|
||||||
|
datapoints.format = [
|
||||||
|
{ required: true },
|
||||||
|
{ x: true, number: true, required: true },
|
||||||
|
{ y: true, number: true, required: true },
|
||||||
|
{ x: true, number: true, required: true },
|
||||||
|
{ y: true, number: true, required: true }
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(plot) {
|
||||||
|
plot.hooks.processRawData.push(processRawData);
|
||||||
|
plot.hooks.drawSeries.push(drawSeries);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'image',
|
||||||
|
version: '1.1'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,336 +1,346 @@
|
||||||
/*
|
/* Flot plugin for adding the ability to pan and zoom the plot.
|
||||||
Flot plugin for adding panning and zooming capabilities to a plot.
|
|
||||||
|
|
||||||
The default behaviour is double click and scrollwheel up/down to zoom
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
in, drag to pan. The plugin defines plot.zoom({ center }),
|
Licensed under the MIT license.
|
||||||
plot.zoomOut() and plot.pan(offset) so you easily can add custom
|
|
||||||
controls. It also fires a "plotpan" and "plotzoom" event when
|
|
||||||
something happens, useful for synchronizing plots.
|
|
||||||
|
|
||||||
Options:
|
The default behaviour is double click and scrollwheel up/down to zoom in, drag
|
||||||
|
to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
|
||||||
|
plot.pan( offset ) so you easily can add custom controls. It also fires
|
||||||
|
"plotpan" and "plotzoom" events, useful for synchronizing plots.
|
||||||
|
|
||||||
zoom: {
|
The plugin supports these options:
|
||||||
interactive: false
|
|
||||||
trigger: "dblclick" // or "click" for single click
|
zoom: {
|
||||||
amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
interactive: false
|
||||||
}
|
trigger: "dblclick" // or "click" for single click
|
||||||
|
amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
||||||
pan: {
|
}
|
||||||
interactive: false
|
|
||||||
cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
|
pan: {
|
||||||
frameRate: 20
|
interactive: false
|
||||||
}
|
cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
|
||||||
|
frameRate: 20
|
||||||
|
}
|
||||||
|
|
||||||
|
xaxis, yaxis, x2axis, y2axis: {
|
||||||
|
zoomRange: null // or [ number, number ] (min range, max range) or false
|
||||||
|
panRange: null // or [ number, number ] (min, max) or false
|
||||||
|
}
|
||||||
|
|
||||||
xaxis, yaxis, x2axis, y2axis: {
|
|
||||||
zoomRange: null // or [number, number] (min range, max range) or false
|
|
||||||
panRange: null // or [number, number] (min, max) or false
|
|
||||||
}
|
|
||||||
|
|
||||||
"interactive" enables the built-in drag/click behaviour. If you enable
|
"interactive" enables the built-in drag/click behaviour. If you enable
|
||||||
interactive for pan, then you'll have a basic plot that supports
|
interactive for pan, then you'll have a basic plot that supports moving
|
||||||
moving around; the same for zoom.
|
around; the same for zoom.
|
||||||
|
|
||||||
"amount" specifies the default amount to zoom in (so 1.5 = 150%)
|
"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
|
||||||
relative to the current viewport.
|
the current viewport.
|
||||||
|
|
||||||
"cursor" is a standard CSS mouse cursor string used for visual
|
"cursor" is a standard CSS mouse cursor string used for visual feedback to the
|
||||||
feedback to the user when dragging.
|
user when dragging.
|
||||||
|
|
||||||
"frameRate" specifies the maximum number of times per second the plot
|
"frameRate" specifies the maximum number of times per second the plot will
|
||||||
will update itself while the user is panning around on it (set to null
|
update itself while the user is panning around on it (set to null to disable
|
||||||
to disable intermediate pans, the plot will then not update until the
|
intermediate pans, the plot will then not update until the mouse button is
|
||||||
mouse button is released).
|
released).
|
||||||
|
|
||||||
"zoomRange" is the interval in which zooming can happen, e.g. with
|
"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
|
||||||
zoomRange: [1, 100] the zoom will never scale the axis so that the
|
[1, 100] the zoom will never scale the axis so that the difference between min
|
||||||
difference between min and max is smaller than 1 or larger than 100.
|
and max is smaller than 1 or larger than 100. You can set either end to null
|
||||||
You can set either end to null to ignore, e.g. [1, null]. If you set
|
to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
|
||||||
zoomRange to false, zooming on that axis will be disabled.
|
will be disabled.
|
||||||
|
|
||||||
"panRange" confines the panning to stay within a range, e.g. with
|
"panRange" confines the panning to stay within a range, e.g. with panRange:
|
||||||
panRange: [-10, 20] panning stops at -10 in one end and at 20 in the
|
[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
|
||||||
other. Either can be null, e.g. [-10, null]. If you set
|
be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
|
||||||
panRange to false, panning on that axis will be disabled.
|
will be disabled.
|
||||||
|
|
||||||
Example API usage:
|
Example API usage:
|
||||||
|
|
||||||
plot = $.plot(...);
|
plot = $.plot(...);
|
||||||
|
|
||||||
// zoom default amount in on the pixel (10, 20)
|
|
||||||
plot.zoom({ center: { left: 10, top: 20 } });
|
|
||||||
|
|
||||||
// zoom out again
|
// zoom default amount in on the pixel ( 10, 20 )
|
||||||
plot.zoomOut({ center: { left: 10, top: 20 } });
|
plot.zoom({ center: { left: 10, top: 20 } });
|
||||||
|
|
||||||
// zoom 200% in on the pixel (10, 20)
|
// zoom out again
|
||||||
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
|
plot.zoomOut({ center: { left: 10, top: 20 } });
|
||||||
|
|
||||||
// pan 100 pixels to the left and 20 down
|
|
||||||
plot.pan({ left: -100, top: 20 })
|
|
||||||
|
|
||||||
Here, "center" specifies where the center of the zooming should
|
// zoom 200% in on the pixel (10, 20)
|
||||||
happen. Note that this is defined in pixel space, not the space of the
|
plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
|
||||||
data points (you can use the p2c helpers on the axes in Flot to help
|
|
||||||
you convert between these).
|
// pan 100 pixels to the left and 20 down
|
||||||
|
plot.pan({ left: -100, top: 20 })
|
||||||
|
|
||||||
|
Here, "center" specifies where the center of the zooming should happen. Note
|
||||||
|
that this is defined in pixel space, not the space of the data points (you can
|
||||||
|
use the p2c helpers on the axes in Flot to help you convert between these).
|
||||||
|
|
||||||
|
"amount" is the amount to zoom the viewport relative to the current range, so
|
||||||
|
1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
|
||||||
|
can set the default in the options.
|
||||||
|
|
||||||
"amount" is the amount to zoom the viewport relative to the current
|
|
||||||
range, so 1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is
|
|
||||||
70% (zoom out). You can set the default in the options.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
// First two dependencies, jquery.event.drag.js and
|
// First two dependencies, jquery.event.drag.js and
|
||||||
// jquery.mousewheel.js, we put them inline here to save people the
|
// jquery.mousewheel.js, we put them inline here to save people the
|
||||||
// effort of downloading them.
|
// effort of downloading them.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
|
jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
|
||||||
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
|
Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
|
||||||
*/
|
*/
|
||||||
(function(E){E.fn.drag=function(L,K,J){if(K){this.bind("dragstart",L)}if(J){this.bind("dragend",J)}return !L?this.trigger("drag"):this.bind("drag",K?K:L)};var A=E.event,B=A.special,F=B.drag={not:":input",distance:0,which:1,dragging:false,setup:function(J){J=E.extend({distance:F.distance,which:F.which,not:F.not},J||{});J.distance=I(J.distance);A.add(this,"mousedown",H,J);if(this.attachEvent){this.attachEvent("ondragstart",D)}},teardown:function(){A.remove(this,"mousedown",H);if(this===F.dragging){F.dragging=F.proxy=false}G(this,true);if(this.detachEvent){this.detachEvent("ondragstart",D)}}};B.dragstart=B.dragend={setup:function(){},teardown:function(){}};function H(L){var K=this,J,M=L.data||{};if(M.elem){K=L.dragTarget=M.elem;L.dragProxy=F.proxy||K;L.cursorOffsetX=M.pageX-M.left;L.cursorOffsetY=M.pageY-M.top;L.offsetX=L.pageX-L.cursorOffsetX;L.offsetY=L.pageY-L.cursorOffsetY}else{if(F.dragging||(M.which>0&&L.which!=M.which)||E(L.target).is(M.not)){return }}switch(L.type){case"mousedown":E.extend(M,E(K).offset(),{elem:K,target:L.target,pageX:L.pageX,pageY:L.pageY});A.add(document,"mousemove mouseup",H,M);G(K,false);F.dragging=null;return false;case !F.dragging&&"mousemove":if(I(L.pageX-M.pageX)+I(L.pageY-M.pageY)<M.distance){break}L.target=M.target;J=C(L,"dragstart",K);if(J!==false){F.dragging=K;F.proxy=L.dragProxy=E(J||K)[0]}case"mousemove":if(F.dragging){J=C(L,"drag",K);if(B.drop){B.drop.allowed=(J!==false);B.drop.handler(L)}if(J!==false){break}L.type="mouseup"}case"mouseup":A.remove(document,"mousemove mouseup",H);if(F.dragging){if(B.drop){B.drop.handler(L)}C(L,"dragend",K)}G(K,true);F.dragging=F.proxy=M.elem=false;break}return true}function C(M,K,L){M.type=K;var J=E.event.handle.call(L,M);return J===false?false:J||M.result}function I(J){return Math.pow(J,2)}function D(){return(F.dragging===false)}function G(K,J){if(!K){return }K.unselectable=J?"off":"on";K.onselectstart=function(){return J};if(K.style){K.style.MozUserSelect=J?"":"none"}}})(jQuery);
|
(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);
|
||||||
|
|
||||||
|
|
||||||
/* jquery.mousewheel.min.js
|
/* jquery.mousewheel.min.js
|
||||||
* Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
|
* Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
* Licensed under the MIT License (LICENSE.txt).
|
||||||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
|
||||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||||
|
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||||
|
*
|
||||||
|
* Version: 3.0.6
|
||||||
*
|
*
|
||||||
* Version: 3.0.2
|
|
||||||
*
|
|
||||||
* Requires: 1.2.2+
|
* Requires: 1.2.2+
|
||||||
*/
|
*/
|
||||||
(function(c){var a=["DOMMouseScroll","mousewheel"];c.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var d=a.length;d;){this.addEventListener(a[--d],b,false)}}else{this.onmousewheel=b}},teardown:function(){if(this.removeEventListener){for(var d=a.length;d;){this.removeEventListener(a[--d],b,false)}}else{this.onmousewheel=null}}};c.fn.extend({mousewheel:function(d){return d?this.bind("mousewheel",d):this.trigger("mousewheel")},unmousewheel:function(d){return this.unbind("mousewheel",d)}});function b(f){var d=[].slice.call(arguments,1),g=0,e=true;f=c.event.fix(f||window.event);f.type="mousewheel";if(f.wheelDelta){g=f.wheelDelta/120}if(f.detail){g=-f.detail/3}d.unshift(f,g);return c.event.handle.apply(this,d)}})(jQuery);
|
(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = {
|
var options = {
|
||||||
xaxis: {
|
xaxis: {
|
||||||
zoomRange: null, // or [number, number] (min range, max range)
|
zoomRange: null, // or [number, number] (min range, max range)
|
||||||
panRange: null // or [number, number] (min, max)
|
panRange: null // or [number, number] (min, max)
|
||||||
},
|
},
|
||||||
zoom: {
|
zoom: {
|
||||||
interactive: false,
|
interactive: false,
|
||||||
trigger: "dblclick", // or "click" for single click
|
trigger: "dblclick", // or "click" for single click
|
||||||
amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)
|
||||||
},
|
},
|
||||||
pan: {
|
pan: {
|
||||||
interactive: false,
|
interactive: false,
|
||||||
cursor: "move",
|
cursor: "move",
|
||||||
frameRate: 20
|
frameRate: 20
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function init(plot) {
|
||||||
|
function onZoomClick(e, zoomOut) {
|
||||||
|
var c = plot.offset();
|
||||||
|
c.left = e.pageX - c.left;
|
||||||
|
c.top = e.pageY - c.top;
|
||||||
|
if (zoomOut)
|
||||||
|
plot.zoomOut({ center: c });
|
||||||
|
else
|
||||||
|
plot.zoom({ center: c });
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseWheel(e, delta) {
|
||||||
|
e.preventDefault();
|
||||||
|
onZoomClick(e, delta < 0);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
|
||||||
|
panTimeout = null;
|
||||||
|
|
||||||
|
function onDragStart(e) {
|
||||||
|
if (e.which != 1) // only accept left-click
|
||||||
|
return false;
|
||||||
|
var c = plot.getPlaceholder().css('cursor');
|
||||||
|
if (c)
|
||||||
|
prevCursor = c;
|
||||||
|
plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
|
||||||
|
prevPageX = e.pageX;
|
||||||
|
prevPageY = e.pageY;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDrag(e) {
|
||||||
|
var frameRate = plot.getOptions().pan.frameRate;
|
||||||
|
if (panTimeout || !frameRate)
|
||||||
|
return;
|
||||||
|
|
||||||
|
panTimeout = setTimeout(function () {
|
||||||
|
plot.pan({ left: prevPageX - e.pageX,
|
||||||
|
top: prevPageY - e.pageY });
|
||||||
|
prevPageX = e.pageX;
|
||||||
|
prevPageY = e.pageY;
|
||||||
|
|
||||||
|
panTimeout = null;
|
||||||
|
}, 1 / frameRate * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDragEnd(e) {
|
||||||
|
if (panTimeout) {
|
||||||
|
clearTimeout(panTimeout);
|
||||||
|
panTimeout = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.getPlaceholder().css('cursor', prevCursor);
|
||||||
|
plot.pan({ left: prevPageX - e.pageX,
|
||||||
|
top: prevPageY - e.pageY });
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindEvents(plot, eventHolder) {
|
||||||
|
var o = plot.getOptions();
|
||||||
|
if (o.zoom.interactive) {
|
||||||
|
eventHolder[o.zoom.trigger](onZoomClick);
|
||||||
|
eventHolder.mousewheel(onMouseWheel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.pan.interactive) {
|
||||||
|
eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
|
||||||
|
eventHolder.bind("drag", onDrag);
|
||||||
|
eventHolder.bind("dragend", onDragEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.zoomOut = function (args) {
|
||||||
|
if (!args)
|
||||||
|
args = {};
|
||||||
|
|
||||||
|
if (!args.amount)
|
||||||
|
args.amount = plot.getOptions().zoom.amount;
|
||||||
|
|
||||||
|
args.amount = 1 / args.amount;
|
||||||
|
plot.zoom(args);
|
||||||
};
|
};
|
||||||
|
|
||||||
function init(plot) {
|
plot.zoom = function (args) {
|
||||||
function onZoomClick(e, zoomOut) {
|
if (!args)
|
||||||
var c = plot.offset();
|
args = {};
|
||||||
c.left = e.pageX - c.left;
|
|
||||||
c.top = e.pageY - c.top;
|
|
||||||
if (zoomOut)
|
|
||||||
plot.zoomOut({ center: c });
|
|
||||||
else
|
|
||||||
plot.zoom({ center: c });
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseWheel(e, delta) {
|
var c = args.center,
|
||||||
onZoomClick(e, delta < 0);
|
amount = args.amount || plot.getOptions().zoom.amount,
|
||||||
return false;
|
w = plot.width(), h = plot.height();
|
||||||
}
|
|
||||||
|
|
||||||
var prevCursor = 'default', prevPageX = 0, prevPageY = 0,
|
|
||||||
panTimeout = null;
|
|
||||||
|
|
||||||
function onDragStart(e) {
|
if (!c)
|
||||||
if (e.which != 1) // only accept left-click
|
c = { left: w / 2, top: h / 2 };
|
||||||
return false;
|
|
||||||
var c = plot.getPlaceholder().css('cursor');
|
|
||||||
if (c)
|
|
||||||
prevCursor = c;
|
|
||||||
plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);
|
|
||||||
prevPageX = e.pageX;
|
|
||||||
prevPageY = e.pageY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function onDrag(e) {
|
|
||||||
var frameRate = plot.getOptions().pan.frameRate;
|
|
||||||
if (panTimeout || !frameRate)
|
|
||||||
return;
|
|
||||||
|
|
||||||
panTimeout = setTimeout(function () {
|
var xf = c.left / w,
|
||||||
plot.pan({ left: prevPageX - e.pageX,
|
yf = c.top / h,
|
||||||
top: prevPageY - e.pageY });
|
minmax = {
|
||||||
prevPageX = e.pageX;
|
x: {
|
||||||
prevPageY = e.pageY;
|
min: c.left - xf * w / amount,
|
||||||
|
max: c.left + (1 - xf) * w / amount
|
||||||
panTimeout = null;
|
},
|
||||||
}, 1 / frameRate * 1000);
|
y: {
|
||||||
}
|
min: c.top - yf * h / amount,
|
||||||
|
max: c.top + (1 - yf) * h / amount
|
||||||
function onDragEnd(e) {
|
|
||||||
if (panTimeout) {
|
|
||||||
clearTimeout(panTimeout);
|
|
||||||
panTimeout = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.getPlaceholder().css('cursor', prevCursor);
|
|
||||||
plot.pan({ left: prevPageX - e.pageX,
|
|
||||||
top: prevPageY - e.pageY });
|
|
||||||
}
|
|
||||||
|
|
||||||
function bindEvents(plot, eventHolder) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
if (o.zoom.interactive) {
|
|
||||||
eventHolder[o.zoom.trigger](onZoomClick);
|
|
||||||
eventHolder.mousewheel(onMouseWheel);
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (o.pan.interactive) {
|
$.each(plot.getAxes(), function(_, axis) {
|
||||||
eventHolder.bind("dragstart", { distance: 10 }, onDragStart);
|
var opts = axis.options,
|
||||||
eventHolder.bind("drag", onDrag);
|
min = minmax[axis.direction].min,
|
||||||
eventHolder.bind("dragend", onDragEnd);
|
max = minmax[axis.direction].max,
|
||||||
}
|
zr = opts.zoomRange,
|
||||||
|
pr = opts.panRange;
|
||||||
|
|
||||||
|
if (zr === false) // no zooming on this axis
|
||||||
|
return;
|
||||||
|
|
||||||
|
min = axis.c2p(min);
|
||||||
|
max = axis.c2p(max);
|
||||||
|
if (min > max) {
|
||||||
|
// make sure min < max
|
||||||
|
var tmp = min;
|
||||||
|
min = max;
|
||||||
|
max = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
plot.zoomOut = function (args) {
|
//Check that we are in panRange
|
||||||
if (!args)
|
if (pr) {
|
||||||
args = {};
|
if (pr[0] != null && min < pr[0]) {
|
||||||
|
min = pr[0];
|
||||||
if (!args.amount)
|
}
|
||||||
args.amount = plot.getOptions().zoom.amount
|
if (pr[1] != null && max > pr[1]) {
|
||||||
|
max = pr[1];
|
||||||
args.amount = 1 / args.amount;
|
}
|
||||||
plot.zoom(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.zoom = function (args) {
|
|
||||||
if (!args)
|
|
||||||
args = {};
|
|
||||||
|
|
||||||
var c = args.center,
|
|
||||||
amount = args.amount || plot.getOptions().zoom.amount,
|
|
||||||
w = plot.width(), h = plot.height();
|
|
||||||
|
|
||||||
if (!c)
|
|
||||||
c = { left: w / 2, top: h / 2 };
|
|
||||||
|
|
||||||
var xf = c.left / w,
|
|
||||||
yf = c.top / h,
|
|
||||||
minmax = {
|
|
||||||
x: {
|
|
||||||
min: c.left - xf * w / amount,
|
|
||||||
max: c.left + (1 - xf) * w / amount
|
|
||||||
},
|
|
||||||
y: {
|
|
||||||
min: c.top - yf * h / amount,
|
|
||||||
max: c.top + (1 - yf) * h / amount
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$.each(plot.getAxes(), function(_, axis) {
|
|
||||||
var opts = axis.options,
|
|
||||||
min = minmax[axis.direction].min,
|
|
||||||
max = minmax[axis.direction].max,
|
|
||||||
zr = opts.zoomRange;
|
|
||||||
|
|
||||||
if (zr === false) // no zooming on this axis
|
|
||||||
return;
|
|
||||||
|
|
||||||
min = axis.c2p(min);
|
|
||||||
max = axis.c2p(max);
|
|
||||||
if (min > max) {
|
|
||||||
// make sure min < max
|
|
||||||
var tmp = min;
|
|
||||||
min = max;
|
|
||||||
max = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
var range = max - min;
|
|
||||||
if (zr &&
|
|
||||||
((zr[0] != null && range < zr[0]) ||
|
|
||||||
(zr[1] != null && range > zr[1])))
|
|
||||||
return;
|
|
||||||
|
|
||||||
opts.min = min;
|
|
||||||
opts.max = max;
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.setupGrid();
|
|
||||||
plot.draw();
|
|
||||||
|
|
||||||
if (!args.preventEvent)
|
|
||||||
plot.getPlaceholder().trigger("plotzoom", [ plot ]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plot.pan = function (args) {
|
var range = max - min;
|
||||||
var delta = {
|
if (zr &&
|
||||||
x: +args.left,
|
((zr[0] != null && range < zr[0] && amount >1) ||
|
||||||
y: +args.top
|
(zr[1] != null && range > zr[1] && amount <1)))
|
||||||
};
|
return;
|
||||||
|
|
||||||
if (isNaN(delta.x))
|
opts.min = min;
|
||||||
delta.x = 0;
|
opts.max = max;
|
||||||
if (isNaN(delta.y))
|
});
|
||||||
delta.y = 0;
|
|
||||||
|
|
||||||
$.each(plot.getAxes(), function (_, axis) {
|
plot.setupGrid();
|
||||||
var opts = axis.options,
|
plot.draw();
|
||||||
min, max, d = delta[axis.direction];
|
|
||||||
|
|
||||||
min = axis.c2p(axis.p2c(axis.min) + d),
|
if (!args.preventEvent)
|
||||||
max = axis.c2p(axis.p2c(axis.max) + d);
|
plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
|
||||||
|
};
|
||||||
|
|
||||||
var pr = opts.panRange;
|
plot.pan = function (args) {
|
||||||
if (pr === false) // no panning on this axis
|
var delta = {
|
||||||
return;
|
x: +args.left,
|
||||||
|
y: +args.top
|
||||||
if (pr) {
|
};
|
||||||
// check whether we hit the wall
|
|
||||||
if (pr[0] != null && pr[0] > min) {
|
if (isNaN(delta.x))
|
||||||
d = pr[0] - min;
|
delta.x = 0;
|
||||||
min += d;
|
if (isNaN(delta.y))
|
||||||
max += d;
|
delta.y = 0;
|
||||||
}
|
|
||||||
|
$.each(plot.getAxes(), function (_, axis) {
|
||||||
if (pr[1] != null && pr[1] < max) {
|
var opts = axis.options,
|
||||||
d = pr[1] - max;
|
min, max, d = delta[axis.direction];
|
||||||
min += d;
|
|
||||||
max += d;
|
min = axis.c2p(axis.p2c(axis.min) + d),
|
||||||
}
|
max = axis.c2p(axis.p2c(axis.max) + d);
|
||||||
}
|
|
||||||
|
var pr = opts.panRange;
|
||||||
opts.min = min;
|
if (pr === false) // no panning on this axis
|
||||||
opts.max = max;
|
return;
|
||||||
});
|
|
||||||
|
if (pr) {
|
||||||
plot.setupGrid();
|
// check whether we hit the wall
|
||||||
plot.draw();
|
if (pr[0] != null && pr[0] > min) {
|
||||||
|
d = pr[0] - min;
|
||||||
if (!args.preventEvent)
|
min += d;
|
||||||
plot.getPlaceholder().trigger("plotpan", [ plot ]);
|
max += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pr[1] != null && pr[1] < max) {
|
||||||
|
d = pr[1] - max;
|
||||||
|
min += d;
|
||||||
|
max += d;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function shutdown(plot, eventHolder) {
|
opts.min = min;
|
||||||
eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
|
opts.max = max;
|
||||||
eventHolder.unbind("mousewheel", onMouseWheel);
|
});
|
||||||
eventHolder.unbind("dragstart", onDragStart);
|
|
||||||
eventHolder.unbind("drag", onDrag);
|
plot.setupGrid();
|
||||||
eventHolder.unbind("dragend", onDragEnd);
|
plot.draw();
|
||||||
if (panTimeout)
|
|
||||||
clearTimeout(panTimeout);
|
if (!args.preventEvent)
|
||||||
}
|
plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
|
||||||
|
};
|
||||||
plot.hooks.bindEvents.push(bindEvents);
|
|
||||||
plot.hooks.shutdown.push(shutdown);
|
function shutdown(plot, eventHolder) {
|
||||||
|
eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
|
||||||
|
eventHolder.unbind("mousewheel", onMouseWheel);
|
||||||
|
eventHolder.unbind("dragstart", onDragStart);
|
||||||
|
eventHolder.unbind("drag", onDrag);
|
||||||
|
eventHolder.unbind("dragend", onDragEnd);
|
||||||
|
if (panTimeout)
|
||||||
|
clearTimeout(panTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
plot.hooks.bindEvents.push(bindEvents);
|
||||||
init: init,
|
plot.hooks.shutdown.push(shutdown);
|
||||||
options: options,
|
}
|
||||||
name: 'navigate',
|
|
||||||
version: '1.3'
|
$.plot.plugins.push({
|
||||||
});
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'navigate',
|
||||||
|
version: '1.3'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,60 +1,59 @@
|
||||||
/*
|
/* Flot plugin for automatically redrawing plots as the placeholder resizes.
|
||||||
Flot plugin for automatically redrawing plots when the placeholder
|
|
||||||
size changes, e.g. on window resizes.
|
|
||||||
|
|
||||||
It works by listening for changes on the placeholder div (through the
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
jQuery resize event plugin) - if the size changes, it will redraw the
|
Licensed under the MIT license.
|
||||||
plot.
|
|
||||||
|
It works by listening for changes on the placeholder div (through the jQuery
|
||||||
|
resize event plugin) - if the size changes, it will redraw the plot.
|
||||||
|
|
||||||
|
There are no options. If you need to disable the plugin for some plots, you
|
||||||
|
can just fix the size of their placeholders.
|
||||||
|
|
||||||
There are no options. If you need to disable the plugin for some
|
|
||||||
plots, you can just fix the size of their placeholders.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Inline dependency:
|
||||||
/* Inline dependency:
|
|
||||||
* jQuery resize event - v1.1 - 3/14/2010
|
* jQuery resize event - v1.1 - 3/14/2010
|
||||||
* http://benalman.com/projects/jquery-resize-plugin/
|
* http://benalman.com/projects/jquery-resize-plugin/
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||||
* Dual licensed under the MIT and GPL licenses.
|
* Dual licensed under the MIT and GPL licenses.
|
||||||
* http://benalman.com/about/license/
|
* http://benalman.com/about/license/
|
||||||
*/
|
*/
|
||||||
(function($,h,c){var a=$([]),e=$.resize=$.extend($.resize,{}),i,k="setTimeout",j="resize",d=j+"-special-event",b="delay",f="throttleWindow";e[b]=250;e[f]=true;$.event.special[j]={setup:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.add(l);$.data(this,d,{w:l.width(),h:l.height()});if(a.length===1){g()}},teardown:function(){if(!e[f]&&this[k]){return false}var l=$(this);a=a.not(l);l.removeData(d);if(!a.length){clearTimeout(i)}},add:function(l){if(!e[f]&&this[k]){return false}var n;function m(s,o,p){var q=$(this),r=$.data(this,d);r.w=o!==c?o:q.width();r.h=p!==c?p:q.height();n.apply(this,arguments)}if($.isFunction(l)){n=l;return m}else{n=l.handler;l.handler=m}}};function g(){i=h[k](function(){a.each(function(){var n=$(this),m=n.width(),l=n.height(),o=$.data(this,d);if(m!==o.w||l!==o.h){n.trigger(j,[o.w=m,o.h=l])}});g()},e[b])}})(jQuery,this);
|
(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
|
||||||
|
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = { }; // no options
|
var options = { }; // no options
|
||||||
|
|
||||||
function init(plot) {
|
function init(plot) {
|
||||||
function onResize() {
|
function onResize() {
|
||||||
var placeholder = plot.getPlaceholder();
|
var placeholder = plot.getPlaceholder();
|
||||||
|
|
||||||
// somebody might have hidden us and we can't plot
|
// somebody might have hidden us and we can't plot
|
||||||
// when we don't have the dimensions
|
// when we don't have the dimensions
|
||||||
if (placeholder.width() == 0 || placeholder.height() == 0)
|
if (placeholder.width() == 0 || placeholder.height() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
plot.resize();
|
plot.resize();
|
||||||
plot.setupGrid();
|
plot.setupGrid();
|
||||||
plot.draw();
|
plot.draw();
|
||||||
}
|
|
||||||
|
|
||||||
function bindEvents(plot, eventHolder) {
|
|
||||||
plot.getPlaceholder().resize(onResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
function shutdown(plot, eventHolder) {
|
|
||||||
plot.getPlaceholder().unbind("resize", onResize);
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(bindEvents);
|
|
||||||
plot.hooks.shutdown.push(shutdown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
function bindEvents(plot, eventHolder) {
|
||||||
init: init,
|
plot.getPlaceholder().resize(onResize);
|
||||||
options: options,
|
}
|
||||||
name: 'resize',
|
|
||||||
version: '1.0'
|
function shutdown(plot, eventHolder) {
|
||||||
});
|
plot.getPlaceholder().unbind("resize", onResize);
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.bindEvents.push(bindEvents);
|
||||||
|
plot.hooks.shutdown.push(shutdown);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'resize',
|
||||||
|
version: '1.0'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,344 +1,360 @@
|
||||||
/*
|
/* Flot plugin for selecting regions of a plot.
|
||||||
Flot plugin for selecting regions.
|
|
||||||
|
|
||||||
The plugin defines the following options:
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
selection: {
|
The plugin supports these options:
|
||||||
mode: null or "x" or "y" or "xy",
|
|
||||||
color: color
|
|
||||||
}
|
|
||||||
|
|
||||||
Selection support is enabled by setting the mode to one of "x", "y" or
|
selection: {
|
||||||
"xy". In "x" mode, the user will only be able to specify the x range,
|
mode: null or "x" or "y" or "xy",
|
||||||
similarly for "y" mode. For "xy", the selection becomes a rectangle
|
color: color,
|
||||||
where both ranges can be specified. "color" is color of the selection
|
shape: "round" or "miter" or "bevel",
|
||||||
(if you need to change the color later on, you can get to it with
|
minSize: number of pixels
|
||||||
plot.getOptions().selection.color).
|
}
|
||||||
|
|
||||||
When selection support is enabled, a "plotselected" event will be
|
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
|
||||||
emitted on the DOM element you passed into the plot function. The
|
In "x" mode, the user will only be able to specify the x range, similarly for
|
||||||
event handler gets a parameter with the ranges selected on the axes,
|
"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
|
||||||
like this:
|
specified. "color" is color of the selection (if you need to change the color
|
||||||
|
later on, you can get to it with plot.getOptions().selection.color). "shape"
|
||||||
|
is the shape of the corners of the selection.
|
||||||
|
|
||||||
placeholder.bind("plotselected", function(event, ranges) {
|
"minSize" is the minimum size a selection can be in pixels. This value can
|
||||||
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
be customized to determine the smallest size a selection can be and still
|
||||||
// similar for yaxis - with multiple axes, the extra ones are in
|
have the selection rectangle be displayed. When customizing this value, the
|
||||||
// x2axis, x3axis, ...
|
fact that it refers to pixels, not axis units must be taken into account.
|
||||||
});
|
Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
|
||||||
|
minute, setting "minSize" to 1 will not make the minimum selection size 1
|
||||||
|
minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
|
||||||
|
"plotunselected" events from being fired when the user clicks the mouse without
|
||||||
|
dragging.
|
||||||
|
|
||||||
The "plotselected" event is only fired when the user has finished
|
When selection support is enabled, a "plotselected" event will be emitted on
|
||||||
making the selection. A "plotselecting" event is fired during the
|
the DOM element you passed into the plot function. The event handler gets a
|
||||||
process with the same parameters as the "plotselected" event, in case
|
parameter with the ranges selected on the axes, like this:
|
||||||
you want to know what's happening while it's happening,
|
|
||||||
|
|
||||||
A "plotunselected" event with no arguments is emitted when the user
|
placeholder.bind( "plotselected", function( event, ranges ) {
|
||||||
clicks the mouse to remove the selection.
|
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
||||||
|
// similar for yaxis - with multiple axes, the extra ones are in
|
||||||
|
// x2axis, x3axis, ...
|
||||||
|
});
|
||||||
|
|
||||||
|
The "plotselected" event is only fired when the user has finished making the
|
||||||
|
selection. A "plotselecting" event is fired during the process with the same
|
||||||
|
parameters as the "plotselected" event, in case you want to know what's
|
||||||
|
happening while it's happening,
|
||||||
|
|
||||||
|
A "plotunselected" event with no arguments is emitted when the user clicks the
|
||||||
|
mouse to remove the selection. As stated above, setting "minSize" to 0 will
|
||||||
|
destroy this behavior.
|
||||||
|
|
||||||
The plugin allso adds the following methods to the plot object:
|
The plugin allso adds the following methods to the plot object:
|
||||||
|
|
||||||
- setSelection(ranges, preventEvent)
|
- setSelection( ranges, preventEvent )
|
||||||
|
|
||||||
Set the selection rectangle. The passed in ranges is on the same
|
Set the selection rectangle. The passed in ranges is on the same form as
|
||||||
form as returned in the "plotselected" event. If the selection mode
|
returned in the "plotselected" event. If the selection mode is "x", you
|
||||||
is "x", you should put in either an xaxis range, if the mode is "y"
|
should put in either an xaxis range, if the mode is "y" you need to put in
|
||||||
you need to put in an yaxis range and both xaxis and yaxis if the
|
an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
|
||||||
selection mode is "xy", like this:
|
this:
|
||||||
|
|
||||||
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
||||||
|
|
||||||
setSelection will trigger the "plotselected" event when called. If
|
setSelection will trigger the "plotselected" event when called. If you don't
|
||||||
you don't want that to happen, e.g. if you're inside a
|
want that to happen, e.g. if you're inside a "plotselected" handler, pass
|
||||||
"plotselected" handler, pass true as the second parameter. If you
|
true as the second parameter. If you are using multiple axes, you can
|
||||||
are using multiple axes, you can specify the ranges on any of those,
|
specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
|
||||||
e.g. as x2axis/x3axis/... instead of xaxis, the plugin picks the
|
xaxis, the plugin picks the first one it sees.
|
||||||
first one it sees.
|
|
||||||
|
- clearSelection( preventEvent )
|
||||||
- clearSelection(preventEvent)
|
|
||||||
|
|
||||||
Clear the selection rectangle. Pass in true to avoid getting a
|
Clear the selection rectangle. Pass in true to avoid getting a
|
||||||
"plotunselected" event.
|
"plotunselected" event.
|
||||||
|
|
||||||
- getSelection()
|
- getSelection()
|
||||||
|
|
||||||
Returns the current selection in the same format as the
|
Returns the current selection in the same format as the "plotselected"
|
||||||
"plotselected" event. If there's currently no selection, the
|
event. If there's currently no selection, the function returns null.
|
||||||
function returns null.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
function init(plot) {
|
function init(plot) {
|
||||||
var selection = {
|
var selection = {
|
||||||
first: { x: -1, y: -1}, second: { x: -1, y: -1},
|
first: { x: -1, y: -1}, second: { x: -1, y: -1},
|
||||||
show: false,
|
show: false,
|
||||||
active: false
|
active: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: The drag handling implemented here should be
|
// FIXME: The drag handling implemented here should be
|
||||||
// abstracted out, there's some similar code from a library in
|
// abstracted out, there's some similar code from a library in
|
||||||
// the navigation plugin, this should be massaged a bit to fit
|
// the navigation plugin, this should be massaged a bit to fit
|
||||||
// the Flot cases here better and reused. Doing this would
|
// the Flot cases here better and reused. Doing this would
|
||||||
// make this plugin much slimmer.
|
// make this plugin much slimmer.
|
||||||
var savedhandlers = {};
|
var savedhandlers = {};
|
||||||
|
|
||||||
var mouseUpHandler = null;
|
var mouseUpHandler = null;
|
||||||
|
|
||||||
function onMouseMove(e) {
|
|
||||||
if (selection.active) {
|
|
||||||
updateSelection(e);
|
|
||||||
|
|
||||||
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseDown(e) {
|
function onMouseMove(e) {
|
||||||
if (e.which != 1) // only accept left-click
|
if (selection.active) {
|
||||||
return;
|
updateSelection(e);
|
||||||
|
|
||||||
// cancel out any text selections
|
|
||||||
document.body.focus();
|
|
||||||
|
|
||||||
// prevent text selection and drag in old-school browsers
|
|
||||||
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
|
|
||||||
savedhandlers.onselectstart = document.onselectstart;
|
|
||||||
document.onselectstart = function () { return false; };
|
|
||||||
}
|
|
||||||
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
|
|
||||||
savedhandlers.ondrag = document.ondrag;
|
|
||||||
document.ondrag = function () { return false; };
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectionPos(selection.first, e);
|
|
||||||
|
|
||||||
selection.active = true;
|
|
||||||
|
|
||||||
// this is a bit silly, but we have to use a closure to be
|
|
||||||
// able to whack the same handler again
|
|
||||||
mouseUpHandler = function (e) { onMouseUp(e); };
|
|
||||||
|
|
||||||
$(document).one("mouseup", mouseUpHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMouseUp(e) {
|
|
||||||
mouseUpHandler = null;
|
|
||||||
|
|
||||||
// revert drag stuff for old-school browsers
|
|
||||||
if (document.onselectstart !== undefined)
|
|
||||||
document.onselectstart = savedhandlers.onselectstart;
|
|
||||||
if (document.ondrag !== undefined)
|
|
||||||
document.ondrag = savedhandlers.ondrag;
|
|
||||||
|
|
||||||
// no more dragging
|
|
||||||
selection.active = false;
|
|
||||||
updateSelection(e);
|
|
||||||
|
|
||||||
if (selectionIsSane())
|
|
||||||
triggerSelectedEvent();
|
|
||||||
else {
|
|
||||||
// this counts as a clear
|
|
||||||
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
|
||||||
plot.getPlaceholder().trigger("plotselecting", [ null ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSelection() {
|
|
||||||
if (!selectionIsSane())
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var r = {}, c1 = selection.first, c2 = selection.second;
|
|
||||||
$.each(plot.getAxes(), function (name, axis) {
|
|
||||||
if (axis.used) {
|
|
||||||
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
|
|
||||||
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
function triggerSelectedEvent() {
|
|
||||||
var r = getSelection();
|
|
||||||
|
|
||||||
plot.getPlaceholder().trigger("plotselected", [ r ]);
|
|
||||||
|
|
||||||
// backwards-compat stuff, to be removed in future
|
|
||||||
if (r.xaxis && r.yaxis)
|
|
||||||
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clamp(min, value, max) {
|
|
||||||
return value < min ? min: (value > max ? max: value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelectionPos(pos, e) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
var offset = plot.getPlaceholder().offset();
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
|
|
||||||
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
|
|
||||||
|
|
||||||
if (o.selection.mode == "y")
|
|
||||||
pos.x = pos == selection.first ? 0 : plot.width();
|
|
||||||
|
|
||||||
if (o.selection.mode == "x")
|
|
||||||
pos.y = pos == selection.first ? 0 : plot.height();
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateSelection(pos) {
|
|
||||||
if (pos.pageX == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setSelectionPos(selection.second, pos);
|
|
||||||
if (selectionIsSane()) {
|
|
||||||
selection.show = true;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
clearSelection(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearSelection(preventEvent) {
|
|
||||||
if (selection.show) {
|
|
||||||
selection.show = false;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
if (!preventEvent)
|
|
||||||
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// function taken from markings support in Flot
|
|
||||||
function extractRange(ranges, coord) {
|
|
||||||
var axis, from, to, key, axes = plot.getAxes();
|
|
||||||
|
|
||||||
for (var k in axes) {
|
|
||||||
axis = axes[k];
|
|
||||||
if (axis.direction == coord) {
|
|
||||||
key = coord + axis.n + "axis";
|
|
||||||
if (!ranges[key] && axis.n == 1)
|
|
||||||
key = coord + "axis"; // support x1axis as xaxis
|
|
||||||
if (ranges[key]) {
|
|
||||||
from = ranges[key].from;
|
|
||||||
to = ranges[key].to;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// backwards-compat stuff - to be removed in future
|
|
||||||
if (!ranges[key]) {
|
|
||||||
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
|
|
||||||
from = ranges[coord + "1"];
|
|
||||||
to = ranges[coord + "2"];
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto-reverse as an added bonus
|
|
||||||
if (from != null && to != null && from > to) {
|
|
||||||
var tmp = from;
|
|
||||||
from = to;
|
|
||||||
to = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return { from: from, to: to, axis: axis };
|
|
||||||
}
|
|
||||||
|
|
||||||
function setSelection(ranges, preventEvent) {
|
|
||||||
var axis, range, o = plot.getOptions();
|
|
||||||
|
|
||||||
if (o.selection.mode == "y") {
|
|
||||||
selection.first.x = 0;
|
|
||||||
selection.second.x = plot.width();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range = extractRange(ranges, "x");
|
|
||||||
|
|
||||||
selection.first.x = range.axis.p2c(range.from);
|
|
||||||
selection.second.x = range.axis.p2c(range.to);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o.selection.mode == "x") {
|
|
||||||
selection.first.y = 0;
|
|
||||||
selection.second.y = plot.height();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
range = extractRange(ranges, "y");
|
|
||||||
|
|
||||||
selection.first.y = range.axis.p2c(range.from);
|
|
||||||
selection.second.y = range.axis.p2c(range.to);
|
|
||||||
}
|
|
||||||
|
|
||||||
selection.show = true;
|
|
||||||
plot.triggerRedrawOverlay();
|
|
||||||
if (!preventEvent && selectionIsSane())
|
|
||||||
triggerSelectedEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectionIsSane() {
|
|
||||||
var minSize = 5;
|
|
||||||
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
|
|
||||||
Math.abs(selection.second.y - selection.first.y) >= minSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.clearSelection = clearSelection;
|
|
||||||
plot.setSelection = setSelection;
|
|
||||||
plot.getSelection = getSelection;
|
|
||||||
|
|
||||||
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
|
||||||
var o = plot.getOptions();
|
|
||||||
if (o.selection.mode != null) {
|
|
||||||
eventHolder.mousemove(onMouseMove);
|
|
||||||
eventHolder.mousedown(onMouseDown);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
|
||||||
// draw selection
|
|
||||||
if (selection.show && selectionIsSane()) {
|
|
||||||
var plotOffset = plot.getPlotOffset();
|
|
||||||
var o = plot.getOptions();
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
ctx.translate(plotOffset.left, plotOffset.top);
|
|
||||||
|
|
||||||
var c = $.color.parse(o.selection.color);
|
|
||||||
|
|
||||||
ctx.strokeStyle = c.scale('a', 0.8).toString();
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.lineJoin = "round";
|
|
||||||
ctx.fillStyle = c.scale('a', 0.4).toString();
|
|
||||||
|
|
||||||
var x = Math.min(selection.first.x, selection.second.x),
|
|
||||||
y = Math.min(selection.first.y, selection.second.y),
|
|
||||||
w = Math.abs(selection.second.x - selection.first.x),
|
|
||||||
h = Math.abs(selection.second.y - selection.first.y);
|
|
||||||
|
|
||||||
ctx.fillRect(x, y, w, h);
|
|
||||||
ctx.strokeRect(x, y, w, h);
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
|
||||||
eventHolder.unbind("mousemove", onMouseMove);
|
|
||||||
eventHolder.unbind("mousedown", onMouseDown);
|
|
||||||
|
|
||||||
if (mouseUpHandler)
|
|
||||||
$(document).unbind("mouseup", mouseUpHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
function onMouseDown(e) {
|
||||||
init: init,
|
if (e.which != 1) // only accept left-click
|
||||||
options: {
|
return;
|
||||||
selection: {
|
|
||||||
mode: null, // one of null, "x", "y" or "xy"
|
// cancel out any text selections
|
||||||
color: "#e8cfac"
|
document.body.focus();
|
||||||
}
|
|
||||||
},
|
// prevent text selection and drag in old-school browsers
|
||||||
name: 'selection',
|
if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
|
||||||
version: '1.1'
|
savedhandlers.onselectstart = document.onselectstart;
|
||||||
|
document.onselectstart = function () { return false; };
|
||||||
|
}
|
||||||
|
if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
|
||||||
|
savedhandlers.ondrag = document.ondrag;
|
||||||
|
document.ondrag = function () { return false; };
|
||||||
|
}
|
||||||
|
|
||||||
|
setSelectionPos(selection.first, e);
|
||||||
|
|
||||||
|
selection.active = true;
|
||||||
|
|
||||||
|
// this is a bit silly, but we have to use a closure to be
|
||||||
|
// able to whack the same handler again
|
||||||
|
mouseUpHandler = function (e) { onMouseUp(e); };
|
||||||
|
|
||||||
|
$(document).one("mouseup", mouseUpHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onMouseUp(e) {
|
||||||
|
mouseUpHandler = null;
|
||||||
|
|
||||||
|
// revert drag stuff for old-school browsers
|
||||||
|
if (document.onselectstart !== undefined)
|
||||||
|
document.onselectstart = savedhandlers.onselectstart;
|
||||||
|
if (document.ondrag !== undefined)
|
||||||
|
document.ondrag = savedhandlers.ondrag;
|
||||||
|
|
||||||
|
// no more dragging
|
||||||
|
selection.active = false;
|
||||||
|
updateSelection(e);
|
||||||
|
|
||||||
|
if (selectionIsSane())
|
||||||
|
triggerSelectedEvent();
|
||||||
|
else {
|
||||||
|
// this counts as a clear
|
||||||
|
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
||||||
|
plot.getPlaceholder().trigger("plotselecting", [ null ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelection() {
|
||||||
|
if (!selectionIsSane())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!selection.show) return null;
|
||||||
|
|
||||||
|
var r = {}, c1 = selection.first, c2 = selection.second;
|
||||||
|
$.each(plot.getAxes(), function (name, axis) {
|
||||||
|
if (axis.used) {
|
||||||
|
var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
|
||||||
|
r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerSelectedEvent() {
|
||||||
|
var r = getSelection();
|
||||||
|
|
||||||
|
plot.getPlaceholder().trigger("plotselected", [ r ]);
|
||||||
|
|
||||||
|
// backwards-compat stuff, to be removed in future
|
||||||
|
if (r.xaxis && r.yaxis)
|
||||||
|
plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clamp(min, value, max) {
|
||||||
|
return value < min ? min: (value > max ? max: value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelectionPos(pos, e) {
|
||||||
|
var o = plot.getOptions();
|
||||||
|
var offset = plot.getPlaceholder().offset();
|
||||||
|
var plotOffset = plot.getPlotOffset();
|
||||||
|
pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
|
||||||
|
pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
|
||||||
|
|
||||||
|
if (o.selection.mode == "y")
|
||||||
|
pos.x = pos == selection.first ? 0 : plot.width();
|
||||||
|
|
||||||
|
if (o.selection.mode == "x")
|
||||||
|
pos.y = pos == selection.first ? 0 : plot.height();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSelection(pos) {
|
||||||
|
if (pos.pageX == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setSelectionPos(selection.second, pos);
|
||||||
|
if (selectionIsSane()) {
|
||||||
|
selection.show = true;
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
clearSelection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearSelection(preventEvent) {
|
||||||
|
if (selection.show) {
|
||||||
|
selection.show = false;
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
if (!preventEvent)
|
||||||
|
plot.getPlaceholder().trigger("plotunselected", [ ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// function taken from markings support in Flot
|
||||||
|
function extractRange(ranges, coord) {
|
||||||
|
var axis, from, to, key, axes = plot.getAxes();
|
||||||
|
|
||||||
|
for (var k in axes) {
|
||||||
|
axis = axes[k];
|
||||||
|
if (axis.direction == coord) {
|
||||||
|
key = coord + axis.n + "axis";
|
||||||
|
if (!ranges[key] && axis.n == 1)
|
||||||
|
key = coord + "axis"; // support x1axis as xaxis
|
||||||
|
if (ranges[key]) {
|
||||||
|
from = ranges[key].from;
|
||||||
|
to = ranges[key].to;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// backwards-compat stuff - to be removed in future
|
||||||
|
if (!ranges[key]) {
|
||||||
|
axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
|
||||||
|
from = ranges[coord + "1"];
|
||||||
|
to = ranges[coord + "2"];
|
||||||
|
}
|
||||||
|
|
||||||
|
// auto-reverse as an added bonus
|
||||||
|
if (from != null && to != null && from > to) {
|
||||||
|
var tmp = from;
|
||||||
|
from = to;
|
||||||
|
to = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { from: from, to: to, axis: axis };
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSelection(ranges, preventEvent) {
|
||||||
|
var axis, range, o = plot.getOptions();
|
||||||
|
|
||||||
|
if (o.selection.mode == "y") {
|
||||||
|
selection.first.x = 0;
|
||||||
|
selection.second.x = plot.width();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
range = extractRange(ranges, "x");
|
||||||
|
|
||||||
|
selection.first.x = range.axis.p2c(range.from);
|
||||||
|
selection.second.x = range.axis.p2c(range.to);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o.selection.mode == "x") {
|
||||||
|
selection.first.y = 0;
|
||||||
|
selection.second.y = plot.height();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
range = extractRange(ranges, "y");
|
||||||
|
|
||||||
|
selection.first.y = range.axis.p2c(range.from);
|
||||||
|
selection.second.y = range.axis.p2c(range.to);
|
||||||
|
}
|
||||||
|
|
||||||
|
selection.show = true;
|
||||||
|
plot.triggerRedrawOverlay();
|
||||||
|
if (!preventEvent && selectionIsSane())
|
||||||
|
triggerSelectedEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectionIsSane() {
|
||||||
|
var minSize = plot.getOptions().selection.minSize;
|
||||||
|
return Math.abs(selection.second.x - selection.first.x) >= minSize &&
|
||||||
|
Math.abs(selection.second.y - selection.first.y) >= minSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.clearSelection = clearSelection;
|
||||||
|
plot.setSelection = setSelection;
|
||||||
|
plot.getSelection = getSelection;
|
||||||
|
|
||||||
|
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
||||||
|
var o = plot.getOptions();
|
||||||
|
if (o.selection.mode != null) {
|
||||||
|
eventHolder.mousemove(onMouseMove);
|
||||||
|
eventHolder.mousedown(onMouseDown);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
plot.hooks.drawOverlay.push(function (plot, ctx) {
|
||||||
|
// draw selection
|
||||||
|
if (selection.show && selectionIsSane()) {
|
||||||
|
var plotOffset = plot.getPlotOffset();
|
||||||
|
var o = plot.getOptions();
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(plotOffset.left, plotOffset.top);
|
||||||
|
|
||||||
|
var c = $.color.parse(o.selection.color);
|
||||||
|
|
||||||
|
ctx.strokeStyle = c.scale('a', 0.8).toString();
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.lineJoin = o.selection.shape;
|
||||||
|
ctx.fillStyle = c.scale('a', 0.4).toString();
|
||||||
|
|
||||||
|
var x = Math.min(selection.first.x, selection.second.x) + 0.5,
|
||||||
|
y = Math.min(selection.first.y, selection.second.y) + 0.5,
|
||||||
|
w = Math.abs(selection.second.x - selection.first.x) - 1,
|
||||||
|
h = Math.abs(selection.second.y - selection.first.y) - 1;
|
||||||
|
|
||||||
|
ctx.fillRect(x, y, w, h);
|
||||||
|
ctx.strokeRect(x, y, w, h);
|
||||||
|
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
plot.hooks.shutdown.push(function (plot, eventHolder) {
|
||||||
|
eventHolder.unbind("mousemove", onMouseMove);
|
||||||
|
eventHolder.unbind("mousedown", onMouseDown);
|
||||||
|
|
||||||
|
if (mouseUpHandler)
|
||||||
|
$(document).unbind("mouseup", mouseUpHandler);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: {
|
||||||
|
selection: {
|
||||||
|
mode: null, // one of null, "x", "y" or "xy"
|
||||||
|
color: "#e8cfac",
|
||||||
|
shape: "round", // one of "round", "miter", or "bevel"
|
||||||
|
minSize: 5 // minimum number of pixels
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: 'selection',
|
||||||
|
version: '1.1'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,184 +1,188 @@
|
||||||
/*
|
/* Flot plugin for stacking data sets rather than overlyaing them.
|
||||||
Flot plugin for stacking data sets, i.e. putting them on top of each
|
|
||||||
other, for accumulative graphs.
|
|
||||||
|
|
||||||
The plugin assumes the data is sorted on x (or y if stacking
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
horizontally). For line charts, it is assumed that if a line has an
|
Licensed under the MIT license.
|
||||||
undefined gap (from a null point), then the line above it should have
|
|
||||||
the same gap - insert zeros instead of "null" if you want another
|
|
||||||
behaviour. This also holds for the start and end of the chart. Note
|
|
||||||
that stacking a mix of positive and negative values in most instances
|
|
||||||
doesn't make sense (so it looks weird).
|
|
||||||
|
|
||||||
Two or more series are stacked when their "stack" attribute is set to
|
The plugin assumes the data is sorted on x (or y if stacking horizontally).
|
||||||
the same key (which can be any number or string or just "true"). To
|
For line charts, it is assumed that if a line has an undefined gap (from a
|
||||||
specify the default stack, you can set
|
null point), then the line above it should have the same gap - insert zeros
|
||||||
|
instead of "null" if you want another behaviour. This also holds for the start
|
||||||
|
and end of the chart. Note that stacking a mix of positive and negative values
|
||||||
|
in most instances doesn't make sense (so it looks weird).
|
||||||
|
|
||||||
series: {
|
Two or more series are stacked when their "stack" attribute is set to the same
|
||||||
stack: null or true or key (number/string)
|
key (which can be any number or string or just "true"). To specify the default
|
||||||
}
|
stack, you can set the stack option like this:
|
||||||
|
|
||||||
or specify it for a specific series
|
series: {
|
||||||
|
stack: null/false, true, or a key (number/string)
|
||||||
|
}
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], stack: true }])
|
You can also specify it for a single series, like this:
|
||||||
|
|
||||||
The stacking order is determined by the order of the data series in
|
$.plot( $("#placeholder"), [{
|
||||||
the array (later series end up on top of the previous).
|
data: [ ... ],
|
||||||
|
stack: true
|
||||||
|
}])
|
||||||
|
|
||||||
|
The stacking order is determined by the order of the data series in the array
|
||||||
|
(later series end up on top of the previous).
|
||||||
|
|
||||||
|
Internally, the plugin modifies the datapoints in each series, adding an
|
||||||
|
offset to the y value. For line series, extra data points are inserted through
|
||||||
|
interpolation. If there's a second y value, it's also adjusted (e.g for bar
|
||||||
|
charts or filled areas).
|
||||||
|
|
||||||
Internally, the plugin modifies the datapoints in each series, adding
|
|
||||||
an offset to the y value. For line series, extra data points are
|
|
||||||
inserted through interpolation. If there's a second y value, it's also
|
|
||||||
adjusted (e.g for bar charts or filled areas).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = {
|
var options = {
|
||||||
series: { stack: null } // or number/string
|
series: { stack: null } // or number/string
|
||||||
};
|
};
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function findMatchingSeries(s, allseries) {
|
|
||||||
var res = null
|
|
||||||
for (var i = 0; i < allseries.length; ++i) {
|
|
||||||
if (s == allseries[i])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (allseries[i].stack == s.stack)
|
|
||||||
res = allseries[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
function stackData(plot, s, datapoints) {
|
|
||||||
if (s.stack == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var other = findMatchingSeries(s, plot.getData());
|
function init(plot) {
|
||||||
if (!other)
|
function findMatchingSeries(s, allseries) {
|
||||||
return;
|
var res = null;
|
||||||
|
for (var i = 0; i < allseries.length; ++i) {
|
||||||
|
if (s == allseries[i])
|
||||||
|
break;
|
||||||
|
|
||||||
var ps = datapoints.pointsize,
|
if (allseries[i].stack == s.stack)
|
||||||
points = datapoints.points,
|
res = allseries[i];
|
||||||
otherps = other.datapoints.pointsize,
|
}
|
||||||
otherpoints = other.datapoints.points,
|
|
||||||
newpoints = [],
|
|
||||||
px, py, intery, qx, qy, bottom,
|
|
||||||
withlines = s.lines.show,
|
|
||||||
horizontal = s.bars.horizontal,
|
|
||||||
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
|
|
||||||
withsteps = withlines && s.lines.steps,
|
|
||||||
fromgap = true,
|
|
||||||
keyOffset = horizontal ? 1 : 0,
|
|
||||||
accumulateOffset = horizontal ? 0 : 1,
|
|
||||||
i = 0, j = 0, l;
|
|
||||||
|
|
||||||
while (true) {
|
return res;
|
||||||
if (i >= points.length)
|
|
||||||
break;
|
|
||||||
|
|
||||||
l = newpoints.length;
|
|
||||||
|
|
||||||
if (points[i] == null) {
|
|
||||||
// copy gaps
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (j >= otherpoints.length) {
|
|
||||||
// for lines, we can't use the rest of the points
|
|
||||||
if (!withlines) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
}
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
else if (otherpoints[j] == null) {
|
|
||||||
// oops, got a gap
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(null);
|
|
||||||
fromgap = true;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// cases where we actually got two points
|
|
||||||
px = points[i + keyOffset];
|
|
||||||
py = points[i + accumulateOffset];
|
|
||||||
qx = otherpoints[j + keyOffset];
|
|
||||||
qy = otherpoints[j + accumulateOffset];
|
|
||||||
bottom = 0;
|
|
||||||
|
|
||||||
if (px == qx) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
newpoints[l + accumulateOffset] += qy;
|
|
||||||
bottom = qy;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else if (px > qx) {
|
|
||||||
// we got past point below, might need to
|
|
||||||
// insert interpolated extra point
|
|
||||||
if (withlines && i > 0 && points[i - ps] != null) {
|
|
||||||
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
|
|
||||||
newpoints.push(qx);
|
|
||||||
newpoints.push(intery + qy);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
bottom = qy;
|
|
||||||
}
|
|
||||||
|
|
||||||
j += otherps;
|
|
||||||
}
|
|
||||||
else { // px < qx
|
|
||||||
if (fromgap && withlines) {
|
|
||||||
// if we come from a gap, we just skip this point
|
|
||||||
i += ps;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints.push(points[i + m]);
|
|
||||||
|
|
||||||
// we might be able to interpolate a point below,
|
|
||||||
// this can give us a better y
|
|
||||||
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
|
||||||
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
|
|
||||||
|
|
||||||
newpoints[l + accumulateOffset] += bottom;
|
|
||||||
|
|
||||||
i += ps;
|
|
||||||
}
|
|
||||||
|
|
||||||
fromgap = false;
|
|
||||||
|
|
||||||
if (l != newpoints.length && withbottom)
|
|
||||||
newpoints[l + 2] += bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
// maintain the line steps invariant
|
|
||||||
if (withsteps && l != newpoints.length && l > 0
|
|
||||||
&& newpoints[l] != null
|
|
||||||
&& newpoints[l] != newpoints[l - ps]
|
|
||||||
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
|
||||||
for (m = 0; m < ps; ++m)
|
|
||||||
newpoints[l + ps + m] = newpoints[l + m];
|
|
||||||
newpoints[l + 1] = newpoints[l - ps + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(stackData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
function stackData(plot, s, datapoints) {
|
||||||
init: init,
|
if (s.stack == null || s.stack === false)
|
||||||
options: options,
|
return;
|
||||||
name: 'stack',
|
|
||||||
version: '1.2'
|
var other = findMatchingSeries(s, plot.getData());
|
||||||
});
|
if (!other)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var ps = datapoints.pointsize,
|
||||||
|
points = datapoints.points,
|
||||||
|
otherps = other.datapoints.pointsize,
|
||||||
|
otherpoints = other.datapoints.points,
|
||||||
|
newpoints = [],
|
||||||
|
px, py, intery, qx, qy, bottom,
|
||||||
|
withlines = s.lines.show,
|
||||||
|
horizontal = s.bars.horizontal,
|
||||||
|
withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
|
||||||
|
withsteps = withlines && s.lines.steps,
|
||||||
|
fromgap = true,
|
||||||
|
keyOffset = horizontal ? 1 : 0,
|
||||||
|
accumulateOffset = horizontal ? 0 : 1,
|
||||||
|
i = 0, j = 0, l, m;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (i >= points.length)
|
||||||
|
break;
|
||||||
|
|
||||||
|
l = newpoints.length;
|
||||||
|
|
||||||
|
if (points[i] == null) {
|
||||||
|
// copy gaps
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints.push(points[i + m]);
|
||||||
|
i += ps;
|
||||||
|
}
|
||||||
|
else if (j >= otherpoints.length) {
|
||||||
|
// for lines, we can't use the rest of the points
|
||||||
|
if (!withlines) {
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints.push(points[i + m]);
|
||||||
|
}
|
||||||
|
i += ps;
|
||||||
|
}
|
||||||
|
else if (otherpoints[j] == null) {
|
||||||
|
// oops, got a gap
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints.push(null);
|
||||||
|
fromgap = true;
|
||||||
|
j += otherps;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// cases where we actually got two points
|
||||||
|
px = points[i + keyOffset];
|
||||||
|
py = points[i + accumulateOffset];
|
||||||
|
qx = otherpoints[j + keyOffset];
|
||||||
|
qy = otherpoints[j + accumulateOffset];
|
||||||
|
bottom = 0;
|
||||||
|
|
||||||
|
if (px == qx) {
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints.push(points[i + m]);
|
||||||
|
|
||||||
|
newpoints[l + accumulateOffset] += qy;
|
||||||
|
bottom = qy;
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
j += otherps;
|
||||||
|
}
|
||||||
|
else if (px > qx) {
|
||||||
|
// we got past point below, might need to
|
||||||
|
// insert interpolated extra point
|
||||||
|
if (withlines && i > 0 && points[i - ps] != null) {
|
||||||
|
intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
|
||||||
|
newpoints.push(qx);
|
||||||
|
newpoints.push(intery + qy);
|
||||||
|
for (m = 2; m < ps; ++m)
|
||||||
|
newpoints.push(points[i + m]);
|
||||||
|
bottom = qy;
|
||||||
|
}
|
||||||
|
|
||||||
|
j += otherps;
|
||||||
|
}
|
||||||
|
else { // px < qx
|
||||||
|
if (fromgap && withlines) {
|
||||||
|
// if we come from a gap, we just skip this point
|
||||||
|
i += ps;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints.push(points[i + m]);
|
||||||
|
|
||||||
|
// we might be able to interpolate a point below,
|
||||||
|
// this can give us a better y
|
||||||
|
if (withlines && j > 0 && otherpoints[j - otherps] != null)
|
||||||
|
bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
|
||||||
|
|
||||||
|
newpoints[l + accumulateOffset] += bottom;
|
||||||
|
|
||||||
|
i += ps;
|
||||||
|
}
|
||||||
|
|
||||||
|
fromgap = false;
|
||||||
|
|
||||||
|
if (l != newpoints.length && withbottom)
|
||||||
|
newpoints[l + 2] += bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// maintain the line steps invariant
|
||||||
|
if (withsteps && l != newpoints.length && l > 0
|
||||||
|
&& newpoints[l] != null
|
||||||
|
&& newpoints[l] != newpoints[l - ps]
|
||||||
|
&& newpoints[l + 1] != newpoints[l - ps + 1]) {
|
||||||
|
for (m = 0; m < ps; ++m)
|
||||||
|
newpoints[l + ps + m] = newpoints[l + m];
|
||||||
|
newpoints[l + 1] = newpoints[l - ps + 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datapoints.points = newpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.processDatapoints.push(stackData);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'stack',
|
||||||
|
version: '1.2'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,71 @@
|
||||||
/*
|
/* Flot plugin that adds some extra symbols for plotting points.
|
||||||
Flot plugin that adds some extra symbols for plotting points.
|
|
||||||
|
|
||||||
The symbols are accessed as strings through the standard symbol
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
choice:
|
Licensed under the MIT license.
|
||||||
|
|
||||||
series: {
|
The symbols are accessed as strings through the standard symbol options:
|
||||||
points: {
|
|
||||||
symbol: "square" // or "diamond", "triangle", "cross"
|
series: {
|
||||||
}
|
points: {
|
||||||
}
|
symbol: "square" // or "diamond", "triangle", "cross"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
function processRawData(plot, series, datapoints) {
|
function processRawData(plot, series, datapoints) {
|
||||||
// we normalize the area of each symbol so it is approximately the
|
// we normalize the area of each symbol so it is approximately the
|
||||||
// same as a circle of the given radius
|
// same as a circle of the given radius
|
||||||
|
|
||||||
var handlers = {
|
var handlers = {
|
||||||
square: function (ctx, x, y, radius, shadow) {
|
square: function (ctx, x, y, radius, shadow) {
|
||||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
||||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
var size = radius * Math.sqrt(Math.PI) / 2;
|
||||||
ctx.rect(x - size, y - size, size + size, size + size);
|
ctx.rect(x - size, y - size, size + size, size + size);
|
||||||
},
|
},
|
||||||
diamond: function (ctx, x, y, radius, shadow) {
|
diamond: function (ctx, x, y, radius, shadow) {
|
||||||
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
|
// pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
|
||||||
var size = radius * Math.sqrt(Math.PI / 2);
|
var size = radius * Math.sqrt(Math.PI / 2);
|
||||||
ctx.moveTo(x - size, y);
|
ctx.moveTo(x - size, y);
|
||||||
ctx.lineTo(x, y - size);
|
ctx.lineTo(x, y - size);
|
||||||
ctx.lineTo(x + size, y);
|
ctx.lineTo(x + size, y);
|
||||||
ctx.lineTo(x, y + size);
|
ctx.lineTo(x, y + size);
|
||||||
ctx.lineTo(x - size, y);
|
ctx.lineTo(x - size, y);
|
||||||
},
|
},
|
||||||
triangle: function (ctx, x, y, radius, shadow) {
|
triangle: function (ctx, x, y, radius, shadow) {
|
||||||
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
|
// pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
|
||||||
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
|
var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
|
||||||
var height = size * Math.sin(Math.PI / 3);
|
var height = size * Math.sin(Math.PI / 3);
|
||||||
ctx.moveTo(x - size/2, y + height/2);
|
ctx.moveTo(x - size/2, y + height/2);
|
||||||
ctx.lineTo(x + size/2, y + height/2);
|
ctx.lineTo(x + size/2, y + height/2);
|
||||||
if (!shadow) {
|
if (!shadow) {
|
||||||
ctx.lineTo(x, y - height/2);
|
ctx.lineTo(x, y - height/2);
|
||||||
ctx.lineTo(x - size/2, y + height/2);
|
ctx.lineTo(x - size/2, y + height/2);
|
||||||
}
|
|
||||||
},
|
|
||||||
cross: function (ctx, x, y, radius, shadow) {
|
|
||||||
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
|
||||||
var size = radius * Math.sqrt(Math.PI) / 2;
|
|
||||||
ctx.moveTo(x - size, y - size);
|
|
||||||
ctx.lineTo(x + size, y + size);
|
|
||||||
ctx.moveTo(x - size, y + size);
|
|
||||||
ctx.lineTo(x + size, y - size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
cross: function (ctx, x, y, radius, shadow) {
|
||||||
|
// pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
|
||||||
|
var size = radius * Math.sqrt(Math.PI) / 2;
|
||||||
|
ctx.moveTo(x - size, y - size);
|
||||||
|
ctx.lineTo(x + size, y + size);
|
||||||
|
ctx.moveTo(x - size, y + size);
|
||||||
|
ctx.lineTo(x + size, y - size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
var s = series.points.symbol;
|
var s = series.points.symbol;
|
||||||
if (handlers[s])
|
if (handlers[s])
|
||||||
series.points.symbol = handlers[s];
|
series.points.symbol = handlers[s];
|
||||||
}
|
}
|
||||||
|
|
||||||
function init(plot) {
|
function init(plot) {
|
||||||
plot.hooks.processDatapoints.push(processRawData);
|
plot.hooks.processDatapoints.push(processRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
$.plot.plugins.push({
|
||||||
init: init,
|
init: init,
|
||||||
name: 'symbols',
|
name: 'symbols',
|
||||||
version: '1.0'
|
version: '1.0'
|
||||||
});
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
|
|
@ -1,103 +1,142 @@
|
||||||
/*
|
/* Flot plugin for thresholding data.
|
||||||
Flot plugin for thresholding data. Controlled through the option
|
|
||||||
"threshold" in either the global series options
|
|
||||||
|
|
||||||
series: {
|
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||||
threshold: {
|
Licensed under the MIT license.
|
||||||
below: number
|
|
||||||
color: colorspec
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
or in a specific series
|
The plugin supports these options:
|
||||||
|
|
||||||
$.plot($("#placeholder"), [{ data: [ ... ], threshold: { ... }}])
|
series: {
|
||||||
|
threshold: {
|
||||||
|
below: number
|
||||||
|
color: colorspec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
The data points below "below" are drawn with the specified color. This
|
It can also be applied to a single series, like this:
|
||||||
makes it easy to mark points below 0, e.g. for budget data.
|
|
||||||
|
$.plot( $("#placeholder"), [{
|
||||||
|
data: [ ... ],
|
||||||
|
threshold: { ... }
|
||||||
|
}])
|
||||||
|
|
||||||
|
An array can be passed for multiple thresholding, like this:
|
||||||
|
|
||||||
|
threshold: [{
|
||||||
|
below: number1
|
||||||
|
color: color1
|
||||||
|
},{
|
||||||
|
below: number2
|
||||||
|
color: color2
|
||||||
|
}]
|
||||||
|
|
||||||
|
These multiple threshold objects can be passed in any order since they are
|
||||||
|
sorted by the processing function.
|
||||||
|
|
||||||
|
The data points below "below" are drawn with the specified color. This makes
|
||||||
|
it easy to mark points below 0, e.g. for budget data.
|
||||||
|
|
||||||
|
Internally, the plugin works by splitting the data into two series, above and
|
||||||
|
below the threshold. The extra series below the threshold will have its label
|
||||||
|
cleared and the special "originSeries" attribute set to the original series.
|
||||||
|
You may need to check for this in hover events.
|
||||||
|
|
||||||
Internally, the plugin works by splitting the data into two series,
|
|
||||||
above and below the threshold. The extra series below the threshold
|
|
||||||
will have its label cleared and the special "originSeries" attribute
|
|
||||||
set to the original series. You may need to check for this in hover
|
|
||||||
events.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function ($) {
|
(function ($) {
|
||||||
var options = {
|
var options = {
|
||||||
series: { threshold: null } // or { below: number, color: color spec}
|
series: { threshold: null } // or { below: number, color: color spec}
|
||||||
};
|
};
|
||||||
|
|
||||||
function init(plot) {
|
|
||||||
function thresholdData(plot, s, datapoints) {
|
|
||||||
if (!s.threshold)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var ps = datapoints.pointsize, i, x, y, p, prevp,
|
|
||||||
thresholded = $.extend({}, s); // note: shallow copy
|
|
||||||
|
|
||||||
thresholded.datapoints = { points: [], pointsize: ps };
|
function init(plot) {
|
||||||
thresholded.label = null;
|
function thresholdData(plot, s, datapoints, below, color) {
|
||||||
thresholded.color = s.threshold.color;
|
var ps = datapoints.pointsize, i, x, y, p, prevp,
|
||||||
thresholded.threshold = null;
|
thresholded = $.extend({}, s); // note: shallow copy
|
||||||
thresholded.originSeries = s;
|
|
||||||
thresholded.data = [];
|
|
||||||
|
|
||||||
var below = s.threshold.below,
|
thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
|
||||||
origpoints = datapoints.points,
|
thresholded.label = null;
|
||||||
addCrossingPoints = s.lines.show;
|
thresholded.color = color;
|
||||||
|
thresholded.threshold = null;
|
||||||
|
thresholded.originSeries = s;
|
||||||
|
thresholded.data = [];
|
||||||
|
|
||||||
threspoints = [];
|
var origpoints = datapoints.points,
|
||||||
newpoints = [];
|
addCrossingPoints = s.lines.show;
|
||||||
|
|
||||||
for (i = 0; i < origpoints.length; i += ps) {
|
var threspoints = [];
|
||||||
x = origpoints[i]
|
var newpoints = [];
|
||||||
y = origpoints[i + 1];
|
var m;
|
||||||
|
|
||||||
prevp = p;
|
for (i = 0; i < origpoints.length; i += ps) {
|
||||||
if (y < below)
|
x = origpoints[i];
|
||||||
p = threspoints;
|
y = origpoints[i + 1];
|
||||||
else
|
|
||||||
p = newpoints;
|
|
||||||
|
|
||||||
if (addCrossingPoints && prevp != p && x != null
|
prevp = p;
|
||||||
&& i > 0 && origpoints[i - ps] != null) {
|
if (y < below)
|
||||||
var interx = (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]) * (below - y) + x;
|
p = threspoints;
|
||||||
prevp.push(interx);
|
else
|
||||||
prevp.push(below);
|
p = newpoints;
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
prevp.push(origpoints[i + m]);
|
|
||||||
|
|
||||||
p.push(null); // start new segment
|
|
||||||
p.push(null);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
p.push(origpoints[i + m]);
|
|
||||||
p.push(interx);
|
|
||||||
p.push(below);
|
|
||||||
for (m = 2; m < ps; ++m)
|
|
||||||
p.push(origpoints[i + m]);
|
|
||||||
}
|
|
||||||
|
|
||||||
p.push(x);
|
if (addCrossingPoints && prevp != p && x != null
|
||||||
p.push(y);
|
&& i > 0 && origpoints[i - ps] != null) {
|
||||||
}
|
var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
|
||||||
|
prevp.push(interx);
|
||||||
|
prevp.push(below);
|
||||||
|
for (m = 2; m < ps; ++m)
|
||||||
|
prevp.push(origpoints[i + m]);
|
||||||
|
|
||||||
datapoints.points = newpoints;
|
p.push(null); // start new segment
|
||||||
thresholded.datapoints.points = threspoints;
|
p.push(null);
|
||||||
|
for (m = 2; m < ps; ++m)
|
||||||
if (thresholded.datapoints.points.length > 0)
|
p.push(origpoints[i + m]);
|
||||||
plot.getData().push(thresholded);
|
p.push(interx);
|
||||||
|
p.push(below);
|
||||||
// FIXME: there are probably some edge cases left in bars
|
for (m = 2; m < ps; ++m)
|
||||||
|
p.push(origpoints[i + m]);
|
||||||
}
|
}
|
||||||
|
|
||||||
plot.hooks.processDatapoints.push(thresholdData);
|
p.push(x);
|
||||||
|
p.push(y);
|
||||||
|
for (m = 2; m < ps; ++m)
|
||||||
|
p.push(origpoints[i + m]);
|
||||||
|
}
|
||||||
|
|
||||||
|
datapoints.points = newpoints;
|
||||||
|
thresholded.datapoints.points = threspoints;
|
||||||
|
|
||||||
|
if (thresholded.datapoints.points.length > 0) {
|
||||||
|
var origIndex = $.inArray(s, plot.getData());
|
||||||
|
// Insert newly-generated series right after original one (to prevent it from becoming top-most)
|
||||||
|
plot.getData().splice(origIndex + 1, 0, thresholded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: there are probably some edge cases left in bars
|
||||||
}
|
}
|
||||||
|
|
||||||
$.plot.plugins.push({
|
function processThresholds(plot, s, datapoints) {
|
||||||
init: init,
|
if (!s.threshold)
|
||||||
options: options,
|
return;
|
||||||
name: 'threshold',
|
|
||||||
version: '1.0'
|
if (s.threshold instanceof Array) {
|
||||||
});
|
s.threshold.sort(function(a, b) {
|
||||||
|
return a.below - b.below;
|
||||||
|
});
|
||||||
|
|
||||||
|
$(s.threshold).each(function(i, th) {
|
||||||
|
thresholdData(plot, s, datapoints, th.below, th.color);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
plot.hooks.processDatapoints.push(processThresholds);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.plot.plugins.push({
|
||||||
|
init: init,
|
||||||
|
options: options,
|
||||||
|
name: 'threshold',
|
||||||
|
version: '1.2'
|
||||||
|
});
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -384,7 +384,7 @@
|
||||||
args.complete($chart);
|
args.complete($chart);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($chart.find('.connector-line.highlighted').size()) {
|
if ($chart.find('.connector-line.highlighted').length) {
|
||||||
$info.appendTo($chart).append(
|
$info.appendTo($chart).append(
|
||||||
$('<span>').addClass('color-key'),
|
$('<span>').addClass('color-key'),
|
||||||
$('<span>').html('= Contains a public network')
|
$('<span>').html('= Contains a public network')
|
||||||
|
|
|
||||||
|
|
@ -450,10 +450,10 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logout action
|
// Logout action
|
||||||
$('#user-options a').live('click', function() {
|
$(document).on('click', '#user-options a', function() {
|
||||||
loginArgs.logoutAction({
|
loginArgs.logoutAction({
|
||||||
context: cloudStack.context
|
context: cloudStack.context
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window._reloadUI = function() {
|
window._reloadUI = function() {
|
||||||
|
|
|
||||||
|
|
@ -2445,7 +2445,7 @@
|
||||||
var $tierSelect = $(".ui-dialog-content").find('.tier-select select');
|
var $tierSelect = $(".ui-dialog-content").find('.tier-select select');
|
||||||
|
|
||||||
// if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later
|
// if $tierSelect is not initialized, return; tierSelect() will refresh listView and come back here later
|
||||||
if ($tierSelect.size() == 0) {
|
if ($tierSelect.length == 0) {
|
||||||
args.response.success({
|
args.response.success({
|
||||||
data: null
|
data: null
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -761,7 +761,7 @@ var addGuestNetworkDialog = {
|
||||||
} else { //domain-specific
|
} else { //domain-specific
|
||||||
array1.push("&acltype=domain");
|
array1.push("&acltype=domain");
|
||||||
|
|
||||||
if ($form.find('.form-item[rel=subdomainaccess]:visible input:checked').size())
|
if ($form.find('.form-item[rel=subdomainaccess]:visible input:checked').length)
|
||||||
array1.push("&subdomainaccess=true");
|
array1.push("&subdomainaccess=true");
|
||||||
else
|
else
|
||||||
array1.push("&subdomainaccess=false");
|
array1.push("&subdomainaccess=false");
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@
|
||||||
|
|
||||||
$wizard.click(function(event) {
|
$wizard.click(function(event) {
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
if ($target.closest('button.next').size()) {
|
if ($target.closest('button.next').length) {
|
||||||
$form.validate();
|
$form.validate();
|
||||||
if ($form.valid()) {
|
if ($form.valid()) {
|
||||||
completeAction();
|
completeAction();
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($target.closest('button.cancel').size()) {
|
if ($target.closest('button.cancel').length) {
|
||||||
close();
|
close();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -112,14 +112,14 @@
|
||||||
|
|
||||||
if (ldapStatus) {
|
if (ldapStatus) {
|
||||||
var $table = $wizard.find('.ldap-account-choice tbody');
|
var $table = $wizard.find('.ldap-account-choice tbody');
|
||||||
$("#label_ldap_group_name").live("keypress", function(event) {
|
$("#label_ldap_group_name").on("keypress", function(event) {
|
||||||
if ($table.find("#tr-groupname-message").length === 0) {
|
if ($table.find("#tr-groupname-message").length === 0) {
|
||||||
$("<tr id='tr-groupname-message'>").appendTo($table).append("<td colspan=\"4\">"+_l('message.ldap.group.import')+"</td>");
|
$("<tr id='tr-groupname-message'>").appendTo($table).append("<td colspan=\"4\">"+_l('message.ldap.group.import')+"</td>");
|
||||||
}
|
}
|
||||||
$table.find("tr").hide();
|
$table.find("tr").hide();
|
||||||
$table.find("#tr-groupname-message").show();
|
$table.find("#tr-groupname-message").show();
|
||||||
});
|
});
|
||||||
$("#label_ldap_group_name").live("blur", function(event) {
|
$("#label_ldap_group_name").on("blur", function(event) {
|
||||||
if (!$(this).val()) {
|
if (!$(this).val()) {
|
||||||
$table.find("tr").show();
|
$table.find("tr").show();
|
||||||
$table.find("#tr-groupname-message").hide();
|
$table.find("#tr-groupname-message").hide();
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@
|
||||||
|
|
||||||
if (!$dataList.find(
|
if (!$dataList.find(
|
||||||
'input[type=radio]:checked, input[type=checkbox]:checked'
|
'input[type=radio]:checked, input[type=checkbox]:checked'
|
||||||
).size()) {
|
).length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: _l('message.select.instance')
|
message: _l('message.select.instance')
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,12 @@
|
||||||
data['new-network-ip'] = $form.find('.new-network .select.advanced .specify-ip input[type=text]').val();
|
data['new-network-ip'] = $form.find('.new-network .select.advanced .specify-ip input[type=text]').val();
|
||||||
|
|
||||||
// Handle multi-disk service offerings
|
// Handle multi-disk service offerings
|
||||||
if ($form.find('.multi-disk-select-container').size()) {
|
if ($form.find('.multi-disk-select-container').length) {
|
||||||
data['disk-offerings-multi'] = [];
|
data['disk-offerings-multi'] = [];
|
||||||
|
|
||||||
var $diskGroups = $form.find('.disk-select-group');
|
var $diskGroups = $form.find('.disk-select-group');
|
||||||
var $selectedDisks = $.grep($diskGroups, function (diskGroup) {
|
var $selectedDisks = $.grep($diskGroups, function (diskGroup) {
|
||||||
return $(diskGroup).find('input[type=checkbox]:checked').size();
|
return $(diskGroup).find('input[type=checkbox]:checked').length;
|
||||||
});
|
});
|
||||||
|
|
||||||
$selectedDisks.map(function (disk) {
|
$selectedDisks.map(function (disk) {
|
||||||
|
|
@ -86,7 +86,7 @@
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
var $listView = $('.list-view.instances');
|
var $listView = $('.list-view.instances');
|
||||||
|
|
||||||
if ($listView.size()) {
|
if ($listView.length) {
|
||||||
var $loading = $('.list-view.instances').listView('prependItem', {
|
var $loading = $('.list-view.instances').listView('prependItem', {
|
||||||
data: [{
|
data: [{
|
||||||
name: data.displayname ? data.displayname : _l('label.new.vm'),
|
name: data.displayname ? data.displayname : _l('label.new.vm'),
|
||||||
|
|
@ -104,7 +104,7 @@
|
||||||
listViewArgs.complete({
|
listViewArgs.complete({
|
||||||
_custom: args._custom,
|
_custom: args._custom,
|
||||||
messageArgs: cloudStack.serializeForm($form),
|
messageArgs: cloudStack.serializeForm($form),
|
||||||
$item: $listView.size() ? $loading : $('<div>')
|
$item: $listView.length ? $loading : $('<div>')
|
||||||
});
|
});
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
@ -158,17 +158,17 @@
|
||||||
|
|
||||||
var $checkedOtherSelect = $otherSelects.filter(function() {
|
var $checkedOtherSelect = $otherSelects.filter(function() {
|
||||||
return $(this).not('.single-select') &&
|
return $(this).not('.single-select') &&
|
||||||
$(this).find('input[type=checkbox]:checked').size() &&
|
$(this).find('input[type=checkbox]:checked').length &&
|
||||||
$(this).find('input[type=radio]:checked').size();
|
$(this).find('input[type=radio]:checked').length;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!$checkedOtherSelect.size() &&
|
if (!$checkedOtherSelect.length &&
|
||||||
!$('.new-network:visible input[type=radio]:checked').size()) {
|
!$('.new-network:visible input[type=radio]:checked').length) {
|
||||||
$(this).closest('.select').find('input[type=radio]').click();
|
$(this).closest('.select').find('input[type=radio]').click();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!$otherSelects.size()) &&
|
if ((!$otherSelects.length) &&
|
||||||
$newNetwork.find('input[type=checkbox]').is(':unchecked')) {
|
$newNetwork.find('input[type=checkbox]').is(':unchecked')) {
|
||||||
// Set as default
|
// Set as default
|
||||||
$(this).closest('.select').find('input[type=radio]').click();
|
$(this).closest('.select').find('input[type=radio]').click();
|
||||||
|
|
@ -268,10 +268,9 @@
|
||||||
|
|
||||||
var dataGenerators = {
|
var dataGenerators = {
|
||||||
setup: function($step, formData) {
|
setup: function($step, formData) {
|
||||||
var originalValues = function(formData) {
|
var originalValues = function(formData, initialValue) {
|
||||||
$step.find('select').val(
|
var selectedValue = formData.zoneid || initialValue;
|
||||||
formData.zoneid
|
$step.find('select').val(selectedValue);
|
||||||
);
|
|
||||||
|
|
||||||
$step.find('input[type=radio]').filter(function() {
|
$step.find('input[type=radio]').filter(function() {
|
||||||
return $(this).val() == formData['select-template'];
|
return $(this).val() == formData['select-template'];
|
||||||
|
|
@ -282,7 +281,11 @@
|
||||||
response: {
|
response: {
|
||||||
success: function(args) {
|
success: function(args) {
|
||||||
// Zones
|
// Zones
|
||||||
$(args.data.zones).each(function() {
|
var initialValue = '';
|
||||||
|
$(args.data.zones).each(function( index ) {
|
||||||
|
if(index == 0){
|
||||||
|
initialValue = this.id;
|
||||||
|
}
|
||||||
$step.find('.select-zone select').append(
|
$step.find('.select-zone select').append(
|
||||||
$('<option>')
|
$('<option>')
|
||||||
.attr({
|
.attr({
|
||||||
|
|
@ -293,7 +296,7 @@
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
originalValues(formData);
|
originalValues(formData, initialValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -309,7 +312,7 @@
|
||||||
return $(this).val() == formData.templateid;
|
return $(this).val() == formData.templateid;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!$selected.size()) {
|
if (!$selected.length) {
|
||||||
$inputs.filter(':first').click();
|
$inputs.filter(':first').click();
|
||||||
} else {
|
} else {
|
||||||
$selected.click();
|
$selected.click();
|
||||||
|
|
@ -541,7 +544,7 @@
|
||||||
return $(this).val() == formData.diskofferingid;
|
return $(this).val() == formData.diskofferingid;
|
||||||
}).click();
|
}).click();
|
||||||
|
|
||||||
if (!$targetInput.size()) {
|
if (!$targetInput.length) {
|
||||||
$step.find('input[type=radio]:visible').filter(':first').click();
|
$step.find('input[type=radio]:visible').filter(':first').click();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -620,7 +623,7 @@
|
||||||
$group.toggleClass('selected');
|
$group.toggleClass('selected');
|
||||||
$group.find('.select:first input[type=radio]').click();
|
$group.find('.select:first input[type=radio]').click();
|
||||||
|
|
||||||
if (!$multiDiskSelect.find('input[type=checkbox]:checked').size()) {
|
if (!$multiDiskSelect.find('input[type=checkbox]:checked').length) {
|
||||||
$step.find('.no-thanks input[type=radio]').click();
|
$step.find('.no-thanks input[type=radio]').click();
|
||||||
} else {
|
} else {
|
||||||
$step.find('.no-thanks input[type=radio]').attr('checked', false);
|
$step.find('.no-thanks input[type=radio]').attr('checked', false);
|
||||||
|
|
@ -655,10 +658,10 @@
|
||||||
var item = $.grep(args.data.diskOfferings, function(elem) {
|
var item = $.grep(args.data.diskOfferings, function(elem) {
|
||||||
return elem.id == val;
|
return elem.id == val;
|
||||||
})[0];
|
})[0];
|
||||||
var isMultiDisk = $step.find('.multi-disk-select').size();
|
var isMultiDisk = $step.find('.multi-disk-select').length;
|
||||||
|
|
||||||
// Uncheck any multi-select groups
|
// Uncheck any multi-select groups
|
||||||
if ($target.closest('.no-thanks').size() && isMultiDisk) {
|
if ($target.closest('.no-thanks').length && isMultiDisk) {
|
||||||
$step.find('.disk-select-group input[type=checkbox]:checked').click();
|
$step.find('.disk-select-group input[type=checkbox]:checked').click();
|
||||||
$(this).attr('checked', true);
|
$(this).attr('checked', true);
|
||||||
|
|
||||||
|
|
@ -881,7 +884,7 @@
|
||||||
var $checkbox = $step.find('.new-network input[type=checkbox]');
|
var $checkbox = $step.find('.new-network input[type=checkbox]');
|
||||||
var $newNetwork = $checkbox.closest('.new-network');
|
var $newNetwork = $checkbox.closest('.new-network');
|
||||||
|
|
||||||
if ($step.find('.select.my-networks .select-container .select:visible').size()) {
|
if ($step.find('.select.my-networks .select-container .select:visible').length) {
|
||||||
$checkbox.attr('checked', false);
|
$checkbox.attr('checked', false);
|
||||||
$newNetwork.addClass('unselected');
|
$newNetwork.addClass('unselected');
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1023,7 +1026,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
if ($select.closest('.new-network').size()) {
|
if ($select.closest('.new-network').length) {
|
||||||
$select.find('.advanced-options, .specify-ip').remove();
|
$select.find('.advanced-options, .specify-ip').remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1077,10 +1080,10 @@
|
||||||
fieldName = $input.html();
|
fieldName = $input.html();
|
||||||
} else if ($input.is('input[type=radio]')) {
|
} else if ($input.is('input[type=radio]')) {
|
||||||
// Choosen New network as default
|
// Choosen New network as default
|
||||||
if ($input.parents('div.new-network').size()) {
|
if ($input.parents('div.new-network').length) {
|
||||||
fieldName = $input.closest('div.new-network').find('input[name="new-network-name"]').val();
|
fieldName = $input.closest('div.new-network').find('input[name="new-network-name"]').val();
|
||||||
// Choosen Network from existed
|
// Choosen Network from existed
|
||||||
} else if ($input.parents('div.my-networks').size()) {
|
} else if ($input.parents('div.my-networks').length) {
|
||||||
fieldName = $input.closest('div.select').find('.select-desc .name').html();
|
fieldName = $input.closest('div.select').find('.select-desc .name').html();
|
||||||
} else {
|
} else {
|
||||||
fieldName = $input.parent().find('.select-desc .name').html();
|
fieldName = $input.parent().find('.select-desc .name').html();
|
||||||
|
|
@ -1124,7 +1127,7 @@
|
||||||
var targetIndex = index - 1;
|
var targetIndex = index - 1;
|
||||||
|
|
||||||
if (index <= 1) targetIndex = 0;
|
if (index <= 1) targetIndex = 0;
|
||||||
if (targetIndex == $steps.size()) {
|
if (targetIndex == $steps.length) {
|
||||||
completeAction();
|
completeAction();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -1182,7 +1185,7 @@
|
||||||
}).fadeOut('slow');
|
}).fadeOut('slow');
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!$targetStep.find('input[type=radio]:checked').size()) {
|
if (!$targetStep.find('input[type=radio]:checked').length) {
|
||||||
$targetStep.find('input[type=radio]:first').click();
|
$targetStep.find('input[type=radio]:first').click();
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
@ -1194,10 +1197,10 @@
|
||||||
var $activeStep = $form.find('.step:visible');
|
var $activeStep = $form.find('.step:visible');
|
||||||
|
|
||||||
// Next button
|
// Next button
|
||||||
if ($target.closest('div.button.next').size()) {
|
if ($target.closest('div.button.next').length) {
|
||||||
//step 2 - select template/ISO
|
//step 2 - select template/ISO
|
||||||
if($activeStep.hasClass('select-iso')) {
|
if($activeStep.hasClass('select-iso')) {
|
||||||
if ($activeStep.find('.content:visible input:checked').size() == 0) {
|
if ($activeStep.find('.content:visible input:checked').length == 0) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: 'message.step.1.continue'
|
message: 'message.step.1.continue'
|
||||||
});
|
});
|
||||||
|
|
@ -1210,7 +1213,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
//step 6 - select network
|
//step 6 - select network
|
||||||
if ($activeStep.find('.wizard-step-conditional.select-network:visible').size() > 0) {
|
if ($activeStep.find('.wizard-step-conditional.select-network:visible').length > 0) {
|
||||||
var data = $activeStep.data('my-networks');
|
var data = $activeStep.data('my-networks');
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
|
@ -1219,7 +1222,7 @@
|
||||||
)['my-networks']);
|
)['my-networks']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($activeStep.find('input[type=checkbox]:checked').size() == 0) { //if no checkbox is checked
|
if ($activeStep.find('input[type=checkbox]:checked').length == 0) { //if no checkbox is checked
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: 'message.step.4.continue'
|
message: 'message.step.4.continue'
|
||||||
});
|
});
|
||||||
|
|
@ -1234,7 +1237,7 @@
|
||||||
if (advSGFilter == 0) { //when total number of selected sg networks is 0, then 'Select Security Group' is skipped, go to step 6 directly
|
if (advSGFilter == 0) { //when total number of selected sg networks is 0, then 'Select Security Group' is skipped, go to step 6 directly
|
||||||
showStep(6);
|
showStep(6);
|
||||||
} else { //when total number of selected sg networks > 0
|
} else { //when total number of selected sg networks > 0
|
||||||
if ($activeStep.find('input[type=checkbox]:checked').size() > 1) { //when total number of selected networks > 1
|
if ($activeStep.find('input[type=checkbox]:checked').length > 1) { //when total number of selected networks > 1
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: "Can't create a vm with multiple networks one of which is Security Group enabled"
|
message: "Can't create a vm with multiple networks one of which is Security Group enabled"
|
||||||
});
|
});
|
||||||
|
|
@ -1246,7 +1249,7 @@
|
||||||
|
|
||||||
//step 6 - review (spcifiy displyname, group as well)
|
//step 6 - review (spcifiy displyname, group as well)
|
||||||
if ($activeStep.hasClass('review')) {
|
if ($activeStep.hasClass('review')) {
|
||||||
if ($activeStep.find('input[name=displayname]').size() > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
|
if ($activeStep.find('input[name=displayname]').length > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
|
||||||
//validate
|
//validate
|
||||||
var b = cloudStack.validate.vmHostName($activeStep.find('input[name=displayname]').val());
|
var b = cloudStack.validate.vmHostName($activeStep.find('input[name=displayname]').val());
|
||||||
if (b == false)
|
if (b == false)
|
||||||
|
|
@ -1255,7 +1258,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$form.valid()) {
|
if (!$form.valid()) {
|
||||||
if ($form.find('input.error:visible, select.error:visible').size()) {
|
if ($form.find('input.error:visible, select.error:visible').length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1270,7 +1273,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Previous button
|
// Previous button
|
||||||
if ($target.closest('div.button.previous').size()) {
|
if ($target.closest('div.button.previous').length) {
|
||||||
var $step = $steps.filter(':visible');
|
var $step = $steps.filter(':visible');
|
||||||
var $networkStep = $steps.filter('.network');
|
var $networkStep = $steps.filter('.network');
|
||||||
var index = $step.index();
|
var index = $step.index();
|
||||||
|
|
@ -1278,10 +1281,10 @@
|
||||||
$networkStep.removeClass('next-use-security-groups');
|
$networkStep.removeClass('next-use-security-groups');
|
||||||
|
|
||||||
if (index) {
|
if (index) {
|
||||||
if (index == $steps.size() - 1 && $networkStep.hasClass('next-use-security-groups')) {
|
if (index == $steps.length - 1 && $networkStep.hasClass('next-use-security-groups')) {
|
||||||
showStep(5);
|
showStep(5);
|
||||||
} else if ($activeStep.find('.select-security-group:visible').size() &&
|
} else if ($activeStep.find('.select-security-group:visible').length &&
|
||||||
$activeStep.find('.select-network.no-add-network').size()) {
|
$activeStep.find('.select-network.no-add-network').length) {
|
||||||
showStep(5);
|
showStep(5);
|
||||||
} else {
|
} else {
|
||||||
showStep(index);
|
showStep(index);
|
||||||
|
|
@ -1292,14 +1295,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close button
|
// Close button
|
||||||
if ($target.closest('div.button.cancel').size()) {
|
if ($target.closest('div.button.cancel').length) {
|
||||||
close();
|
close();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edit link
|
// Edit link
|
||||||
if ($target.closest('div.edit').size()) {
|
if ($target.closest('div.edit').length) {
|
||||||
var $edit = $target.closest('div.edit');
|
var $edit = $target.closest('div.edit');
|
||||||
|
|
||||||
showStep($edit.find('a').attr('href'));
|
showStep($edit.find('a').attr('href'));
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
return $dashboard
|
return $dashboard
|
||||||
.click(function(event) {
|
.click(function(event) {
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
if ($target.closest('[view-all-target]').size()) {
|
if ($target.closest('[view-all-target]').length) {
|
||||||
var targetID = $target.closest('[view-all-target]').attr('view-all-target');
|
var targetID = $target.closest('[view-all-target]').attr('view-all-target');
|
||||||
args.$browser.cloudBrowser('addPanel', {
|
args.$browser.cloudBrowser('addPanel', {
|
||||||
title: $target.closest('[view-all-title]').attr('view-all-title'),
|
title: $target.closest('[view-all-title]').attr('view-all-title'),
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
$plugin.click(function() {
|
$plugin.click(function() {
|
||||||
var $mainSection = $('#navigation ul li').filter('.' + plugin.id);
|
var $mainSection = $('#navigation ul li').filter('.' + plugin.id);
|
||||||
|
|
||||||
if ($mainSection.size()) {
|
if ($mainSection.length) {
|
||||||
$mainSection.click();
|
$mainSection.click();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -275,7 +275,7 @@
|
||||||
var $management = $panel.find('.management');
|
var $management = $panel.find('.management');
|
||||||
var $managementInvite = $panel.find('.management-invite');
|
var $managementInvite = $panel.find('.management-invite');
|
||||||
|
|
||||||
if ($management.size()) {
|
if ($management.length) {
|
||||||
$management.children().remove();
|
$management.children().remove();
|
||||||
$management.append(pageElems.userManagement({
|
$management.append(pageElems.userManagement({
|
||||||
context: cloudStack.context
|
context: cloudStack.context
|
||||||
|
|
@ -284,7 +284,7 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($managementInvite.size()) {
|
if ($managementInvite.length) {
|
||||||
$managementInvite.children().remove();
|
$managementInvite.children().remove();
|
||||||
$managementInvite.append(pageElems.userManagement({
|
$managementInvite.append(pageElems.userManagement({
|
||||||
context: cloudStack.context,
|
context: cloudStack.context,
|
||||||
|
|
@ -635,7 +635,7 @@
|
||||||
|
|
||||||
// Initial load
|
// Initial load
|
||||||
loadData(function() {
|
loadData(function() {
|
||||||
if (!$list.find('li').size()) {
|
if (!$list.find('li').length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: isAdmin() || isDomainAdmin() || g_userProjectsEnabled ? _l('message.no.projects') : _l('message.no.projects.adminOnly')
|
message: isAdmin() || isDomainAdmin() || g_userProjectsEnabled ? _l('message.no.projects') : _l('message.no.projects.adminOnly')
|
||||||
}).closest('.ui-dialog');
|
}).closest('.ui-dialog');
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@
|
||||||
return $(this).index() == index;
|
return $(this).index() == index;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($tr.size() && $tr.hasClass('active')) {
|
if ($tr.length && $tr.hasClass('active')) {
|
||||||
$(this).addClass('disabled ui-state-disabled');
|
$(this).addClass('disabled ui-state-disabled');
|
||||||
} else {
|
} else {
|
||||||
$(this).removeClass('disabled ui-state-disabled');
|
$(this).removeClass('disabled ui-state-disabled');
|
||||||
|
|
@ -126,7 +126,7 @@
|
||||||
if ($(this).is('.ui-tabs-selected.ui-state-disabled')) {
|
if ($(this).is('.ui-tabs-selected.ui-state-disabled')) {
|
||||||
$snapshots.find('form').show();
|
$snapshots.find('form').show();
|
||||||
|
|
||||||
if ($snapshots.find('li.ui-state-disabled').size() == $snapshots.find('li').size()) {
|
if ($snapshots.find('li.ui-state-disabled').length == $snapshots.find('li').length) {
|
||||||
$snapshots.find('form').hide();
|
$snapshots.find('form').hide();
|
||||||
} else {
|
} else {
|
||||||
$snapshots.find('li:not(.ui-state-disabled):first a').click();
|
$snapshots.find('li:not(.ui-state-disabled):first a').click();
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@
|
||||||
var $li = $target.closest('li');
|
var $li = $target.closest('li');
|
||||||
var region, url;
|
var region, url;
|
||||||
|
|
||||||
if ($li.size() && !$li.hasClass('active')) {
|
if ($li.length && !$li.hasClass('active')) {
|
||||||
region = $li.data('region-data');
|
region = $li.data('region-data');
|
||||||
url = region.endpoint;
|
url = region.endpoint;
|
||||||
id = region.id;
|
id = region.id;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
if (!$uploadVolume.find(
|
if (!$uploadVolume.find(
|
||||||
'input[type=radio]:checked, input[type=checkbox]:checked'
|
'input[type=radio]:checked, input[type=checkbox]:checked'
|
||||||
).size()) {
|
).length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: _l('message.select.instance')
|
message: _l('message.select.instance')
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -409,7 +409,7 @@
|
||||||
|
|
||||||
// Title shows tier details
|
// Title shows tier details
|
||||||
$title.click(function() {
|
$title.click(function() {
|
||||||
if ($browser && $browser.size()) { // Fix null exception, if add tier returns error
|
if ($browser && $browser.length) { // Fix null exception, if add tier returns error
|
||||||
$browser.cloudBrowser('addPanel', {
|
$browser.cloudBrowser('addPanel', {
|
||||||
title: name,
|
title: name,
|
||||||
maximizeIfSelected: true,
|
maximizeIfSelected: true,
|
||||||
|
|
@ -545,7 +545,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
var showAddTierDialog = function() {
|
var showAddTierDialog = function() {
|
||||||
if ($(this).find('.loading-overlay').size()) {
|
if ($(this).find('.loading-overlay').length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
var $forms = $wizard.find('form').filter(function() {
|
var $forms = $wizard.find('form').filter(function() {
|
||||||
return !options.all ? !$(this).closest('.multi-edit').size() : true;
|
return !options.all ? !$(this).closest('.multi-edit').length : true;
|
||||||
});
|
});
|
||||||
var $physicalNetworkItems = $wizard.find(
|
var $physicalNetworkItems = $wizard.find(
|
||||||
'.steps .setup-physical-network .select-container.multi'
|
'.steps .setup-physical-network .select-container.multi'
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
'.steps .setup-storage-traffic .data-body .data-item');
|
'.steps .setup-storage-traffic .data-body .data-item');
|
||||||
var groupedForms = {};
|
var groupedForms = {};
|
||||||
|
|
||||||
if ($physicalNetworkItems.find('li.traffic-type-draggable.storage').size()) {
|
if ($physicalNetworkItems.find('li.traffic-type-draggable.storage').length) {
|
||||||
$wizard.find('li.conditional.storage-traffic').show();
|
$wizard.find('li.conditional.storage-traffic').show();
|
||||||
} else {
|
} else {
|
||||||
$wizard.find('li.conditional.storage-traffic').hide();
|
$wizard.find('li.conditional.storage-traffic').hide();
|
||||||
|
|
@ -93,7 +93,7 @@
|
||||||
// Traffic type configuration data
|
// Traffic type configuration data
|
||||||
trafficTypeConfiguration: trafficTypeConfiguration,
|
trafficTypeConfiguration: trafficTypeConfiguration,
|
||||||
|
|
||||||
guestConfiguration: $guestForm.size() ? cloudStack.serializeForm($guestForm) : null
|
guestConfiguration: $guestForm.length ? cloudStack.serializeForm($guestForm) : null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -172,7 +172,7 @@
|
||||||
*/
|
*/
|
||||||
var customValidation = {
|
var customValidation = {
|
||||||
networkRanges: function($form) {
|
networkRanges: function($form) {
|
||||||
if ($form.closest('.multi-edit').find('.data-item').size()) {
|
if ($form.closest('.multi-edit').find('.data-item').length) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +184,7 @@
|
||||||
|
|
||||||
physicalNetworks: function($form) {
|
physicalNetworks: function($form) {
|
||||||
var $enabledPhysicalNetworks = $form.filter(':not(.disabled)').filter(function() {
|
var $enabledPhysicalNetworks = $form.filter(':not(.disabled)').filter(function() {
|
||||||
return $(this).find('.traffic-type-draggable').size();
|
return $(this).find('.traffic-type-draggable').length;
|
||||||
});
|
});
|
||||||
var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
|
var $trafficTypes = $enabledPhysicalNetworks.find('.traffic-type-draggable');
|
||||||
var $configuredTrafficTypes = $trafficTypes.filter(function() {
|
var $configuredTrafficTypes = $trafficTypes.filter(function() {
|
||||||
|
|
@ -193,8 +193,8 @@
|
||||||
return ($trafficType.data('traffic-type-data') != null);
|
return ($trafficType.data('traffic-type-data') != null);
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($enabledPhysicalNetworks.size() > 1 &&
|
if ($enabledPhysicalNetworks.length > 1 &&
|
||||||
$configuredTrafficTypes.size() != $trafficTypes.size()) {
|
$configuredTrafficTypes.length != $trafficTypes.length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: _l('message.configure.all.traffic.types')
|
message: _l('message.configure.all.traffic.types')
|
||||||
});
|
});
|
||||||
|
|
@ -215,9 +215,9 @@
|
||||||
var $physicalNetworks = $step.find('.select-container.multi');
|
var $physicalNetworks = $step.find('.select-container.multi');
|
||||||
var isCustomValidated;
|
var isCustomValidated;
|
||||||
|
|
||||||
if ($multiEditForm.size()) {
|
if ($multiEditForm.length) {
|
||||||
isCustomValidated = customValidation.networkRanges($multiEditForm);
|
isCustomValidated = customValidation.networkRanges($multiEditForm);
|
||||||
} else if ($physicalNetworks.size()) {
|
} else if ($physicalNetworks.length) {
|
||||||
isCustomValidated = customValidation.physicalNetworks($physicalNetworks);
|
isCustomValidated = customValidation.physicalNetworks($physicalNetworks);
|
||||||
} else {
|
} else {
|
||||||
isCustomValidated = true;
|
isCustomValidated = true;
|
||||||
|
|
@ -240,7 +240,7 @@
|
||||||
var $existingPhysicalNetworks = physicalNetwork.getNetworks($wizard);
|
var $existingPhysicalNetworks = physicalNetwork.getNetworks($wizard);
|
||||||
|
|
||||||
// Initialize physical networks
|
// Initialize physical networks
|
||||||
if (!$existingPhysicalNetworks.size()) {
|
if (!$existingPhysicalNetworks.length) {
|
||||||
physicalNetwork.add($wizard);
|
physicalNetwork.add($wizard);
|
||||||
} else if (!isAdvancedNetwork($wizard)) {
|
} else if (!isAdvancedNetwork($wizard)) {
|
||||||
$existingPhysicalNetworks.filter(':first').siblings().each(function() {
|
$existingPhysicalNetworks.filter(':first').siblings().each(function() {
|
||||||
|
|
@ -459,12 +459,12 @@
|
||||||
return $(this).attr('traffic-type-id') == trafficTypeID;
|
return $(this).attr('traffic-type-id') == trafficTypeID;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (physicalNetwork.isTrafficTypeClone($trafficType) && !$container.closest('.select-container.multi').size()) {
|
if (physicalNetwork.isTrafficTypeClone($trafficType) && !$container.closest('.select-container.multi').length) {
|
||||||
// Get traffic type from original container
|
// Get traffic type from original container
|
||||||
return $trafficType.filter(function() {
|
return $trafficType.filter(function() {
|
||||||
return $(this).closest(
|
return $(this).closest(
|
||||||
physicalNetwork.getOriginalTrafficContainer($trafficType)
|
physicalNetwork.getOriginalTrafficContainer($trafficType)
|
||||||
).size();
|
).length;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -516,10 +516,10 @@
|
||||||
var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
|
var $trafficType = physicalNetwork.getTrafficType(trafficTypeID, $container);
|
||||||
var $dropArea = $physicalNetwork.find('.drop-container ul');
|
var $dropArea = $physicalNetwork.find('.drop-container ul');
|
||||||
|
|
||||||
if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size()) return false;
|
if ($physicalNetwork.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length) return false;
|
||||||
|
|
||||||
if (physicalNetwork.isTrafficTypeClone($trafficType)) {
|
if (physicalNetwork.isTrafficTypeClone($trafficType)) {
|
||||||
if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).size()) {
|
if (!physicalNetwork.getTrafficType(trafficTypeID, $physicalNetwork).length) {
|
||||||
$trafficType = $trafficType.clone()
|
$trafficType = $trafficType.clone()
|
||||||
.removeClass('disabled')
|
.removeClass('disabled')
|
||||||
.appendTo($dropArea)
|
.appendTo($dropArea)
|
||||||
|
|
@ -563,7 +563,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
if (physicalNetwork.isTrafficTypeClone($trafficType) &&
|
if (physicalNetwork.isTrafficTypeClone($trafficType) &&
|
||||||
$physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').size() > 1) {
|
$physicalNetworks.find('.traffic-type-draggable[traffic-type-id=' + trafficTypeID + ']').length > 1) {
|
||||||
$trafficType.remove();
|
$trafficType.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -580,10 +580,10 @@
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var $emptyContainers = $containers.filter(function() {
|
var $emptyContainers = $containers.filter(function() {
|
||||||
return !$(this).find('li').size();
|
return !$(this).find('li').length;
|
||||||
});
|
});
|
||||||
|
|
||||||
return !$emptyContainers.size() ? $containers.size() : false;
|
return !$emptyContainers.length ? $containers.length : false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -598,7 +598,7 @@
|
||||||
$allPhysicalNetworks.each(function() {
|
$allPhysicalNetworks.each(function() {
|
||||||
var $ul = $(this).find('.drop-container ul');
|
var $ul = $(this).find('.drop-container ul');
|
||||||
|
|
||||||
if (!$(this).find('li').size()) {
|
if (!$(this).find('li').length) {
|
||||||
$(this).addClass('disabled');
|
$(this).addClass('disabled');
|
||||||
$ul.fadeOut();
|
$ul.fadeOut();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -609,8 +609,8 @@
|
||||||
|
|
||||||
$containers.each(function() {
|
$containers.each(function() {
|
||||||
var $currentContainer = $(this);
|
var $currentContainer = $(this);
|
||||||
if (!$currentContainer.find('li').size() &&
|
if (!$currentContainer.find('li').length &&
|
||||||
$containers.size() > containerTotal) {
|
$containers.length > containerTotal) {
|
||||||
$currentContainer.remove();
|
$currentContainer.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -753,7 +753,7 @@
|
||||||
|
|
||||||
$ul.addClass('active');
|
$ul.addClass('active');
|
||||||
|
|
||||||
if (!$ul.find('li').size()) {
|
if (!$ul.find('li').length) {
|
||||||
$(this).closest('.select-container.multi').removeClass('disabled');
|
$(this).closest('.select-container.multi').removeClass('disabled');
|
||||||
$ul.fadeIn();
|
$ul.fadeIn();
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +772,7 @@
|
||||||
var trafficTypeData = ui.draggable.data('traffic-type-data');
|
var trafficTypeData = ui.draggable.data('traffic-type-data');
|
||||||
|
|
||||||
if (trafficTypeID == 'guest' &&
|
if (trafficTypeID == 'guest' &&
|
||||||
ui.draggable.closest('.select-container.multi').size()) {
|
ui.draggable.closest('.select-container.multi').length) {
|
||||||
ui.draggable.remove();
|
ui.draggable.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -880,7 +880,7 @@
|
||||||
|
|
||||||
// Only use networks w/ guest traffic type
|
// Only use networks w/ guest traffic type
|
||||||
$physicalNetworks = $physicalNetworks.filter(function() {
|
$physicalNetworks = $physicalNetworks.filter(function() {
|
||||||
return $(this).find('li.guest').size();
|
return $(this).find('li.guest').length;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
@ -1101,7 +1101,7 @@
|
||||||
var targetIndex = index - 1;
|
var targetIndex = index - 1;
|
||||||
|
|
||||||
if (index <= 1) targetIndex = 0;
|
if (index <= 1) targetIndex = 0;
|
||||||
if (targetIndex == $steps.size()) {
|
if (targetIndex == $steps.length) {
|
||||||
completeAction();
|
completeAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1130,7 +1130,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (formID) {
|
if (formID) {
|
||||||
if (!$targetStep.find('form').size()) {
|
if (!$targetStep.find('form').length) {
|
||||||
makeForm(args, formID, formState).appendTo($targetStep.find('.content.input-area .select-container'));
|
makeForm(args, formID, formState).appendTo($targetStep.find('.content.input-area .select-container'));
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
|
|
@ -1185,7 +1185,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($uiCustom.size()) {
|
if ($uiCustom.length) {
|
||||||
$uiCustom.each(function() {
|
$uiCustom.each(function() {
|
||||||
var $item = $(this);
|
var $item = $(this);
|
||||||
var id = $item.attr('ui-custom');
|
var id = $item.attr('ui-custom');
|
||||||
|
|
@ -1210,7 +1210,7 @@
|
||||||
$nextButton.removeClass('final post-launch');
|
$nextButton.removeClass('final post-launch');
|
||||||
|
|
||||||
// Show launch button if last step
|
// Show launch button if last step
|
||||||
if ($targetStep.index() == $steps.size() - 1 || options.nextStep) {
|
if ($targetStep.index() == $steps.length - 1 || options.nextStep) {
|
||||||
$nextButton.find('span').html(options.nextStep ? _l('label.save.changes') : _l('label.launch.zone'));
|
$nextButton.find('span').html(options.nextStep ? _l('label.save.changes') : _l('label.launch.zone'));
|
||||||
$nextButton.addClass('final');
|
$nextButton.addClass('final');
|
||||||
|
|
||||||
|
|
@ -1225,7 +1225,7 @@
|
||||||
}).toggleClass('active');
|
}).toggleClass('active');
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
if (!$targetStep.find('input[type=radio]:checked').size()) {
|
if (!$targetStep.find('input[type=radio]:checked').length) {
|
||||||
$targetStep.find('input[type=radio]:first').click();
|
$targetStep.find('input[type=radio]:first').click();
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
|
|
@ -1329,25 +1329,25 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next button
|
// Next button
|
||||||
if ($target.closest('div.button.next').size()) {
|
if ($target.closest('div.button.next').length) {
|
||||||
var $step = $steps.filter(':visible');
|
var $step = $steps.filter(':visible');
|
||||||
// Validation
|
// Validation
|
||||||
var $form = $('form:visible').filter(function() {
|
var $form = $('form:visible').filter(function() {
|
||||||
// Don't include multi-edit (validation happens separately)
|
// Don't include multi-edit (validation happens separately)
|
||||||
return !$(this).closest('.multi-edit').size();
|
return !$(this).closest('.multi-edit').length;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle validation for custom UI components
|
// Handle validation for custom UI components
|
||||||
var isCustomValidated = checkCustomValidation($step);
|
var isCustomValidated = checkCustomValidation($step);
|
||||||
if (($form.size() && !$form.valid()) || !isCustomValidated) {
|
if (($form.length && !$form.valid()) || !isCustomValidated) {
|
||||||
if (($form && $form.find('.error:visible').size()) || !isCustomValidated)
|
if (($form && $form.find('.error:visible').length) || !isCustomValidated)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//when hypervisor is BareMetal (begin)
|
//when hypervisor is BareMetal (begin)
|
||||||
var data = getData($wizard);
|
var data = getData($wizard);
|
||||||
if (('zone' in data) && (data.zone.hypervisor == 'BareMetal')) {
|
if (('zone' in data) && (data.zone.hypervisor == 'BareMetal')) {
|
||||||
if ($('.zone-wizard:visible').find('#add_zone_guest_traffic_desc:visible').size() > 0) { //$steps.filter(':visible').index() == 6
|
if ($('.zone-wizard:visible').find('#add_zone_guest_traffic_desc:visible').length > 0) { //$steps.filter(':visible').index() == 6
|
||||||
showStep('launch');
|
showStep('launch');
|
||||||
completeAction();
|
completeAction();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1355,10 +1355,10 @@
|
||||||
}
|
}
|
||||||
//when hypervisor is BareMetal (end)
|
//when hypervisor is BareMetal (end)
|
||||||
|
|
||||||
if (!$target.closest('.button.next.final').size())
|
if (!$target.closest('.button.next.final').length)
|
||||||
showStep($steps.filter(':visible').index() + 2);
|
showStep($steps.filter(':visible').index() + 2);
|
||||||
else {
|
else {
|
||||||
if ($target.closest('.button.next.final.post-launch').size()) {
|
if ($target.closest('.button.next.final.post-launch').length) {
|
||||||
showStep('launch');
|
showStep('launch');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1369,21 +1369,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Previous button
|
// Previous button
|
||||||
if ($target.closest('div.button.previous').size()) {
|
if ($target.closest('div.button.previous').length) {
|
||||||
showStep($steps.filter(':visible').index(), true);
|
showStep($steps.filter(':visible').index(), true);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close button
|
// Close button
|
||||||
if ($target.closest('div.button.cancel').size()) {
|
if ($target.closest('div.button.cancel').length) {
|
||||||
close();
|
close();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Edit link
|
// Edit link
|
||||||
if ($target.closest('div.edit').size()) {
|
if ($target.closest('div.edit').length) {
|
||||||
var $edit = $target.closest('div.edit');
|
var $edit = $target.closest('div.edit');
|
||||||
|
|
||||||
showStep($edit.find('a').attr('href'));
|
showStep($edit.find('a').attr('href'));
|
||||||
|
|
@ -1395,7 +1395,7 @@
|
||||||
var $editTrafficTypeButton = $target.closest('.drop-container .traffic-type-draggable .edit-traffic-type');
|
var $editTrafficTypeButton = $target.closest('.drop-container .traffic-type-draggable .edit-traffic-type');
|
||||||
var $trafficType = $editTrafficTypeButton.closest('.traffic-type-draggable');
|
var $trafficType = $editTrafficTypeButton.closest('.traffic-type-draggable');
|
||||||
|
|
||||||
if ($editTrafficTypeButton.size()) {
|
if ($editTrafficTypeButton.length) {
|
||||||
physicalNetwork.editTrafficTypeDialog($trafficType);
|
physicalNetwork.editTrafficTypeDialog($trafficType);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@
|
||||||
}).join(',')
|
}).join(',')
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($target.closest('.select.project-view').size()) {
|
if ($target.closest('.select.project-view').length) {
|
||||||
$('#cloudStack3-container').addClass('project-view');
|
$('#cloudStack3-container').addClass('project-view');
|
||||||
$projectSwitcher.addClass('alt');
|
$projectSwitcher.addClass('alt');
|
||||||
$projectSwitcher.find('.select.project-view').addClass('active')
|
$projectSwitcher.find('.select.project-view').addClass('active')
|
||||||
|
|
@ -404,9 +404,9 @@
|
||||||
function checkHoveredLabel($target) {
|
function checkHoveredLabel($target) {
|
||||||
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
||||||
if (($target.is('label[for]') && !$target.parents('body.login')) ||
|
if (($target.is('label[for]') && !$target.parents('body.login')) ||
|
||||||
($multiWizard.size() &&
|
($multiWizard.length &&
|
||||||
($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) ||
|
($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').length) ||
|
||||||
($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size())
|
($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').length)
|
||||||
))
|
))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -419,7 +419,7 @@
|
||||||
if (checkHoveredLabel($target)) {
|
if (checkHoveredLabel($target)) {
|
||||||
$target.addClass('label-hovered');
|
$target.addClass('label-hovered');
|
||||||
}
|
}
|
||||||
if ($target.closest('#user, #user-options').size()) {
|
if ($target.closest('#user, #user-options').length) {
|
||||||
return false;
|
return false;
|
||||||
} else $('#user-options').hide();
|
} else $('#user-options').hide();
|
||||||
|
|
||||||
|
|
@ -441,19 +441,19 @@
|
||||||
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
var $multiWizard = $('div.ui-dialog div.multi-wizard');
|
||||||
|
|
||||||
// Wizard: trigger click event for input when click it label
|
// Wizard: trigger click event for input when click it label
|
||||||
if ($multiWizard.size()) {
|
if ($multiWizard.length) {
|
||||||
if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) {
|
if ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').length) {
|
||||||
$target.prev('input').trigger('click');
|
$target.prev('input').trigger('click');
|
||||||
}
|
}
|
||||||
if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size()) {
|
if ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').length) {
|
||||||
$target.parent('div.select-desc').prev('input').trigger('click');
|
$target.parent('div.select-desc').prev('input').trigger('click');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$container.size()) return true;
|
if (!$container.length) return true;
|
||||||
|
|
||||||
// Navigation items
|
// Navigation items
|
||||||
if ($target.closest('li.navigation-item').size() && $target.closest('#navigation').size()) {
|
if ($target.closest('li.navigation-item').length && $target.closest('#navigation').length) {
|
||||||
var $navItem = $target.closest('li.navigation-item');
|
var $navItem = $target.closest('li.navigation-item');
|
||||||
|
|
||||||
if ($navItem.is('.disabled')) return false;
|
if ($navItem.is('.disabled')) return false;
|
||||||
|
|
@ -463,7 +463,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Browser expand
|
// Browser expand
|
||||||
if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').size()) {
|
if ($target.hasClass('control expand') && $target.closest('div.panel div.toolbar').length) {
|
||||||
$browser.cloudBrowser('toggleMaximizePanel', {
|
$browser.cloudBrowser('toggleMaximizePanel', {
|
||||||
panel: $target.closest('div.panel')
|
panel: $target.closest('div.panel')
|
||||||
});
|
});
|
||||||
|
|
@ -478,7 +478,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// User options
|
// User options
|
||||||
if ($target.closest('#user div.icon.options').size()) {
|
if ($target.closest('#user div.icon.options').length) {
|
||||||
$('#user-options').toggle();
|
$('#user-options').toggle();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -382,7 +382,7 @@
|
||||||
|
|
||||||
// Make sure all data is loaded to pass to select fn
|
// Make sure all data is loaded to pass to select fn
|
||||||
dependsOnLoaded = $.inArray(
|
dependsOnLoaded = $.inArray(
|
||||||
true, $dependsOn.map(function(index, item) { return $(item).find('option').size() ? true : false; })
|
true, $dependsOn.map(function(index, item) { return $(item).find('option').length ? true : false; })
|
||||||
) > -1;
|
) > -1;
|
||||||
|
|
||||||
if (!dependsOnLoaded) {
|
if (!dependsOnLoaded) {
|
||||||
|
|
@ -776,7 +776,7 @@
|
||||||
|
|
||||||
if (!$formContainer.find('form').valid()) {
|
if (!$formContainer.find('form').valid()) {
|
||||||
// Ignore hidden field validation
|
// Ignore hidden field validation
|
||||||
if ($formContainer.find('input.error:visible, select.error:visible').size()) {
|
if ($formContainer.find('input.error:visible, select.error:visible').length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -970,7 +970,7 @@
|
||||||
click: function() {
|
click: function() {
|
||||||
if (!$listView.find(
|
if (!$listView.find(
|
||||||
'input[type=radio]:checked, input[type=checkbox]:checked'
|
'input[type=radio]:checked, input[type=checkbox]:checked'
|
||||||
).size()) {
|
).length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: _l('message.select.instance')
|
message: _l('message.select.instance')
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
var data, elem;
|
var data, elem;
|
||||||
|
|
||||||
$elem = $target.closest('.cloudStack-elem.' + widget);
|
$elem = $target.closest('.cloudStack-elem.' + widget);
|
||||||
if (!$elem.size())
|
if (!$elem.length)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
$widget = $('.cloudStack-widget.' + widget);
|
$widget = $('.cloudStack-widget.' + widget);
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@
|
||||||
*/
|
*/
|
||||||
width: function($container, options) {
|
width: function($container, options) {
|
||||||
options = options ? options : {};
|
options = options ? options : {};
|
||||||
var width = $container.find('div.panel').size() < 1 || !options.partial ?
|
var width = $container.find('div.panel').length < 1 || !options.partial ?
|
||||||
$container.width() : $container.width() - $container.width() / 4;
|
$container.width() : $container.width() - $container.width() / 4;
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
* Get left position
|
* Get left position
|
||||||
*/
|
*/
|
||||||
position: function($container, options) {
|
position: function($container, options) {
|
||||||
return $container.find('div.panel').size() <= 1 || !options.partial ?
|
return $container.find('div.panel').length <= 1 || !options.partial ?
|
||||||
0 : _panel.width($container, options) - _panel.width($container, options) / 1.5;
|
0 : _panel.width($container, options) - _panel.width($container, options) / 1.5;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -340,7 +340,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#breadcrumbs li').live('click', cloudStack.ui.event.bind(
|
$(document).on('click', '#breadcrumbs li', cloudStack.ui.event.bind(
|
||||||
'cloudBrowser', {
|
'cloudBrowser', {
|
||||||
'breadcrumb': function($target, $browser, data) {
|
'breadcrumb': function($target, $browser, data) {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -228,9 +228,9 @@
|
||||||
$tbody.width($thead.width());
|
$tbody.width($thead.width());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ths.size() > $tds.size()) {
|
if ($ths.length > $tds.length) {
|
||||||
$ths.width(
|
$ths.width(
|
||||||
$table.width() / $ths.size()
|
$table.width() / $ths.length
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -281,7 +281,7 @@
|
||||||
|
|
||||||
var init = function() {
|
var init = function() {
|
||||||
var noSelect = options && options.noSelect == true ? true : false;
|
var noSelect = options && options.noSelect == true ? true : false;
|
||||||
if (!$table.closest('div.data-table').size() && !$table.hasClass('no-split')) {
|
if (!$table.closest('div.data-table').length && !$table.hasClass('no-split')) {
|
||||||
reattachTable();
|
reattachTable();
|
||||||
$table.find('tbody').closest('table').addClass('body');
|
$table.find('tbody').closest('table').addClass('body');
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +304,7 @@
|
||||||
$table.bind('click', function(event) {
|
$table.bind('click', function(event) {
|
||||||
var $tr = $(event.target).closest('tr');
|
var $tr = $(event.target).closest('tr');
|
||||||
|
|
||||||
if (!$tr.size() || noSelect) return true;
|
if (!$tr.length || noSelect) return true;
|
||||||
var rowIndex = $tr.index();
|
var rowIndex = $tr.index();
|
||||||
|
|
||||||
toggleSelectRow(rowIndex);
|
toggleSelectRow(rowIndex);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
var $listView = $row.closest('.list-view');
|
var $listView = $row.closest('.list-view');
|
||||||
|
|
||||||
if (!$listView.parents('html').size()) return;
|
if (!$listView.parents('html').length) return;
|
||||||
|
|
||||||
var $newRow;
|
var $newRow;
|
||||||
var jsonObj = $row.data('json-obj');
|
var jsonObj = $row.data('json-obj');
|
||||||
|
|
@ -56,6 +56,15 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var tabEvents = {
|
||||||
|
create: function(event, ui) {
|
||||||
|
manageTabsContent(event, ui);
|
||||||
|
},
|
||||||
|
activate: function(event, ui) {
|
||||||
|
manageTabsContent(event, ui);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Available UI actions to perform for buttons
|
* Available UI actions to perform for buttons
|
||||||
*/
|
*/
|
||||||
|
|
@ -114,7 +123,7 @@
|
||||||
}
|
}
|
||||||
).appendTo($detailView);
|
).appendTo($detailView);
|
||||||
|
|
||||||
$detailView.tabs();
|
$detailView.tabs(tabEvents);
|
||||||
};
|
};
|
||||||
|
|
||||||
var performAction = function(data, options) {
|
var performAction = function(data, options) {
|
||||||
|
|
@ -172,7 +181,7 @@
|
||||||
viewArgs.onActionComplete();
|
viewArgs.onActionComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$detailView.parents('html').size()) {
|
if (!$detailView.parents('html').length) {
|
||||||
replaceListViewItem(null, args.data, {
|
replaceListViewItem(null, args.data, {
|
||||||
$row: $row
|
$row: $row
|
||||||
});
|
});
|
||||||
|
|
@ -222,7 +231,7 @@
|
||||||
cloudStack.ui.notifications.add(
|
cloudStack.ui.notifications.add(
|
||||||
notification,
|
notification,
|
||||||
function(args2) { //name parameter as "args2" instead of "args" to avoid override "args" from success: function(args) {
|
function(args2) { //name parameter as "args2" instead of "args" to avoid override "args" from success: function(args) {
|
||||||
if ($detailView.parents('html').size()) {
|
if ($detailView.parents('html').length) {
|
||||||
$loading.remove();
|
$loading.remove();
|
||||||
|
|
||||||
if (!noRefresh && !viewArgs.compact) {
|
if (!noRefresh && !viewArgs.compact) {
|
||||||
|
|
@ -376,7 +385,7 @@
|
||||||
var $tbody = $row.closest('tbody');
|
var $tbody = $row.closest('tbody');
|
||||||
|
|
||||||
$row.remove();
|
$row.remove();
|
||||||
if (!$tbody.find('tr').size()) {
|
if (!$tbody.find('tr').length) {
|
||||||
$("<tr>").addClass('empty').append(
|
$("<tr>").addClass('empty').append(
|
||||||
$("<td>").html(_l('label.no.data'))
|
$("<td>").html(_l('label.no.data'))
|
||||||
).appendTo($tbody);
|
).appendTo($tbody);
|
||||||
|
|
@ -413,7 +422,7 @@
|
||||||
var $tbody = $row.closest('tbody');
|
var $tbody = $row.closest('tbody');
|
||||||
|
|
||||||
$row.remove();
|
$row.remove();
|
||||||
if (!$tbody.find('tr').size()) {
|
if (!$tbody.find('tr').length) {
|
||||||
$("<tr>").addClass('empty').append(
|
$("<tr>").addClass('empty').append(
|
||||||
$("<td>").html(_l('label.no.data'))
|
$("<td>").html(_l('label.no.data'))
|
||||||
).appendTo($tbody);
|
).appendTo($tbody);
|
||||||
|
|
@ -439,11 +448,11 @@
|
||||||
$detailView.addClass('edit-mode');
|
$detailView.addClass('edit-mode');
|
||||||
var token_value = "";
|
var token_value = "";
|
||||||
|
|
||||||
if ($detailView.find('.button.done').size()) return false;
|
if ($detailView.find('.button.done').length) return false;
|
||||||
|
|
||||||
// Convert value TDs
|
// Convert value TDs
|
||||||
var $inputs = $detailView.find('input, select, textarea').filter(function() {
|
var $inputs = $detailView.find('input, select, textarea').filter(function() {
|
||||||
return !$(this).closest('.tagger').size() && !$(this).attr('type') == 'submit';
|
return !$(this).closest('.tagger').length && !$(this).attr('type') == 'submit';
|
||||||
});
|
});
|
||||||
var action = args.actions[args.actionName];
|
var action = args.actions[args.actionName];
|
||||||
var id = $detailView.data('view-args').id;
|
var id = $detailView.data('view-args').id;
|
||||||
|
|
@ -476,7 +485,7 @@
|
||||||
var $token;
|
var $token;
|
||||||
var tags_value = "";
|
var tags_value = "";
|
||||||
$inputs.each(function() {
|
$inputs.each(function() {
|
||||||
if ($(this).closest('.tagger').size()) return true;
|
if ($(this).closest('.tagger').length) return true;
|
||||||
|
|
||||||
var $input = $(this);
|
var $input = $(this);
|
||||||
var $value = $input.closest('td.value span');
|
var $value = $input.closest('td.value span');
|
||||||
|
|
@ -525,9 +534,9 @@
|
||||||
|
|
||||||
// Remove Edit form
|
// Remove Edit form
|
||||||
var $form = $detailView.find('form').filter(function() {
|
var $form = $detailView.find('form').filter(function() {
|
||||||
return !$(this).closest('.tagger').size();
|
return !$(this).closest('.tagger').length;
|
||||||
});
|
});
|
||||||
if ($form.size()) {
|
if ($form.length) {
|
||||||
var $mainGroups = $form.find('div.main-groups').detach();
|
var $mainGroups = $form.find('div.main-groups').detach();
|
||||||
$form.parent('div').append($mainGroups);
|
$form.parent('div').append($mainGroups);
|
||||||
$form.remove();
|
$form.remove();
|
||||||
|
|
@ -539,7 +548,7 @@
|
||||||
// Put in original values
|
// Put in original values
|
||||||
var cancelEdits = function($inputs, $editButton) {
|
var cancelEdits = function($inputs, $editButton) {
|
||||||
$inputs.each(function() {
|
$inputs.each(function() {
|
||||||
if ($(this).closest('.tagger').size()) return true;
|
if ($(this).closest('.tagger').length) return true;
|
||||||
|
|
||||||
var $input = $(this);
|
var $input = $(this);
|
||||||
var $value = $input.closest('td.value span');
|
var $value = $input.closest('td.value span');
|
||||||
|
|
@ -561,7 +570,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
var applyEdits = function($inputs, $editButton) {
|
var applyEdits = function($inputs, $editButton) {
|
||||||
if ($inputs.size()) {
|
if ($inputs.length) {
|
||||||
$inputs.animate({
|
$inputs.animate({
|
||||||
opacity: 0.5
|
opacity: 0.5
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
@ -634,16 +643,16 @@
|
||||||
|
|
||||||
$editButton.click(function() {
|
$editButton.click(function() {
|
||||||
var $inputs = $detailView.find('input, select, textarea').filter(function() {
|
var $inputs = $detailView.find('input, select, textarea').filter(function() {
|
||||||
return !$(this).closest('.tagger').size();
|
return !$(this).closest('.tagger').length;
|
||||||
});
|
});
|
||||||
var $form = $detailView.find('form').filter(function() {
|
var $form = $detailView.find('form').filter(function() {
|
||||||
return !$(this).closest('.tagger').size();
|
return !$(this).closest('.tagger').length;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($(this).hasClass('done')) {
|
if ($(this).hasClass('done')) {
|
||||||
if (!$form.valid()) {
|
if (!$form.valid()) {
|
||||||
// Ignore hidden field validation
|
// Ignore hidden field validation
|
||||||
if ($form.find('input.error:visible, select.error:visible').size()) {
|
if ($form.find('input.error:visible, select.error:visible').length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -796,7 +805,7 @@
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
if ($detailView.find('td.value span:data(detail-view-is-editable)').size()) {
|
if ($detailView.find('td.value span:data(detail-view-is-editable)').length) {
|
||||||
var $detailsEdit = $detailView.find('div.main-groups').detach(),
|
var $detailsEdit = $detailView.find('div.main-groups').detach(),
|
||||||
$detailsEditForm = $('<form>').append($detailsEdit);
|
$detailsEditForm = $('<form>').append($detailsEdit);
|
||||||
|
|
||||||
|
|
@ -805,7 +814,7 @@
|
||||||
|
|
||||||
// Setup form validation
|
// Setup form validation
|
||||||
var $form = $detailView.find('form').filter(function() {
|
var $form = $detailView.find('form').filter(function() {
|
||||||
return !$(this).closest('.tagger').size();
|
return !$(this).closest('.tagger').length;
|
||||||
});
|
});
|
||||||
$form.validate();
|
$form.validate();
|
||||||
$form.find('input, select').each(function() {
|
$form.find('input, select').each(function() {
|
||||||
|
|
@ -976,7 +985,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
var $actionButtons = $actions.find('div.action:not(.text)');
|
var $actionButtons = $actions.find('div.action:not(.text)');
|
||||||
if ($actionButtons.size() == 1)
|
if ($actionButtons.length == 1)
|
||||||
$actionButtons.addClass('single');
|
$actionButtons.addClass('single');
|
||||||
else {
|
else {
|
||||||
$actionButtons.filter(':first').addClass('first');
|
$actionButtons.filter(':first').addClass('first');
|
||||||
|
|
@ -1180,7 +1189,7 @@
|
||||||
context: context
|
context: context
|
||||||
}) : true
|
}) : true
|
||||||
) : true;
|
) : true;
|
||||||
if ($actions && ($actions.find('div.action').size() || (detailViewArgs.viewAll && showViewAll))) {
|
if ($actions && ($actions.find('div.action').length || (detailViewArgs.viewAll && showViewAll))) {
|
||||||
$actions.prependTo($firstRow.closest('div.detail-group').closest('.details'));
|
$actions.prependTo($firstRow.closest('div.detail-group').closest('.details'));
|
||||||
}
|
}
|
||||||
if (detailViewArgs.viewAll && showViewAll) {
|
if (detailViewArgs.viewAll && showViewAll) {
|
||||||
|
|
@ -1559,12 +1568,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$detailView.tabs({
|
$detailView.tabs(
|
||||||
select: function() {
|
$.extend(true, {}, tabEvents, {
|
||||||
|
select: function() {
|
||||||
// Cleanup old tab content
|
// Cleanup old tab content
|
||||||
$detailView.find('.detail-group').children().remove();
|
$detailView.find('.detail-group').children().remove();
|
||||||
}
|
}}
|
||||||
});
|
)
|
||||||
|
);
|
||||||
|
|
||||||
return $detailView;
|
return $detailView;
|
||||||
};
|
};
|
||||||
|
|
@ -1588,16 +1599,13 @@
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
$(document).bind('tabscreate',manageTabsContent);
|
|
||||||
$(document).bind('tabsactivate',manageTabsContent);
|
|
||||||
|
|
||||||
// View all links
|
// View all links
|
||||||
$('a').live('click', function(event) {
|
$(document).on('click', 'a', function(event) {
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
var $viewAll = $target.closest('td.view-all a');
|
var $viewAll = $target.closest('td.view-all a');
|
||||||
var viewAllArgs;
|
var viewAllArgs;
|
||||||
|
|
||||||
if ($target.closest('div.detail-view').size() && $target.closest('td.view-all a').size()) {
|
if ($target.closest('div.detail-view').length && $target.closest('td.view-all a').length) {
|
||||||
viewAllArgs = $viewAll.data('detail-view-link-view-all');
|
viewAllArgs = $viewAll.data('detail-view-link-view-all');
|
||||||
viewAll(
|
viewAll(
|
||||||
viewAllArgs.custom ?
|
viewAllArgs.custom ?
|
||||||
|
|
@ -1625,7 +1633,7 @@
|
||||||
var $target = $(event.target);
|
var $target = $(event.target);
|
||||||
|
|
||||||
// Refresh
|
// Refresh
|
||||||
if ($target.closest('div.toolbar div.refresh').size()) {
|
if ($target.closest('div.toolbar div.refresh').length) {
|
||||||
loadTabContent(
|
loadTabContent(
|
||||||
$target.closest('div.detail-view').find('div.detail-group:visible'),
|
$target.closest('div.detail-view').find('div.detail-group:visible'),
|
||||||
$target.closest('div.detail-view').data('view-args'),
|
$target.closest('div.detail-view').data('view-args'),
|
||||||
|
|
@ -1636,8 +1644,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detail action
|
// Detail action
|
||||||
if ($target.closest('div.detail-view [detail-action], div.detail-view .action.text').size() &&
|
if ($target.closest('div.detail-view [detail-action], div.detail-view .action.text').length &&
|
||||||
!$target.closest('.list-view').size()) {
|
!$target.closest('.list-view').length) {
|
||||||
var $action = $target.closest('.action').find('[detail-action]');
|
var $action = $target.closest('.action').find('[detail-action]');
|
||||||
var actionName = $action.attr('detail-action');
|
var actionName = $action.attr('detail-action');
|
||||||
var actionCallback = $action.data('detail-view-action-callback');
|
var actionCallback = $action.data('detail-view-action-callback');
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsRefresh) {
|
if (needsRefresh) {
|
||||||
if ($listView.closest('.detail-view').size()) {
|
if ($listView.closest('.detail-view').length) {
|
||||||
$('.detail-view:last .button.refresh').click();
|
$('.detail-view:last .button.refresh').click();
|
||||||
} else {
|
} else {
|
||||||
$loading.remove();
|
$loading.remove();
|
||||||
|
|
@ -375,7 +375,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsRefresh) {
|
if (needsRefresh) {
|
||||||
if (!$listView.closest('.detail-view').size()) {
|
if (!$listView.closest('.detail-view').length) {
|
||||||
$loading.remove();
|
$loading.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1148,7 +1148,7 @@
|
||||||
|
|
||||||
if (!(data && data.length)) {
|
if (!(data && data.length)) {
|
||||||
$listView.data('end-of-table', true);
|
$listView.data('end-of-table', true);
|
||||||
if (!$tbody.find('tr').size()) {
|
if (!$tbody.find('tr').length) {
|
||||||
return [
|
return [
|
||||||
$('<tr>').addClass('empty last').append(
|
$('<tr>').addClass('empty last').append(
|
||||||
$('<td>').html(_l('label.no.data'))
|
$('<td>').html(_l('label.no.data'))
|
||||||
|
|
@ -1186,8 +1186,8 @@
|
||||||
.addClass('multiSelectCheckbox')
|
.addClass('multiSelectCheckbox')
|
||||||
.click(function() {
|
.click(function() {
|
||||||
var checked = $(this).is(':checked');
|
var checked = $(this).is(':checked');
|
||||||
var numRows = $(this).parents('tbody').find('input.multiSelectCheckbox').size();
|
var numRows = $(this).parents('tbody').find('input.multiSelectCheckbox').length;
|
||||||
var numRowsChecked = $(this).parents('tbody').find('input.multiSelectCheckbox:checked').size();
|
var numRowsChecked = $(this).parents('tbody').find('input.multiSelectCheckbox:checked').length;
|
||||||
var enabled = checked || (numRowsChecked > 0);
|
var enabled = checked || (numRowsChecked > 0);
|
||||||
|
|
||||||
toggleMultiSelectActions($td.closest('.list-view'), enabled);
|
toggleMultiSelectActions($td.closest('.list-view'), enabled);
|
||||||
|
|
@ -1326,7 +1326,7 @@
|
||||||
true, {},
|
true, {},
|
||||||
$tr.closest('.list-view').data('view-args').context
|
$tr.closest('.list-view').data('view-args').context
|
||||||
);
|
);
|
||||||
var rowIndex = $tr.closest('tbody').find('tr').size() - ($tr.index());
|
var rowIndex = $tr.closest('tbody').find('tr').length - ($tr.index());
|
||||||
|
|
||||||
context[viewArgs.activeSection] = $tr.data('json-obj');
|
context[viewArgs.activeSection] = $tr.data('json-obj');
|
||||||
|
|
||||||
|
|
@ -1630,11 +1630,11 @@
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
left: $quickView.offset().left + $quickView.outerWidth() - $quickViewTooltip.width() - 2*(parseInt($quickView.css('border-left-width')) + parseInt($quickView.css('border-right-width'))),
|
left: $quickView.offset().left + $quickView.outerWidth() - $quickViewTooltip.width() - 2*(parseInt($quickView.css('border-left-width')) + parseInt($quickView.css('border-right-width'))),
|
||||||
top: $quickView.offset().top,
|
top: $quickView.offset().top,
|
||||||
zIndex: $tr.closest('.panel').zIndex() + 1
|
zIndex: $tr.closest('.panel').css("zIndex") + 1
|
||||||
});
|
});
|
||||||
|
|
||||||
$quickViewTooltip.mouseleave(function() {
|
$quickViewTooltip.mouseleave(function() {
|
||||||
if (!$('.overlay:visible').size()) {
|
if (!$('.overlay:visible').length) {
|
||||||
$quickViewTooltip.remove();
|
$quickViewTooltip.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -1662,7 +1662,7 @@
|
||||||
$('<td>')
|
$('<td>')
|
||||||
.addClass('loading icon')
|
.addClass('loading icon')
|
||||||
.attr({
|
.attr({
|
||||||
'colspan': $table.find('th').size()
|
'colspan': $table.find('th').length
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1830,7 +1830,7 @@
|
||||||
|
|
||||||
// Clear out any existing list view
|
// Clear out any existing list view
|
||||||
var $existingListView = $container.find('div.list-view');
|
var $existingListView = $container.find('div.list-view');
|
||||||
if ($existingListView.size()) {
|
if ($existingListView.length) {
|
||||||
$existingListView.remove();
|
$existingListView.remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1884,7 +1884,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($switcher && $switcher.find('option').size() == 1) {
|
if ($switcher && $switcher.find('option').length == 1) {
|
||||||
listViewData = args.sections[
|
listViewData = args.sections[
|
||||||
$switcher.find('select').val()
|
$switcher.find('select').val()
|
||||||
].listView;
|
].listView;
|
||||||
|
|
@ -2018,7 +2018,7 @@
|
||||||
var code = (event.keyCode ? event.keyCode : event.which);
|
var code = (event.keyCode ? event.keyCode : event.which);
|
||||||
var $input = $listView.find('input:focus');
|
var $input = $listView.find('input:focus');
|
||||||
|
|
||||||
if ($input.size() && $input.hasClass('edit') && code === 13) {
|
if ($input.length && $input.hasClass('edit') && code === 13) {
|
||||||
uiActions.edit($input.closest('tr'), {
|
uiActions.edit($input.closest('tr'), {
|
||||||
callback: listViewData.actions.edit.action
|
callback: listViewData.actions.edit.action
|
||||||
});
|
});
|
||||||
|
|
@ -2078,7 +2078,7 @@
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
$listView.find('select').bind('change', function(event) {
|
$listView.find('select').bind('change', function(event) {
|
||||||
if ($(event.target).closest('.section-select').size()) return true;
|
if ($(event.target).closest('.section-select').length) return true;
|
||||||
if ((event.type == 'click' ||
|
if ((event.type == 'click' ||
|
||||||
event.type == 'mouseup') &&
|
event.type == 'mouseup') &&
|
||||||
($(event.target).is('select') ||
|
($(event.target).is('select') ||
|
||||||
|
|
@ -2124,7 +2124,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
$listView.find('.advanced-search .icon').bind('click', function(event) {
|
$listView.find('.advanced-search .icon').bind('click', function(event) {
|
||||||
if ($listView.find('.advanced-search .form-container:visible').size()) {
|
if ($listView.find('.advanced-search .form-container:visible').length) {
|
||||||
closeAdvancedSearch();
|
closeAdvancedSearch();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2181,7 +2181,7 @@
|
||||||
listView = args.sections[args.activeSection].listView;
|
listView = args.sections[args.activeSection].listView;
|
||||||
}
|
}
|
||||||
if (listView && listView.disableInfiniteScrolling) return false;
|
if (listView && listView.disableInfiniteScrolling) return false;
|
||||||
if ($listView.find('tr.last, td.loading:visible').size()) return false;
|
if ($listView.find('tr.last, td.loading:visible').length) return false;
|
||||||
|
|
||||||
clearTimeout(infScrollTimer);
|
clearTimeout(infScrollTimer);
|
||||||
infScrollTimer = setTimeout(function() {
|
infScrollTimer = setTimeout(function() {
|
||||||
|
|
@ -2246,12 +2246,12 @@
|
||||||
var id = $target.closest('tr').data('list-view-item-id');
|
var id = $target.closest('tr').data('list-view-item-id');
|
||||||
var jsonObj = $target.closest('tr').data('jsonObj');
|
var jsonObj = $target.closest('tr').data('jsonObj');
|
||||||
var detailViewArgs;
|
var detailViewArgs;
|
||||||
var detailViewPresent = ($target.closest('div.data-table tr td.first').size() &&
|
var detailViewPresent = ($target.closest('div.data-table tr td.first').length &&
|
||||||
listViewData.detailView && !$target.closest('div.edit').size()) && !listViewData.detailView.noPanelView;
|
listViewData.detailView && !$target.closest('div.edit').length) && !listViewData.detailView.noPanelView;
|
||||||
var uiCustom = args.uiCustom == true ? true : false;
|
var uiCustom = args.uiCustom == true ? true : false;
|
||||||
|
|
||||||
// Click on first item will trigger detail view (if present)
|
// Click on first item will trigger detail view (if present)
|
||||||
if (detailViewPresent && !uiCustom && !$target.closest('.empty, .loading').size()) {
|
if (detailViewPresent && !uiCustom && !$target.closest('.empty, .loading').length) {
|
||||||
var $loading = $('<div>').addClass('loading-overlay');
|
var $loading = $('<div>').addClass('loading-overlay');
|
||||||
$target.closest('div.data-table').prepend($loading); //overlay the whole listView, so users can't click another row until click-handling for this row is done (e.g. API response is back)
|
$target.closest('div.data-table').prepend($loading); //overlay the whole listView, so users can't click another row until click-handling for this row is done (e.g. API response is back)
|
||||||
|
|
||||||
|
|
@ -2317,9 +2317,9 @@
|
||||||
|
|
||||||
// Action icons
|
// Action icons
|
||||||
if (!$target.closest('td.actions').hasClass('reorder') &&
|
if (!$target.closest('td.actions').hasClass('reorder') &&
|
||||||
($target.closest('td.actions').size() ||
|
($target.closest('td.actions').length ||
|
||||||
$target.closest('.action.add').size() ||
|
$target.closest('.action.add').length ||
|
||||||
$target.closest('.action.main-action').size())) {
|
$target.closest('.action.main-action').length)) {
|
||||||
var actionID = $target.closest('.action').data('list-view-action-id');
|
var actionID = $target.closest('.action').data('list-view-action-id');
|
||||||
var $tr;
|
var $tr;
|
||||||
|
|
||||||
|
|
@ -2327,8 +2327,8 @@
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($target.closest('.action.add').size() ||
|
if ($target.closest('.action.add').length ||
|
||||||
$target.closest('.action.main-action:not(.multiSelectAction)').size()) {
|
$target.closest('.action.main-action:not(.multiSelectAction)').length) {
|
||||||
$tr = $target.closest('div.list-view').find('tr:first'); // Dummy row
|
$tr = $target.closest('div.list-view').find('tr:first'); // Dummy row
|
||||||
} else {
|
} else {
|
||||||
if (listViewData.actions[actionID].isMultiSelectAction) {
|
if (listViewData.actions[actionID].isMultiSelectAction) {
|
||||||
|
|
@ -2360,7 +2360,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section switcher
|
// Section switcher
|
||||||
if ($target.is('a') && $target.closest('div.section-switcher').size()) {
|
if ($target.is('a') && $target.closest('div.section-switcher').length) {
|
||||||
makeListView($container, args, $target.data('list-view-section-id'));
|
makeListView($container, args, $target.data('list-view-section-id'));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2460,7 +2460,7 @@
|
||||||
|
|
||||||
if (preFilter) {
|
if (preFilter) {
|
||||||
$selectedVMs = $listView.find('tbody tr').filter(function() {
|
$selectedVMs = $listView.find('tbody tr').filter(function() {
|
||||||
return $(this).find('td.multiselect input[type=checkbox]:checked').size()
|
return $(this).find('td.multiselect input[type=checkbox]:checked').length
|
||||||
});
|
});
|
||||||
context[$listView.data('view-args').activeSection] = $selectedVMs.map(function(index, item) {
|
context[$listView.data('view-args').activeSection] = $selectedVMs.map(function(index, item) {
|
||||||
return $(item).data('json-obj');
|
return $(item).data('json-obj');
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,7 @@
|
||||||
$td.append($select);
|
$td.append($select);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var matchingValue = $matchingOption.size() ?
|
var matchingValue = $matchingOption.length ?
|
||||||
$matchingOption.html() : data[fieldName];
|
$matchingOption.html() : data[fieldName];
|
||||||
|
|
||||||
$td.append($('<span>').html(_s(matchingValue)));
|
$td.append($('<span>').html(_s(matchingValue)));
|
||||||
|
|
@ -243,7 +243,7 @@
|
||||||
|
|
||||||
var $subItems = $td.closest('.data-item').find('.expandable-listing tr');
|
var $subItems = $td.closest('.data-item').find('.expandable-listing tr');
|
||||||
|
|
||||||
if ($subItems.size()) {
|
if ($subItems.length) {
|
||||||
context.subItemData = $subItems.map(function() {
|
context.subItemData = $subItems.map(function() {
|
||||||
return $(this).data('json-obj');
|
return $(this).data('json-obj');
|
||||||
});
|
});
|
||||||
|
|
@ -598,7 +598,7 @@
|
||||||
text: _l('label.apply'),
|
text: _l('label.apply'),
|
||||||
'class': 'ok',
|
'class': 'ok',
|
||||||
click: function() {
|
click: function() {
|
||||||
if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').size()) {
|
if (!$listView.find('input[type=radio]:checked, input[type=checkbox]:checked').length) {
|
||||||
cloudStack.dialog.notice({
|
cloudStack.dialog.notice({
|
||||||
message: _l('message.select.item')
|
message: _l('message.select.item')
|
||||||
});
|
});
|
||||||
|
|
@ -660,7 +660,7 @@
|
||||||
);
|
);
|
||||||
|
|
||||||
$multi.find('.data tr').filter(function() {
|
$multi.find('.data tr').filter(function() {
|
||||||
return !$(this).closest('.expandable-listing').size();
|
return !$(this).closest('.expandable-listing').length;
|
||||||
}).each(function() {
|
}).each(function() {
|
||||||
var $tr = $(this);
|
var $tr = $(this);
|
||||||
|
|
||||||
|
|
@ -929,8 +929,8 @@
|
||||||
$loading.prependTo($multi);
|
$loading.prependTo($multi);
|
||||||
reorder.moveDrag.action({
|
reorder.moveDrag.action({
|
||||||
targetIndex: ui.item.index(),
|
targetIndex: ui.item.index(),
|
||||||
nextItem: ui.item.next().size() ? ui.item.next().data('json-obj') : null,
|
nextItem: ui.item.next().length ? ui.item.next().data('json-obj') : null,
|
||||||
prevItem: ui.item.prev().size() ? ui.item.prev().data('json-obj') : null,
|
prevItem: ui.item.prev().length ? ui.item.prev().data('json-obj') : null,
|
||||||
context: $.extend(true, {}, context, {
|
context: $.extend(true, {}, context, {
|
||||||
// Passes all rules, so that each index can be updated
|
// Passes all rules, so that each index can be updated
|
||||||
multiRule: [ui.item.data('json-obj')]
|
multiRule: [ui.item.data('json-obj')]
|
||||||
|
|
@ -1121,7 +1121,7 @@
|
||||||
$addVM.bind('click', function() {
|
$addVM.bind('click', function() {
|
||||||
// Validate form first
|
// Validate form first
|
||||||
if (!$multiForm.valid()) {
|
if (!$multiForm.valid()) {
|
||||||
if ($multiForm.find('input.error:visible').size()) {
|
if ($multiForm.find('input.error:visible').length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,8 +145,8 @@
|
||||||
resetTotal: function($popup) {
|
resetTotal: function($popup) {
|
||||||
var $total = $popup.data('notifications-attach-to').find('div.total span');
|
var $total = $popup.data('notifications-attach-to').find('div.total span');
|
||||||
var $items = $popup.find('ul li');
|
var $items = $popup.find('ul li');
|
||||||
var total = $items.size();
|
var total = $items.length;
|
||||||
var completed = $items.filter(':not(.pending)').size();
|
var completed = $items.filter(':not(.pending)').length;
|
||||||
var newTotal = total - completed;
|
var newTotal = total - completed;
|
||||||
|
|
||||||
if (newTotal < 0) newTotal = completed;
|
if (newTotal < 0) newTotal = completed;
|
||||||
|
|
@ -331,7 +331,7 @@
|
||||||
var $attachTo, $popup;
|
var $attachTo, $popup;
|
||||||
|
|
||||||
// Notifications header area
|
// Notifications header area
|
||||||
if ($target.closest('.notifications').size()) {
|
if ($target.closest('.notifications').length) {
|
||||||
$attachTo = $target.closest('.notifications');
|
$attachTo = $target.closest('.notifications');
|
||||||
$popup = $attachTo.data('notifications-popup');
|
$popup = $attachTo.data('notifications-popup');
|
||||||
notifications.popup.show($popup, $attachTo);
|
notifications.popup.show($popup, $attachTo);
|
||||||
|
|
@ -352,11 +352,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Popup
|
// Popup
|
||||||
if ($target.closest('div.notification-box').size()) {
|
if ($target.closest('div.notification-box').length) {
|
||||||
$popup = $target.closest('div.notification-box');
|
$popup = $target.closest('div.notification-box');
|
||||||
|
|
||||||
// Clear list
|
// Clear list
|
||||||
if ($target.closest('.button.clear-list').size()) {
|
if ($target.closest('.button.clear-list').length) {
|
||||||
notifications.clear($popup);
|
notifications.clear($popup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -379,7 +379,7 @@
|
||||||
$(window).resize(function(event) {
|
$(window).resize(function(event) {
|
||||||
var $popup = $('div.notification-box:visible');
|
var $popup = $('div.notification-box:visible');
|
||||||
|
|
||||||
if ($popup.size())
|
if ($popup.length)
|
||||||
notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
|
notifications.popup.reposition($popup, $popup.data('notifications-attach-to'));
|
||||||
});
|
});
|
||||||
})(window.jQuery, window.cloudStack, window._l);
|
})(window.jQuery, window.cloudStack, window._l);
|
||||||
|
|
|
||||||
|
|
@ -165,7 +165,7 @@
|
||||||
|
|
||||||
// Fix overlay
|
// Fix overlay
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
$('.tooltip-box').zIndex($(':ui-dialog').zIndex() + 10);
|
$('.tooltip-box').css( "zIndex", $(':ui-dialog').css("zIndex") + 10);
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@
|
||||||
var $li = $target.closest('li');
|
var $li = $target.closest('li');
|
||||||
|
|
||||||
if ($target.is('li div.expand') && $li.data('tree-view-item-obj')) {
|
if ($target.is('li div.expand') && $li.data('tree-view-item-obj')) {
|
||||||
if ($li.find('ul').size()) {
|
if ($li.find('ul').length) {
|
||||||
$li.find('ul').remove();
|
$li.find('ul').remove();
|
||||||
$li.removeClass('expanded');
|
$li.removeClass('expanded');
|
||||||
|
|
||||||
|
|
@ -128,7 +128,7 @@
|
||||||
$treeView.find('li .name').removeClass('selected');
|
$treeView.find('li .name').removeClass('selected');
|
||||||
$target.addClass('selected');
|
$target.addClass('selected');
|
||||||
|
|
||||||
if ($browser && $browser.size()) {
|
if ($browser && $browser.length) {
|
||||||
$browser.cloudBrowser('addPanel', {
|
$browser.cloudBrowser('addPanel', {
|
||||||
partial: true,
|
partial: true,
|
||||||
title: $target.html(),
|
title: $target.html(),
|
||||||
|
|
|
||||||
|
|
@ -1430,7 +1430,7 @@
|
||||||
args.response.success({
|
args.response.success({
|
||||||
data: items
|
data: items
|
||||||
});
|
});
|
||||||
if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.add').size() === 0){
|
if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.add').length === 0){
|
||||||
var $addAclRuleDivButton = jQuery('<div>').addClass('button add');
|
var $addAclRuleDivButton = jQuery('<div>').addClass('button add');
|
||||||
var $spanAddAclRuleButtonMessage = jQuery('<span>').html(_l('label.add.ACL'));
|
var $spanAddAclRuleButtonMessage = jQuery('<span>').html(_l('label.add.ACL'));
|
||||||
|
|
||||||
|
|
@ -1474,7 +1474,7 @@
|
||||||
});
|
});
|
||||||
jQuery('#details-tab-aclRules').siblings('div.toolbar').append($addAclRuleDivButton);
|
jQuery('#details-tab-aclRules').siblings('div.toolbar').append($addAclRuleDivButton);
|
||||||
}
|
}
|
||||||
if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.export').size() === 0){
|
if(jQuery('#details-tab-aclRules').siblings('div.toolbar').children('div.export').length === 0){
|
||||||
var $exportAclsDivButton = jQuery('<div>').addClass('button export');
|
var $exportAclsDivButton = jQuery('<div>').addClass('button export');
|
||||||
var $linkExportAclRulesButtonMessage = jQuery('<a>').html(_l('label.acl.export'));
|
var $linkExportAclRulesButtonMessage = jQuery('<a>').html(_l('label.acl.export'));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,11 +43,11 @@
|
||||||
var $toolbar = $listView.find('> .toolbar');
|
var $toolbar = $listView.find('> .toolbar');
|
||||||
var $table = $listView.find('> .data-table');
|
var $table = $listView.find('> .data-table');
|
||||||
|
|
||||||
equal($listView.size(), 1, 'List view present');
|
equal($listView.length, 1, 'List view present');
|
||||||
equal($toolbar.size(), 1, 'Toolbar present');
|
equal($toolbar.length, 1, 'Toolbar present');
|
||||||
equal($table.size(), 1, 'Data table div present');
|
equal($table.length, 1, 'Data table div present');
|
||||||
equal($table.find('> .fixed-header table thead tr').size(), 1, 'Fixed header present');
|
equal($table.find('> .fixed-header table thead tr').length, 1, 'Fixed header present');
|
||||||
equal($table.find('> table.body tbody').size(), 1, 'Body table present');
|
equal($table.find('> table.body tbody').length, 1, 'Body table present');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Fields: basic', function() {
|
test('Fields: basic', function() {
|
||||||
|
|
@ -60,7 +60,7 @@
|
||||||
});
|
});
|
||||||
var $fields = $listView.find('.fixed-header table thead tr th');
|
var $fields = $listView.find('.fixed-header table thead tr th');
|
||||||
|
|
||||||
equal($fields.size(), 1, 'Column present');
|
equal($fields.length, 1, 'Column present');
|
||||||
ok($fields.hasClass('fieldA'), 'Has ID as classname');
|
ok($fields.hasClass('fieldA'), 'Has ID as classname');
|
||||||
equal($fields.html(), 'TestFieldA', 'Has correct label');
|
equal($fields.html(), 'TestFieldA', 'Has correct label');
|
||||||
});
|
});
|
||||||
|
|
@ -82,7 +82,7 @@
|
||||||
$.each(testFields, function(k, v) {
|
$.each(testFields, function(k, v) {
|
||||||
var $field = $fields.filter('.' + k);
|
var $field = $fields.filter('.' + k);
|
||||||
|
|
||||||
equal($field.size(), 1, k + '-> Column present');
|
equal($field.length, 1, k + '-> Column present');
|
||||||
equal($field.html(), v.label, k + '-> Has correct label');
|
equal($field.html(), v.label, k + '-> Has correct label');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -90,8 +90,8 @@
|
||||||
test('Data loading state', function() {
|
test('Data loading state', function() {
|
||||||
var $listView = listView();
|
var $listView = listView();
|
||||||
|
|
||||||
equal($listView.find('table.body tr.loading').size(), 1, 'Row has loading state');
|
equal($listView.find('table.body tr.loading').length, 1, 'Row has loading state');
|
||||||
equal($listView.find('table.body tr.loading td.loading.icon').size(), 1, 'Row cell has loading icon');
|
equal($listView.find('table.body tr.loading td.loading.icon').length, 1, 'Row cell has loading icon');
|
||||||
});
|
});
|
||||||
|
|
||||||
asyncTest('Data provider: basic', function() {
|
asyncTest('Data provider: basic', function() {
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
equal($listView.find('.data-table table.body tbody tr.empty td').size(), 1, 'Body table has empty table row');
|
equal($listView.find('.data-table table.body tbody tr.empty td').length, 1, 'Body table has empty table row');
|
||||||
equal($listView.find('.data-table table.body tbody tr.empty td').html(), 'label.no.data', 'Empty contents notice displayed');
|
equal($listView.find('.data-table table.body tbody tr.empty td').html(), 'label.no.data', 'Empty contents notice displayed');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -134,8 +134,8 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
equal($listView.find('table.body tbody tr').size(), 1, 'Body table has table row');
|
equal($listView.find('table.body tbody tr').length, 1, 'Body table has table row');
|
||||||
equal($listView.find('table.body tbody tr td').size(), 2, 'Body table has table cells');
|
equal($listView.find('table.body tbody tr td').length, 2, 'Body table has table cells');
|
||||||
equal($listView.find('table.body tbody tr td.fieldA > span').html(), 'FieldDataA', 'FieldDataA content present');
|
equal($listView.find('table.body tbody tr td.fieldA > span').html(), 'FieldDataA', 'FieldDataA content present');
|
||||||
equal($listView.find('table.body tbody tr td.fieldB > span').html(), 'FieldDataB', 'FieldDataB content present');
|
equal($listView.find('table.body tbody tr td.fieldB > span').html(), 'FieldDataB', 'FieldDataB content present');
|
||||||
});
|
});
|
||||||
|
|
@ -163,7 +163,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
equal($listView.find('table.body tbody tr').size(), 3, 'Body table has correct # of table rows');
|
equal($listView.find('table.body tbody tr').length, 3, 'Body table has correct # of table rows');
|
||||||
|
|
||||||
$(testData).map(function(index, data) {
|
$(testData).map(function(index, data) {
|
||||||
var $tr = $listView.find('table.body tbody tr').filter(function() {
|
var $tr = $listView.find('table.body tbody tr').filter(function() {
|
||||||
|
|
@ -198,9 +198,9 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
equal($listView.find('table tr th').size(), 2, 'Correct number of header columns present');
|
equal($listView.find('table tr th').length, 2, 'Correct number of header columns present');
|
||||||
equal($listView.find('table.body tbody tr td').size(), 2, 'Correct number of data body columns present');
|
equal($listView.find('table.body tbody tr td').length, 2, 'Correct number of data body columns present');
|
||||||
ok(!$listView.find('table.body tbody td.fieldHidden').size(), 'Hidden field not present');
|
ok(!$listView.find('table.body tbody td.fieldHidden').length, 'Hidden field not present');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Filter dropdown', function() {
|
test('Filter dropdown', function() {
|
||||||
|
|
@ -229,7 +229,7 @@
|
||||||
var $filters = $listView.find('.filters select');
|
var $filters = $listView.find('.filters select');
|
||||||
|
|
||||||
var testFilterDropdownContent = function() {
|
var testFilterDropdownContent = function() {
|
||||||
equal($filters.find('option').size(), 2, 'Correct # of filters present');
|
equal($filters.find('option').length, 2, 'Correct # of filters present');
|
||||||
equal($filters.find('option:first').html(), 'FilterOnLabel', 'Filter on label present');
|
equal($filters.find('option:first').html(), 'FilterOnLabel', 'Filter on label present');
|
||||||
equal($filters.find('option:last').html(), 'FilterOffLabel', 'Filter off label present');
|
equal($filters.find('option:last').html(), 'FilterOffLabel', 'Filter off label present');
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue