mirror of
https://github.com/grafana/grafana.git
synced 2025-02-13 17:15:40 -06:00
Switch styles to LESS build, add inspector.html, update flot
This commit is contained in:
parent
c87ca77033
commit
58256acb81
16
Gruntfile.js
16
Gruntfile.js
@ -46,14 +46,28 @@ module.exports = function (grunt) {
|
||||
moment: false
|
||||
}
|
||||
}
|
||||
},
|
||||
less: {
|
||||
production: {
|
||||
options: {
|
||||
paths: ["vendor/bootstrap/less"],
|
||||
yuicompress:true
|
||||
},
|
||||
files: {
|
||||
"common/css/bootstrap.dark.min.css": "vendor/bootstrap/less/bootstrap.dark.less",
|
||||
"common/css/bootstrap.light.min.css": "vendor/bootstrap/less/bootstrap.light.less"
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// load plugins
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('assemble-less');
|
||||
|
||||
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', ['jshint']);
|
||||
grunt.registerTask('default', ['jshint','less']);
|
||||
|
||||
};
|
||||
|
7066
common/css/bootstrap.dark.min.css
vendored
7066
common/css/bootstrap.dark.min.css
vendored
File diff suppressed because one or more lines are too long
4748
common/css/bootstrap.light.min.css
vendored
4748
common/css/bootstrap.light.min.css
vendored
File diff suppressed because one or more lines are too long
@ -132,10 +132,20 @@
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
width: 770px;
|
||||
margin-left: -385px;
|
||||
top: 10px !important;
|
||||
}
|
||||
|
||||
.tiny {
|
||||
font-size: 50%;
|
||||
}
|
||||
|
||||
.smaller {
|
||||
font-size: 70%;
|
||||
}
|
||||
|
||||
.small {
|
||||
font-size: 85%;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/* Flot plugin for rendering pie charts.
|
||||
|
||||
Copyright (c) 2007-2012 IOLA and Ole Laursen.
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
The plugin assumes that each series has a single data value, and that each
|
||||
@ -57,22 +57,22 @@ More detail and specific examples can be found in the included HTML file.
|
||||
|
||||
(function($) {
|
||||
|
||||
// Maximum redraw attempts when fitting labels within the plot
|
||||
|
||||
var REDRAW_ATTEMPTS = 10;
|
||||
|
||||
// Factor by which to shrink the pie when fitting labels within the plot
|
||||
|
||||
var REDRAW_SHRINK = 0.95;
|
||||
|
||||
function init(plot) {
|
||||
|
||||
var canvas = null,
|
||||
canvasWidth = 0,
|
||||
canvasHeight = 0,
|
||||
target = null,
|
||||
maxRadius = null,
|
||||
centerLeft = null,
|
||||
centerTop = null,
|
||||
total = 0,
|
||||
redraw = true,
|
||||
redrawAttempts = 10,
|
||||
shrink = 0.95,
|
||||
legendWidth = 0,
|
||||
processed = false,
|
||||
raw = false,
|
||||
ctx = null;
|
||||
|
||||
// interactive variables
|
||||
@ -81,16 +81,9 @@ More detail and specific examples can be found in the included HTML file.
|
||||
|
||||
// add hook to determine if pie plugin in enabled, and then perform necessary operations
|
||||
|
||||
plot.hooks.processOptions.push(checkPieEnabled);
|
||||
plot.hooks.bindEvents.push(bindEvents);
|
||||
|
||||
// check to see if the pie plugin is enabled
|
||||
|
||||
function checkPieEnabled(plot, options) {
|
||||
plot.hooks.processOptions.push(function(plot, options) {
|
||||
if (options.series.pie.show) {
|
||||
|
||||
//disable grid
|
||||
|
||||
options.grid.show = false;
|
||||
|
||||
// set labels.show
|
||||
@ -120,21 +113,10 @@ More detail and specific examples can be found in the included HTML file.
|
||||
} else if (options.series.pie.tilt < 0) {
|
||||
options.series.pie.tilt = 0;
|
||||
}
|
||||
|
||||
// add processData hook to do transformations on the data
|
||||
|
||||
plot.hooks.processDatapoints.push(processDatapoints);
|
||||
plot.hooks.drawOverlay.push(drawOverlay);
|
||||
|
||||
// draw hook
|
||||
|
||||
plot.hooks.draw.push(draw);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// bind hoverable events
|
||||
|
||||
function bindEvents(plot, eventHolder) {
|
||||
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
||||
var options = plot.getOptions();
|
||||
if (options.series.pie.show) {
|
||||
if (options.grid.hoverable) {
|
||||
@ -144,47 +126,30 @@ More detail and specific examples can be found in the included HTML file.
|
||||
eventHolder.unbind("click").click(onClick);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// debugging function that prints out an object
|
||||
|
||||
function alertObject(obj) {
|
||||
|
||||
var msg = "";
|
||||
|
||||
function traverse(obj, depth) {
|
||||
|
||||
if (!depth) {
|
||||
depth = 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < obj.length; ++i) {
|
||||
for (var j = 0; j < depth; j++) {
|
||||
msg += "\t";
|
||||
}
|
||||
if( typeof obj[i] == "object") {
|
||||
msg += "" + i + ":\n";
|
||||
traverse(obj[i], depth + 1);
|
||||
} else {
|
||||
msg += "" + i + ": " + obj[i] + "\n";
|
||||
}
|
||||
}
|
||||
plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
|
||||
var options = plot.getOptions();
|
||||
if (options.series.pie.show) {
|
||||
processDatapoints(plot, series, data, datapoints);
|
||||
}
|
||||
});
|
||||
|
||||
traverse(obj);
|
||||
alert(msg);
|
||||
}
|
||||
|
||||
function calcTotal(data) {
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var item = parseFloat(data[i].data[0][1]);
|
||||
if (item) {
|
||||
total += item;
|
||||
}
|
||||
plot.hooks.drawOverlay.push(function(plot, octx) {
|
||||
var options = plot.getOptions();
|
||||
if (options.series.pie.show) {
|
||||
drawOverlay(plot, octx);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function processDatapoints(plot, series, data, datapoints) {
|
||||
plot.hooks.draw.push(function(plot, newCtx) {
|
||||
var options = plot.getOptions();
|
||||
if (options.series.pie.show) {
|
||||
draw(plot, newCtx);
|
||||
}
|
||||
});
|
||||
|
||||
function processDatapoints(plot, series, datapoints) {
|
||||
if (!processed) {
|
||||
processed = true;
|
||||
canvas = plot.getCanvas();
|
||||
@ -194,9 +159,127 @@ More detail and specific examples can be found in the included HTML file.
|
||||
}
|
||||
}
|
||||
|
||||
function setupPie() {
|
||||
function combine(data) {
|
||||
|
||||
legendWidth = target.children().filter(".legend").children().width() || 0;
|
||||
var total = 0,
|
||||
combined = 0,
|
||||
numCombined = 0,
|
||||
color = options.series.pie.combine.color,
|
||||
newdata = [];
|
||||
|
||||
// Fix up the raw data from Flot, ensuring the data is numeric
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
|
||||
var value = data[i].data;
|
||||
|
||||
// If the data is an array, we'll assume that it's a standard
|
||||
// Flot x-y pair, and are concerned only with the second value.
|
||||
|
||||
// Note how we use the original array, rather than creating a
|
||||
// new one; this is more efficient and preserves any extra data
|
||||
// that the user may have stored in higher indexes.
|
||||
|
||||
if ($.isArray(value) && value.length == 1) {
|
||||
value = value[0];
|
||||
}
|
||||
|
||||
if ($.isArray(value)) {
|
||||
// Equivalent to $.isNumeric() but compatible with jQuery < 1.7
|
||||
if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
|
||||
value[1] = +value[1];
|
||||
} else {
|
||||
value[1] = 0;
|
||||
}
|
||||
} else if (!isNaN(parseFloat(value)) && isFinite(value)) {
|
||||
value = [1, +value];
|
||||
} else {
|
||||
value = [1, 0];
|
||||
}
|
||||
|
||||
data[i].data = [value];
|
||||
}
|
||||
|
||||
// Sum up all the slices, so we can calculate percentages for each
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
total += data[i].data[0][1];
|
||||
}
|
||||
|
||||
// Count the number of slices with percentages below the combine
|
||||
// threshold; if it turns out to be just one, we won't combine.
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var value = data[i].data[0][1];
|
||||
if (value / total <= options.series.pie.combine.threshold) {
|
||||
combined += value;
|
||||
numCombined++;
|
||||
if (!color) {
|
||||
color = data[i].color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
var value = data[i].data[0][1];
|
||||
if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
|
||||
newdata.push({
|
||||
data: [[1, value]],
|
||||
color: data[i].color,
|
||||
label: data[i].label,
|
||||
angle: value * Math.PI * 2 / total,
|
||||
percent: value / (total / 100)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (numCombined > 1) {
|
||||
newdata.push({
|
||||
data: [[1, combined]],
|
||||
color: color,
|
||||
label: options.series.pie.combine.label,
|
||||
angle: combined * Math.PI * 2 / total,
|
||||
percent: combined / (total / 100)
|
||||
});
|
||||
}
|
||||
|
||||
return newdata;
|
||||
}
|
||||
|
||||
function draw(plot, newCtx) {
|
||||
|
||||
if (!target) {
|
||||
return; // if no series were passed
|
||||
}
|
||||
|
||||
var canvasWidth = plot.getPlaceholder().width(),
|
||||
canvasHeight = plot.getPlaceholder().height(),
|
||||
legendWidth = target.children().filter(".legend").children().width() || 0;
|
||||
|
||||
ctx = newCtx;
|
||||
|
||||
// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
|
||||
|
||||
// When combining smaller slices into an 'other' slice, we need to
|
||||
// add a new series. Since Flot gives plugins no way to modify the
|
||||
// list of series, the pie plugin uses a hack where the first call
|
||||
// to processDatapoints results in a call to setData with the new
|
||||
// list of series, then subsequent processDatapoints do nothing.
|
||||
|
||||
// The plugin-global 'processed' flag is used to control this hack;
|
||||
// it starts out false, and is set to true after the first call to
|
||||
// processDatapoints.
|
||||
|
||||
// Unfortunately this turns future setData calls into no-ops; they
|
||||
// call processDatapoints, the flag is true, and nothing happens.
|
||||
|
||||
// To fix this we'll set the flag back to false here in draw, when
|
||||
// all series have been processed, so the next sequence of calls to
|
||||
// processDatapoints once again starts out with a slice-combine.
|
||||
// This is really a hack; in 0.9 we need to give plugins a proper
|
||||
// way to modify series before any processing begins.
|
||||
|
||||
processed = false;
|
||||
|
||||
// calculate maximum radius and center point
|
||||
|
||||
@ -219,111 +302,29 @@ More detail and specific examples can be found in the included HTML file.
|
||||
} else if (centerLeft > canvasWidth - maxRadius) {
|
||||
centerLeft = canvasWidth - maxRadius;
|
||||
}
|
||||
}
|
||||
|
||||
function fixData(data) {
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
if (typeof(data[i].data) == "number") {
|
||||
data[i].data = [[1, data[i].data]];
|
||||
} else if (typeof(data[i].data) == "undefined" || typeof(data[i].data[0]) == "undefined") {
|
||||
if (typeof(data[i].data) != "undefined" && typeof(data[i].data.label) != "undefined") {
|
||||
data[i].label = data[i].data.label; // fix weirdness coming from flot
|
||||
}
|
||||
data[i].data = [[1, 0]];
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
var slices = plot.getData(),
|
||||
attempts = 0;
|
||||
|
||||
function combine(data) {
|
||||
// Keep shrinking the pie's radius until drawPie returns true,
|
||||
// indicating that all the labels fit, or we try too many times.
|
||||
|
||||
data = fixData(data);
|
||||
calcTotal(data);
|
||||
|
||||
var combined = 0;
|
||||
var numCombined = 0;
|
||||
var color = options.series.pie.combine.color;
|
||||
var newdata = [];
|
||||
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
|
||||
// make sure its a number
|
||||
|
||||
data[i].data[0][1] = parseFloat(data[i].data[0][1]);
|
||||
|
||||
if (!data[i].data[0][1]) {
|
||||
data[i].data[0][1] = 0;
|
||||
}
|
||||
|
||||
if (data[i].data[0][1] / total <= options.series.pie.combine.threshold) {
|
||||
combined += data[i].data[0][1];
|
||||
numCombined++;
|
||||
if (!color) {
|
||||
color = data[i].color;
|
||||
}
|
||||
} else {
|
||||
newdata.push({
|
||||
data: [[1, data[i].data[0][1]]],
|
||||
color: data[i].color,
|
||||
label: data[i].label,
|
||||
angle: data[i].data[0][1] * Math.PI * 2 / total,
|
||||
percent: data[i].data[0][1] / (total / 100)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (numCombined > 0) {
|
||||
newdata.push({
|
||||
data: [[1, combined]],
|
||||
color: color,
|
||||
label: options.series.pie.combine.label,
|
||||
angle: combined * Math.PI * 2 / total,
|
||||
percent: combined / (total / 100)
|
||||
});
|
||||
}
|
||||
|
||||
return newdata;
|
||||
}
|
||||
|
||||
function draw(plot, newCtx) {
|
||||
|
||||
if (!target) {
|
||||
return; // if no series were passed
|
||||
}
|
||||
|
||||
canvasWidth = plot.getPlaceholder().width();
|
||||
canvasHeight = plot.getPlaceholder().height();
|
||||
|
||||
ctx = newCtx;
|
||||
setupPie();
|
||||
|
||||
var slices = plot.getData();
|
||||
var attempts = 0;
|
||||
|
||||
while (redraw && attempts<redrawAttempts) {
|
||||
redraw = false;
|
||||
do {
|
||||
if (attempts > 0) {
|
||||
maxRadius *= shrink;
|
||||
maxRadius *= REDRAW_SHRINK;
|
||||
}
|
||||
attempts += 1;
|
||||
clear();
|
||||
if (options.series.pie.tilt <= 0.8) {
|
||||
drawShadow();
|
||||
}
|
||||
drawPie();
|
||||
}
|
||||
} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
|
||||
|
||||
if (attempts >= redrawAttempts) {
|
||||
if (attempts >= REDRAW_ATTEMPTS) {
|
||||
clear();
|
||||
target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
|
||||
}
|
||||
|
||||
// Reset the redraw flag on success, so the loop above can run
|
||||
// again in the event of a resize or other update.
|
||||
// TODO: We should remove this redraw system entirely!
|
||||
|
||||
redraw = true;
|
||||
|
||||
if (plot.setSeries && plot.insertLegend) {
|
||||
plot.setSeries(slices);
|
||||
plot.insertLegend();
|
||||
@ -408,14 +409,13 @@ More detail and specific examples can be found in the included HTML file.
|
||||
|
||||
drawDonutHole(ctx);
|
||||
|
||||
// draw labels
|
||||
ctx.restore();
|
||||
|
||||
// Draw the labels, returning true if they fit within the plot
|
||||
|
||||
if (options.series.pie.label.show) {
|
||||
drawLabels();
|
||||
}
|
||||
|
||||
// restore to original state
|
||||
ctx.restore();
|
||||
return drawLabels();
|
||||
} else return true;
|
||||
|
||||
function drawSlice(angle, color, fill) {
|
||||
|
||||
@ -456,14 +456,19 @@ More detail and specific examples can be found in the included HTML file.
|
||||
|
||||
for (var i = 0; i < slices.length; ++i) {
|
||||
if (slices[i].percent >= options.series.pie.label.threshold * 100) {
|
||||
drawLabel(slices[i], currentAngle, i);
|
||||
if (!drawLabel(slices[i], currentAngle, i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
currentAngle += slices[i].angle;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
function drawLabel(slice, startAngle, index) {
|
||||
|
||||
if (slice.data[0][1] == 0) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// format label text
|
||||
@ -497,7 +502,7 @@ More detail and specific examples can be found in the included HTML file.
|
||||
// check to make sure that the label is not outside the canvas
|
||||
|
||||
if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
|
||||
redraw = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options.series.pie.label.background.opacity != 0) {
|
||||
@ -515,6 +520,8 @@ More detail and specific examples can be found in the included HTML file.
|
||||
.css("opacity", options.series.pie.label.background.opacity)
|
||||
.insertBefore(label);
|
||||
}
|
||||
|
||||
return true;
|
||||
} // end individual label function
|
||||
} // end drawLabels function
|
||||
} // end drawPie function
|
||||
|
@ -6,10 +6,10 @@ Licensed under the MIT license.
|
||||
The plugin supports these options:
|
||||
|
||||
selection: {
|
||||
mode: null or "x" or "y" or "xy",
|
||||
color: color,
|
||||
shape: "round" or "miter" or "bevel",
|
||||
minSize: number of pixels
|
||||
mode: null or "x" or "y" or "xy",
|
||||
color: color,
|
||||
shape: "round" or "miter" or "bevel",
|
||||
minSize: number of pixels
|
||||
}
|
||||
|
||||
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
|
||||
@ -33,11 +33,11 @@ When selection support is enabled, a "plotselected" event will be emitted on
|
||||
the DOM element you passed into the plot function. The event handler gets a
|
||||
parameter with the ranges selected on the axes, like this:
|
||||
|
||||
placeholder.bind( "plotselected", function( event, ranges ) {
|
||||
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
||||
// similar for yaxis - with multiple axes, the extra ones are in
|
||||
// x2axis, x3axis, ...
|
||||
});
|
||||
placeholder.bind( "plotselected", function( event, ranges ) {
|
||||
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
||||
// similar for yaxis - with multiple axes, the extra ones are in
|
||||
// x2axis, x3axis, ...
|
||||
});
|
||||
|
||||
The "plotselected" event is only fired when the user has finished making the
|
||||
selection. A "plotselecting" event is fired during the process with the same
|
||||
@ -58,7 +58,7 @@ The plugin allso adds the following methods to the plot object:
|
||||
an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
|
||||
this:
|
||||
|
||||
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
||||
setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
|
||||
|
||||
setSelection will trigger the "plotselected" event when called. If you don't
|
||||
want that to happen, e.g. if you're inside a "plotselected" handler, pass
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Flot plugin for stacking data sets rather than overlyaing them.
|
||||
|
||||
Copyright (c) 2007-2012 IOLA and Ole Laursen.
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
The plugin assumes the data is sorted on x (or y if stacking horizontally).
|
||||
@ -15,7 +15,7 @@ key (which can be any number or string or just "true"). To specify the default
|
||||
stack, you can set the stack option like this:
|
||||
|
||||
series: {
|
||||
stack: null or true or key (number/string)
|
||||
stack: null/false, true, or a key (number/string)
|
||||
}
|
||||
|
||||
You can also specify it for a single series, like this:
|
||||
@ -55,7 +55,7 @@ charts or filled areas).
|
||||
}
|
||||
|
||||
function stackData(plot, s, datapoints) {
|
||||
if (s.stack == null)
|
||||
if (s.stack == null || s.stack === false)
|
||||
return;
|
||||
|
||||
var other = findMatchingSeries(s, plot.getData());
|
||||
@ -186,130 +186,3 @@ charts or filled areas).
|
||||
version: '1.2'
|
||||
});
|
||||
})(jQuery);
|
||||
|
||||
(function ($) {
|
||||
var options = {
|
||||
series: {
|
||||
stackpercent: null
|
||||
} // or number/string
|
||||
};
|
||||
|
||||
function init(plot) {
|
||||
|
||||
// will be built up dynamically as a hash from x-value, or y-value if horizontal
|
||||
var stackBases = {};
|
||||
var processed = false;
|
||||
var stackSums = {};
|
||||
|
||||
//set percentage for stacked chart
|
||||
function processRawData(plot, series, data, datapoints) {
|
||||
if (!processed) {
|
||||
processed = true;
|
||||
stackSums = getStackSums(plot.getData());
|
||||
}
|
||||
if (series.stackpercent == true) {
|
||||
var num = data.length;
|
||||
series.percents = [];
|
||||
var key_idx = 0;
|
||||
var value_idx = 1;
|
||||
if (series.bars && series.bars.horizontal && series.bars.horizontal === true) {
|
||||
key_idx = 1;
|
||||
value_idx = 0;
|
||||
}
|
||||
for (var j = 0; j < num; j++) {
|
||||
var sum = stackSums[data[j][key_idx] + ""];
|
||||
if (sum > 0) {
|
||||
series.percents.push(data[j][value_idx] * 100 / sum);
|
||||
} else {
|
||||
series.percents.push(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//calculate summary
|
||||
function getStackSums(_data) {
|
||||
var data_len = _data.length;
|
||||
var sums = {};
|
||||
if (data_len > 0) {
|
||||
//caculate summary
|
||||
for (var i = 0; i < data_len; i++) {
|
||||
if (_data[i].stackpercent) {
|
||||
var key_idx = 0;
|
||||
var value_idx = 1;
|
||||
if (_data[i].bars && _data[i].bars.horizontal && _data[i].bars.horizontal === true) {
|
||||
key_idx = 1;
|
||||
value_idx = 0;
|
||||
}
|
||||
var num = _data[i].data.length;
|
||||
for (var j = 0; j < num; j++) {
|
||||
var value = 0;
|
||||
if (_data[i].data[j][1] != null) {
|
||||
value = _data[i].data[j][value_idx];
|
||||
}
|
||||
if (sums[_data[i].data[j][key_idx] + ""]) {
|
||||
sums[_data[i].data[j][key_idx] + ""] += value;
|
||||
} else {
|
||||
sums[_data[i].data[j][key_idx] + ""] = value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return sums;
|
||||
}
|
||||
|
||||
function stackData(plot, s, datapoints) {
|
||||
if (!s.stackpercent) return;
|
||||
if (!processed) {
|
||||
stackSums = getStackSums(plot.getData());
|
||||
}
|
||||
var newPoints = [];
|
||||
|
||||
|
||||
var key_idx = 0;
|
||||
var value_idx = 1;
|
||||
if (s.bars && s.bars.horizontal && s.bars.horizontal === true) {
|
||||
key_idx = 1;
|
||||
value_idx = 0;
|
||||
}
|
||||
|
||||
for (var i = 0; i < datapoints.points.length; i += 3) {
|
||||
// note that the values need to be turned into absolute y-values.
|
||||
// in other words, if you were to stack (x, y1), (x, y2), and (x, y3),
|
||||
// (each from different series, which is where stackBases comes in),
|
||||
// you'd want the new points to be (x, y1, 0), (x, y1+y2, y1), (x, y1+y2+y3, y1+y2)
|
||||
// generally, (x, thisValue + (base up to this point), + (base up to this point))
|
||||
if (!stackBases[datapoints.points[i + key_idx]]) {
|
||||
stackBases[datapoints.points[i + key_idx]] = 0;
|
||||
}
|
||||
newPoints[i + key_idx] = datapoints.points[i + key_idx];
|
||||
newPoints[i + value_idx] = datapoints.points[i + value_idx] + stackBases[datapoints.points[i + key_idx]];
|
||||
newPoints[i + 2] = stackBases[datapoints.points[i + key_idx]];
|
||||
stackBases[datapoints.points[i + key_idx]] += datapoints.points[i + value_idx];
|
||||
// change points to percentage values
|
||||
// you may need to set yaxis:{ max = 100 }
|
||||
if ( stackSums[newPoints[i+key_idx]+""] > 0 ){
|
||||
newPoints[i + value_idx] = newPoints[i + value_idx] * 100 / stackSums[newPoints[i + key_idx] + ""];
|
||||
newPoints[i + 2] = newPoints[i + 2] * 100 / stackSums[newPoints[i + key_idx] + ""];
|
||||
} else {
|
||||
newPoints[i + value_idx] = 0;
|
||||
newPoints[i + 2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
datapoints.points = newPoints;
|
||||
}
|
||||
|
||||
plot.hooks.processRawData.push(processRawData);
|
||||
plot.hooks.processDatapoints.push(stackData);
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
options: options,
|
||||
name: 'stackpercent',
|
||||
version: '0.1'
|
||||
});
|
||||
})(jQuery);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* Pretty handling of time axes.
|
||||
|
||||
Copyright (c) 2007-2012 IOLA and Ole Laursen.
|
||||
Copyright (c) 2007-2013 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
|
||||
Set axis.mode to "time" to enable. See the section "Time series data" in
|
||||
@ -10,7 +10,14 @@ API.txt for details.
|
||||
|
||||
(function($) {
|
||||
|
||||
var options = {};
|
||||
var options = {
|
||||
xaxis: {
|
||||
timezone: null, // "browser" for local to the client or timezone for timezone-js
|
||||
timeformat: null, // format string to use
|
||||
twelveHourClock: false, // 12 or 24 time in time mode
|
||||
monthNames: null // list of names of months
|
||||
}
|
||||
};
|
||||
|
||||
// round to nearby lower multiple of base
|
||||
|
||||
@ -66,6 +73,7 @@ API.txt for details.
|
||||
case 'b': c = "" + monthNames[d.getMonth()]; break;
|
||||
case 'd': c = leftPad(d.getDate()); break;
|
||||
case 'e': c = leftPad(d.getDate(), " "); break;
|
||||
case 'h': // For back-compat with 0.7; remove in 1.0
|
||||
case 'H': c = leftPad(hours); break;
|
||||
case 'I': c = leftPad(hours12); break;
|
||||
case 'l': c = leftPad(hours12, " "); break;
|
||||
@ -187,7 +195,7 @@ API.txt for details.
|
||||
[1, "year"]]);
|
||||
|
||||
function init(plot) {
|
||||
plot.hooks.processDatapoints.push(function (plot, series, datapoints) {
|
||||
plot.hooks.processOptions.push(function (plot, options) {
|
||||
$.each(plot.getAxes(), function(axisName, axis) {
|
||||
|
||||
var opts = axis.options;
|
||||
@ -287,17 +295,23 @@ API.txt for details.
|
||||
|
||||
if (step >= timeUnitSize.minute) {
|
||||
d.setSeconds(0);
|
||||
} else if (step >= timeUnitSize.hour) {
|
||||
}
|
||||
if (step >= timeUnitSize.hour) {
|
||||
d.setMinutes(0);
|
||||
} else if (step >= timeUnitSize.day) {
|
||||
}
|
||||
if (step >= timeUnitSize.day) {
|
||||
d.setHours(0);
|
||||
} else if (step >= timeUnitSize.day * 4) {
|
||||
}
|
||||
if (step >= timeUnitSize.day * 4) {
|
||||
d.setDate(1);
|
||||
} else if (step >= timeUnitSize.month * 2) {
|
||||
}
|
||||
if (step >= timeUnitSize.month * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 3));
|
||||
} else if (step >= timeUnitSize.quarter * 2) {
|
||||
}
|
||||
if (step >= timeUnitSize.quarter * 2) {
|
||||
d.setMonth(floorInBase(d.getMonth(), 6));
|
||||
} else if (step >= timeUnitSize.year) {
|
||||
}
|
||||
if (step >= timeUnitSize.year) {
|
||||
d.setMonth(0);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
<link rel="stylesheet" href="common/css/animate.min.css">
|
||||
<link rel="stylesheet" href="common/css/bootstrap-responsive.min.css">
|
||||
<link rel="stylesheet" href="common/css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="common/css/main.css">
|
||||
<link rel="stylesheet" href="common/css/timepicker.css">
|
||||
|
||||
<!-- project dependency libs -->
|
||||
@ -26,13 +25,15 @@
|
||||
<script src="config.js"></script>
|
||||
<script src="js/app.js"></script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body ng-controller="DashCtrl" ng-cloak>
|
||||
<div ng-repeat='alert in global_alert' class="alert alert-{{alert.severity}} span12" style="position: fixed;top:2px;opacity:0.9;z-index:8000">
|
||||
<button type="button" class="close" ng-click="clear_alert(alert)">×</button>
|
||||
<strong>{{alert.title}}</strong> <span ng-bind-html-unsafe='alert.text'></span> <div class='pull-right small'> {{$index + 1}} alert(s) </div>
|
||||
<div ng-repeat='alert in global_alert' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
|
||||
<button type="button" class="close" ng-click="clear_alert(alert)" style="padding-right:50px">×</button>
|
||||
<strong>{{alert.title}}</strong> <span ng-bind-html-unsafe='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
|
||||
</div>
|
||||
<div class="navbar navbar-static-top">
|
||||
<div class="navbar-inner">
|
||||
|
@ -7,11 +7,15 @@ angular.module('kibana.directives', [])
|
||||
return {
|
||||
restrict: 'E',
|
||||
link: function(scope, elem, attrs) {
|
||||
var template = '<img src="common/img/load.gif" class="panel-loading" ng-show="panelMeta.loading == true">'+
|
||||
var template = '<i class="icon-spinner small icon-spin icon-large panel-loading" '+
|
||||
'ng-show="panelMeta.loading == true && !panel.title"></i>'+
|
||||
' <span class="editlink panelextra pointer" style="right:15px;top:0px" ' +
|
||||
'bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
|
||||
'<span class="small">{{panel.type}}</span> <i class="icon-cog pointer"></i> '+
|
||||
'</span><h4>{{panel.title}}</h4>';
|
||||
'</span><h4>'+
|
||||
'{{panel.title}} '+
|
||||
'<i class="icon-spinner smaller icon-spin icon-large" ng-show="panelMeta.loading == true && panel.title"></i>'+
|
||||
'</h4>';
|
||||
elem.prepend($compile(angular.element(template))(scope));
|
||||
}
|
||||
};
|
||||
|
@ -8,7 +8,8 @@
|
||||
"devDependencies": {
|
||||
"grunt": "~0.4.0",
|
||||
"grunt-contrib": "~0.7.0",
|
||||
"grunt-contrib-jshint": "~0.6.0"
|
||||
"grunt-contrib-jshint": "~0.6.0",
|
||||
"assemble-less": "~0.4.8"
|
||||
},
|
||||
"license": "Apache License"
|
||||
}
|
||||
|
@ -165,6 +165,7 @@ angular.module('kibana.histogram', [])
|
||||
data = [];
|
||||
if(filterSrv.idsByType('time').length > 0) {
|
||||
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
|
||||
//data = [];
|
||||
}
|
||||
hits = 0;
|
||||
} else {
|
||||
@ -313,7 +314,7 @@ angular.module('kibana.histogram', [])
|
||||
lineWidth: scope.panel.linewidth,
|
||||
steps: false
|
||||
},
|
||||
bars: { show: scope.panel.bars, fill: 1, barWidth: barwidth/1.8 },
|
||||
bars: { show: scope.panel.bars, fill: 1, barWidth: barwidth/1.8, zero: false },
|
||||
points: { show: scope.panel.points, fill: 1, fillColor: false, radius: 5},
|
||||
shadowSize: 1
|
||||
},
|
||||
@ -321,22 +322,21 @@ angular.module('kibana.histogram', [])
|
||||
show: scope.panel['y-axis'],
|
||||
min: 0,
|
||||
max: scope.panel.percentage && scope.panel.stack ? 100 : null,
|
||||
color: "#c8c8c8"
|
||||
},
|
||||
xaxis: {
|
||||
timezone: scope.panel.timezone,
|
||||
show: scope.panel['x-axis'],
|
||||
mode: "time",
|
||||
min: scope.range.from.getTime(),
|
||||
max: scope.range.to.getTime(),
|
||||
timeformat: time_format(scope.panel.interval),
|
||||
label: "Datetime",
|
||||
color: "#c8c8c8",
|
||||
},
|
||||
grid: {
|
||||
backgroundColor: null,
|
||||
borderWidth: 0,
|
||||
borderColor: '#eee',
|
||||
color: "#eee",
|
||||
hoverable: true,
|
||||
color: '#c8c8c8'
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div class="span8">
|
||||
<h6>Columns <small>Click to remove</small></h6>
|
||||
<span style="margin-left:3px" ng-click="toggle_field(field)" ng-repeat="field in $parent.panel.fields" class="label remove pointer">{{field}} </span>
|
||||
<span style="margin-left:3px" ng-click="toggle_field(field)" ng-repeat="field in $parent.panel.fields" class="label pointer remove">{{field}} </span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
|
@ -7,7 +7,7 @@
|
||||
<div>
|
||||
<h5>Last Elasticsearch Query</h5>
|
||||
<pre>curl -XGET '{{config.elasticsearch}}/{{dashboard.indices|stringify}}/_search?pretty' -d '{{inspector}}'
|
||||
</pre>"
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
13
vendor/bootstrap/less/overrides.less
vendored
13
vendor/bootstrap/less/overrides.less
vendored
@ -190,3 +190,16 @@
|
||||
.faded {
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
div.flot-text {
|
||||
color: @textColor !important;
|
||||
}
|
||||
|
||||
.dashboard-notice {
|
||||
z-index:8000;
|
||||
margin-left:0px;
|
||||
padding:3px 0px 3px 0px;
|
||||
width:100%;
|
||||
color: @textColor;
|
||||
padding-left:20px;
|
||||
}
|
2
vendor/bootstrap/less/variables.light.less
vendored
2
vendor/bootstrap/less/variables.light.less
vendored
@ -32,7 +32,7 @@
|
||||
|
||||
// Scaffolding
|
||||
// -------------------------
|
||||
@bodyBackground: @white;
|
||||
@bodyBackground: #ffffff;
|
||||
@textColor: @grayDark;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user