mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #312 from rashidkpc/master
Switch styles to LESS build, add inspector.html, update flot
This commit is contained in:
commit
d84adddab7
16
Gruntfile.js
16
Gruntfile.js
@ -46,14 +46,28 @@ module.exports = function (grunt) {
|
|||||||
moment: false
|
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
|
// load plugins
|
||||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
|
grunt.loadNpmTasks('assemble-less');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Default task.
|
// 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;
|
max-width: 500px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
width: 770px;
|
||||||
|
margin-left: -385px;
|
||||||
|
top: 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
.tiny {
|
.tiny {
|
||||||
font-size: 50%;
|
font-size: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.smaller {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
|
||||||
.small {
|
.small {
|
||||||
font-size: 85%;
|
font-size: 85%;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
/* Flot plugin for rendering pie charts.
|
/* 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.
|
Licensed under the MIT license.
|
||||||
|
|
||||||
The plugin assumes that each series has a single data value, and that each
|
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($) {
|
(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) {
|
function init(plot) {
|
||||||
|
|
||||||
var canvas = null,
|
var canvas = null,
|
||||||
canvasWidth = 0,
|
|
||||||
canvasHeight = 0,
|
|
||||||
target = null,
|
target = null,
|
||||||
maxRadius = null,
|
maxRadius = null,
|
||||||
centerLeft = null,
|
centerLeft = null,
|
||||||
centerTop = null,
|
centerTop = null,
|
||||||
total = 0,
|
|
||||||
redraw = true,
|
|
||||||
redrawAttempts = 10,
|
|
||||||
shrink = 0.95,
|
|
||||||
legendWidth = 0,
|
|
||||||
processed = false,
|
processed = false,
|
||||||
raw = false,
|
|
||||||
ctx = null;
|
ctx = null;
|
||||||
|
|
||||||
// interactive variables
|
// 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
|
// add hook to determine if pie plugin in enabled, and then perform necessary operations
|
||||||
|
|
||||||
plot.hooks.processOptions.push(checkPieEnabled);
|
plot.hooks.processOptions.push(function(plot, options) {
|
||||||
plot.hooks.bindEvents.push(bindEvents);
|
|
||||||
|
|
||||||
// check to see if the pie plugin is enabled
|
|
||||||
|
|
||||||
function checkPieEnabled(plot, options) {
|
|
||||||
if (options.series.pie.show) {
|
if (options.series.pie.show) {
|
||||||
|
|
||||||
//disable grid
|
|
||||||
|
|
||||||
options.grid.show = false;
|
options.grid.show = false;
|
||||||
|
|
||||||
// set labels.show
|
// 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) {
|
} else if (options.series.pie.tilt < 0) {
|
||||||
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
|
plot.hooks.bindEvents.push(function(plot, eventHolder) {
|
||||||
|
|
||||||
function bindEvents(plot, eventHolder) {
|
|
||||||
var options = plot.getOptions();
|
var options = plot.getOptions();
|
||||||
if (options.series.pie.show) {
|
if (options.series.pie.show) {
|
||||||
if (options.grid.hoverable) {
|
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);
|
eventHolder.unbind("click").click(onClick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// debugging function that prints out an object
|
plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
|
||||||
|
var options = plot.getOptions();
|
||||||
function alertObject(obj) {
|
if (options.series.pie.show) {
|
||||||
|
processDatapoints(plot, series, data, datapoints);
|
||||||
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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
traverse(obj);
|
plot.hooks.drawOverlay.push(function(plot, octx) {
|
||||||
alert(msg);
|
var options = plot.getOptions();
|
||||||
}
|
if (options.series.pie.show) {
|
||||||
|
drawOverlay(plot, octx);
|
||||||
function calcTotal(data) {
|
|
||||||
for (var i = 0; i < data.length; ++i) {
|
|
||||||
var item = parseFloat(data[i].data[0][1]);
|
|
||||||
if (item) {
|
|
||||||
total += item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
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) {
|
if (!processed) {
|
||||||
processed = true;
|
processed = true;
|
||||||
canvas = plot.getCanvas();
|
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
|
// 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) {
|
} else if (centerLeft > canvasWidth - maxRadius) {
|
||||||
centerLeft = canvasWidth - maxRadius;
|
centerLeft = canvasWidth - maxRadius;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function fixData(data) {
|
var slices = plot.getData(),
|
||||||
for (var i = 0; i < data.length; ++i) {
|
attempts = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
do {
|
||||||
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;
|
|
||||||
if (attempts > 0) {
|
if (attempts > 0) {
|
||||||
maxRadius *= shrink;
|
maxRadius *= REDRAW_SHRINK;
|
||||||
}
|
}
|
||||||
attempts += 1;
|
attempts += 1;
|
||||||
clear();
|
clear();
|
||||||
if (options.series.pie.tilt <= 0.8) {
|
if (options.series.pie.tilt <= 0.8) {
|
||||||
drawShadow();
|
drawShadow();
|
||||||
}
|
}
|
||||||
drawPie();
|
} while (!drawPie() && attempts < REDRAW_ATTEMPTS)
|
||||||
}
|
|
||||||
|
|
||||||
if (attempts >= redrawAttempts) {
|
if (attempts >= REDRAW_ATTEMPTS) {
|
||||||
clear();
|
clear();
|
||||||
target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>");
|
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) {
|
if (plot.setSeries && plot.insertLegend) {
|
||||||
plot.setSeries(slices);
|
plot.setSeries(slices);
|
||||||
plot.insertLegend();
|
plot.insertLegend();
|
||||||
@ -408,14 +409,13 @@ More detail and specific examples can be found in the included HTML file.
|
|||||||
|
|
||||||
drawDonutHole(ctx);
|
drawDonutHole(ctx);
|
||||||
|
|
||||||
// draw labels
|
ctx.restore();
|
||||||
|
|
||||||
|
// Draw the labels, returning true if they fit within the plot
|
||||||
|
|
||||||
if (options.series.pie.label.show) {
|
if (options.series.pie.label.show) {
|
||||||
drawLabels();
|
return drawLabels();
|
||||||
}
|
} else return true;
|
||||||
|
|
||||||
// restore to original state
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
function drawSlice(angle, color, fill) {
|
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) {
|
for (var i = 0; i < slices.length; ++i) {
|
||||||
if (slices[i].percent >= options.series.pie.label.threshold * 100) {
|
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;
|
currentAngle += slices[i].angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
function drawLabel(slice, startAngle, index) {
|
function drawLabel(slice, startAngle, index) {
|
||||||
|
|
||||||
if (slice.data[0][1] == 0) {
|
if (slice.data[0][1] == 0) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// format label text
|
// 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
|
// 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) {
|
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) {
|
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)
|
.css("opacity", options.series.pie.label.background.opacity)
|
||||||
.insertBefore(label);
|
.insertBefore(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
} // end individual label function
|
} // end individual label function
|
||||||
} // end drawLabels function
|
} // end drawLabels function
|
||||||
} // end drawPie function
|
} // end drawPie function
|
||||||
|
@ -6,10 +6,10 @@ Licensed under the MIT license.
|
|||||||
The plugin supports these options:
|
The plugin supports these options:
|
||||||
|
|
||||||
selection: {
|
selection: {
|
||||||
mode: null or "x" or "y" or "xy",
|
mode: null or "x" or "y" or "xy",
|
||||||
color: color,
|
color: color,
|
||||||
shape: "round" or "miter" or "bevel",
|
shape: "round" or "miter" or "bevel",
|
||||||
minSize: number of pixels
|
minSize: number of pixels
|
||||||
}
|
}
|
||||||
|
|
||||||
Selection support is enabled by setting the mode to one of "x", "y" or "xy".
|
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
|
the DOM element you passed into the plot function. The event handler gets a
|
||||||
parameter with the ranges selected on the axes, like this:
|
parameter with the ranges selected on the axes, like this:
|
||||||
|
|
||||||
placeholder.bind( "plotselected", function( event, ranges ) {
|
placeholder.bind( "plotselected", function( event, ranges ) {
|
||||||
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
|
||||||
// similar for yaxis - with multiple axes, the extra ones are in
|
// similar for yaxis - with multiple axes, the extra ones are in
|
||||||
// x2axis, x3axis, ...
|
// x2axis, x3axis, ...
|
||||||
});
|
});
|
||||||
|
|
||||||
The "plotselected" event is only fired when the user has finished making the
|
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
|
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
|
an yaxis range and both xaxis and yaxis if the 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 you don't
|
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
|
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.
|
/* 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.
|
Licensed under the MIT license.
|
||||||
|
|
||||||
The plugin assumes the data is sorted on x (or y if stacking horizontally).
|
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:
|
stack, you can set the stack option like this:
|
||||||
|
|
||||||
series: {
|
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:
|
You can also specify it for a single series, like this:
|
||||||
@ -55,7 +55,7 @@ charts or filled areas).
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stackData(plot, s, datapoints) {
|
function stackData(plot, s, datapoints) {
|
||||||
if (s.stack == null)
|
if (s.stack == null || s.stack === false)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var other = findMatchingSeries(s, plot.getData());
|
var other = findMatchingSeries(s, plot.getData());
|
||||||
@ -186,130 +186,3 @@ charts or filled areas).
|
|||||||
version: '1.2'
|
version: '1.2'
|
||||||
});
|
});
|
||||||
})(jQuery);
|
})(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.
|
/* 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.
|
Licensed under the MIT license.
|
||||||
|
|
||||||
Set axis.mode to "time" to enable. See the section "Time series data" in
|
Set axis.mode to "time" to enable. See the section "Time series data" in
|
||||||
@ -10,7 +10,14 @@ API.txt for details.
|
|||||||
|
|
||||||
(function($) {
|
(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
|
// round to nearby lower multiple of base
|
||||||
|
|
||||||
@ -66,6 +73,7 @@ API.txt for details.
|
|||||||
case 'b': c = "" + monthNames[d.getMonth()]; break;
|
case 'b': c = "" + monthNames[d.getMonth()]; break;
|
||||||
case 'd': c = leftPad(d.getDate()); break;
|
case 'd': c = leftPad(d.getDate()); break;
|
||||||
case 'e': 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 'H': c = leftPad(hours); break;
|
||||||
case 'I': c = leftPad(hours12); break;
|
case 'I': c = leftPad(hours12); break;
|
||||||
case 'l': c = leftPad(hours12, " "); break;
|
case 'l': c = leftPad(hours12, " "); break;
|
||||||
@ -187,7 +195,7 @@ API.txt for details.
|
|||||||
[1, "year"]]);
|
[1, "year"]]);
|
||||||
|
|
||||||
function init(plot) {
|
function init(plot) {
|
||||||
plot.hooks.processDatapoints.push(function (plot, series, datapoints) {
|
plot.hooks.processOptions.push(function (plot, options) {
|
||||||
$.each(plot.getAxes(), function(axisName, axis) {
|
$.each(plot.getAxes(), function(axisName, axis) {
|
||||||
|
|
||||||
var opts = axis.options;
|
var opts = axis.options;
|
||||||
@ -287,17 +295,23 @@ API.txt for details.
|
|||||||
|
|
||||||
if (step >= timeUnitSize.minute) {
|
if (step >= timeUnitSize.minute) {
|
||||||
d.setSeconds(0);
|
d.setSeconds(0);
|
||||||
} else if (step >= timeUnitSize.hour) {
|
}
|
||||||
|
if (step >= timeUnitSize.hour) {
|
||||||
d.setMinutes(0);
|
d.setMinutes(0);
|
||||||
} else if (step >= timeUnitSize.day) {
|
}
|
||||||
|
if (step >= timeUnitSize.day) {
|
||||||
d.setHours(0);
|
d.setHours(0);
|
||||||
} else if (step >= timeUnitSize.day * 4) {
|
}
|
||||||
|
if (step >= timeUnitSize.day * 4) {
|
||||||
d.setDate(1);
|
d.setDate(1);
|
||||||
} else if (step >= timeUnitSize.month * 2) {
|
}
|
||||||
|
if (step >= timeUnitSize.month * 2) {
|
||||||
d.setMonth(floorInBase(d.getMonth(), 3));
|
d.setMonth(floorInBase(d.getMonth(), 3));
|
||||||
} else if (step >= timeUnitSize.quarter * 2) {
|
}
|
||||||
|
if (step >= timeUnitSize.quarter * 2) {
|
||||||
d.setMonth(floorInBase(d.getMonth(), 6));
|
d.setMonth(floorInBase(d.getMonth(), 6));
|
||||||
} else if (step >= timeUnitSize.year) {
|
}
|
||||||
|
if (step >= timeUnitSize.year) {
|
||||||
d.setMonth(0);
|
d.setMonth(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
<link rel="stylesheet" href="common/css/animate.min.css">
|
<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/bootstrap-responsive.min.css">
|
||||||
<link rel="stylesheet" href="common/css/font-awesome.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">
|
<link rel="stylesheet" href="common/css/timepicker.css">
|
||||||
|
|
||||||
<!-- project dependency libs -->
|
<!-- project dependency libs -->
|
||||||
@ -26,13 +25,15 @@
|
|||||||
<script src="config.js"></script>
|
<script src="config.js"></script>
|
||||||
<script src="js/app.js"></script>
|
<script src="js/app.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body ng-controller="DashCtrl" ng-cloak>
|
<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">
|
<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)">×</button>
|
<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 class='pull-right small'> {{$index + 1}} alert(s) </div>
|
<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>
|
||||||
<div class="navbar navbar-static-top">
|
<div class="navbar navbar-static-top">
|
||||||
<div class="navbar-inner">
|
<div class="navbar-inner">
|
||||||
|
@ -7,11 +7,15 @@ angular.module('kibana.directives', [])
|
|||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
link: function(scope, elem, attrs) {
|
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" ' +
|
' <span class="editlink panelextra pointer" style="right:15px;top:0px" ' +
|
||||||
'bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
|
'bs-modal="\'partials/paneleditor.html\'" ng-show="panel.editable != false">'+
|
||||||
'<span class="small">{{panel.type}}</span> <i class="icon-cog pointer"></i> '+
|
'<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));
|
elem.prepend($compile(angular.element(template))(scope));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "~0.4.0",
|
"grunt": "~0.4.0",
|
||||||
"grunt-contrib": "~0.7.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"
|
"license": "Apache License"
|
||||||
}
|
}
|
||||||
|
@ -165,6 +165,7 @@ angular.module('kibana.histogram', [])
|
|||||||
data = [];
|
data = [];
|
||||||
if(filterSrv.idsByType('time').length > 0) {
|
if(filterSrv.idsByType('time').length > 0) {
|
||||||
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
|
data = [[_range.from.getTime(), null],[_range.to.getTime(), null]];
|
||||||
|
//data = [];
|
||||||
}
|
}
|
||||||
hits = 0;
|
hits = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -313,7 +314,7 @@ angular.module('kibana.histogram', [])
|
|||||||
lineWidth: scope.panel.linewidth,
|
lineWidth: scope.panel.linewidth,
|
||||||
steps: false
|
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},
|
points: { show: scope.panel.points, fill: 1, fillColor: false, radius: 5},
|
||||||
shadowSize: 1
|
shadowSize: 1
|
||||||
},
|
},
|
||||||
@ -321,22 +322,21 @@ angular.module('kibana.histogram', [])
|
|||||||
show: scope.panel['y-axis'],
|
show: scope.panel['y-axis'],
|
||||||
min: 0,
|
min: 0,
|
||||||
max: scope.panel.percentage && scope.panel.stack ? 100 : null,
|
max: scope.panel.percentage && scope.panel.stack ? 100 : null,
|
||||||
color: "#c8c8c8"
|
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
timezone: scope.panel.timezone,
|
timezone: scope.panel.timezone,
|
||||||
show: scope.panel['x-axis'],
|
show: scope.panel['x-axis'],
|
||||||
mode: "time",
|
mode: "time",
|
||||||
|
min: scope.range.from.getTime(),
|
||||||
|
max: scope.range.to.getTime(),
|
||||||
timeformat: time_format(scope.panel.interval),
|
timeformat: time_format(scope.panel.interval),
|
||||||
label: "Datetime",
|
label: "Datetime",
|
||||||
color: "#c8c8c8",
|
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
borderColor: '#eee',
|
|
||||||
color: "#eee",
|
|
||||||
hoverable: true,
|
hoverable: true,
|
||||||
|
color: '#c8c8c8'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="span8">
|
<div class="span8">
|
||||||
<h6>Columns <small>Click to remove</small></h6>
|
<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>
|
</div>
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h5>Last Elasticsearch Query</h5>
|
<h5>Last Elasticsearch Query</h5>
|
||||||
<pre>curl -XGET '{{config.elasticsearch}}/{{dashboard.indices|stringify}}/_search?pretty' -d '{{inspector}}'
|
<pre>curl -XGET '{{config.elasticsearch}}/{{dashboard.indices|stringify}}/_search?pretty' -d '{{inspector}}'
|
||||||
</pre>"
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
13
vendor/bootstrap/less/overrides.less
vendored
13
vendor/bootstrap/less/overrides.less
vendored
@ -190,3 +190,16 @@
|
|||||||
.faded {
|
.faded {
|
||||||
opacity: 0.2;
|
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
|
// Scaffolding
|
||||||
// -------------------------
|
// -------------------------
|
||||||
@bodyBackground: @white;
|
@bodyBackground: #ffffff;
|
||||||
@textColor: @grayDark;
|
@textColor: @grayDark;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user