mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[TSVB] Adding log scale mode to y-axis (#17761)
* [TSVB] Adding log scale mode to y-axis * adding license for jquery.flot.log.js to NOTICE * Adding transforms to log * updating notices * Fixing transform to ingore zero
This commit is contained in:
parent
708810ab30
commit
6201d1a6c7
7 changed files with 205 additions and 0 deletions
20
NOTICE.txt
20
NOTICE.txt
|
@ -31,6 +31,26 @@ THE SOFTWARE.
|
|||
This product uses Noto fonts that are licensed under the SIL Open
|
||||
Font License, Version 1.1.
|
||||
|
||||
---
|
||||
Pretty handling of logarithmic axes.
|
||||
Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||
Licensed under the MIT license.
|
||||
Created by Arne de Laat
|
||||
Set axis.mode to "log" and make the axis logarithmic using transform:
|
||||
axis: {
|
||||
mode: 'log',
|
||||
transform: function(v) {v <= 0 ? Math.log(v) / Math.LN10 : null},
|
||||
inverseTransform: function(v) {Math.pow(10, v)}
|
||||
}
|
||||
The transform filters negative and zero values, because those are
|
||||
invalid on logarithmic scales.
|
||||
This plugin tries to create good looking logarithmic ticks, using
|
||||
unicode superscript characters. If all data to be plotted is between two
|
||||
powers of ten then the default flot tick generator and renderer are
|
||||
used. Logarithmic ticks are places at powers of ten and at half those
|
||||
values if there are not to many ticks already (e.g. [1, 5, 10, 50, 100]).
|
||||
For details, see https://github.com/flot/flot/pull/1328
|
||||
|
||||
---
|
||||
This product bundles angular-ui-bootstrap@0.12.1 which is available under a
|
||||
"MIT" license.
|
||||
|
|
|
@ -38,6 +38,10 @@ class TimeseriesPanelConfig extends Component {
|
|||
{ label: 'Right', value: 'right' },
|
||||
{ label: 'Left', value: 'left' }
|
||||
];
|
||||
const scaleOptions = [
|
||||
{ label: 'Normal', value: 'normal' },
|
||||
{ label: 'Log', value: 'log' }
|
||||
];
|
||||
const legendPositionOptions = [
|
||||
{ label: 'Right', value: 'right' },
|
||||
{ label: 'Left', value: 'left' },
|
||||
|
@ -98,6 +102,17 @@ class TimeseriesPanelConfig extends Component {
|
|||
onChange={handleSelectChange('axis_position')}
|
||||
/>
|
||||
</div>
|
||||
<label className="vis_editor__label" htmlFor={htmlId('axisPos')}>Axis Scale</label>
|
||||
<div className="vis_editor__row_item">
|
||||
<Select
|
||||
inputProps={{ id: htmlId('axisScale') }}
|
||||
autosize={false}
|
||||
clearable={false}
|
||||
options={scaleOptions}
|
||||
value={model.axis_scale}
|
||||
onChange={handleSelectChange('axis_scale')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="vis_editor__vis_config-row">
|
||||
<div className="vis_editor__label">Background Color</div>
|
||||
|
|
|
@ -71,6 +71,11 @@ class TimeseriesVisualization extends Component {
|
|||
|
||||
if (model.axis_min) mainAxis.min = model.axis_min;
|
||||
if (model.axis_max) mainAxis.max = model.axis_max;
|
||||
if (model.axis_scale === 'log') {
|
||||
mainAxis.mode = 'log';
|
||||
mainAxis.transform = value => value > 0 ? Math.log(value) / Math.LN10 : null;
|
||||
mainAxis.inverseTransform = value => Math.pow(10, value);
|
||||
}
|
||||
|
||||
const yaxes = [mainAxis];
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ export default function MetricsVisProvider(Private) {
|
|||
interval: 'auto',
|
||||
axis_position: 'left',
|
||||
axis_formatter: 'number',
|
||||
axis_scale: 'normal',
|
||||
show_legend: 1,
|
||||
show_grid: 1
|
||||
},
|
||||
|
|
|
@ -32,6 +32,7 @@ class FlotChart extends Component {
|
|||
axis.max !== this.props.yaxes[i].max ||
|
||||
axis.min !== this.props.yaxes[i].min ||
|
||||
axis.axisFormatter !== this.props.yaxes[i].axisFormatter ||
|
||||
axis.mode !== this.props.yaxes[i].mode ||
|
||||
axis.axisFormatterTemplate !== this.props.yaxes[i].axisFormatterTemplate
|
||||
);
|
||||
}
|
||||
|
|
|
@ -37,4 +37,5 @@ require('ui/flot-charts/jquery.flot.pie');
|
|||
require('ui/flot-charts/jquery.flot.stack');
|
||||
require('ui/flot-charts/jquery.flot.threshold');
|
||||
require('ui/flot-charts/jquery.flot.fillbetween');
|
||||
require('ui/flot-charts/jquery.flot.log');
|
||||
module.exports = $;
|
||||
|
|
162
src/ui/public/flot-charts/jquery.flot.log.js
Normal file
162
src/ui/public/flot-charts/jquery.flot.log.js
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*@notice
|
||||
* Pretty handling of logarithmic axes.
|
||||
* Copyright (c) 2007-2014 IOLA and Ole Laursen.
|
||||
* Licensed under the MIT license.
|
||||
* Created by Arne de Laat
|
||||
* Set axis.mode to "log" and make the axis logarithmic using transform:
|
||||
* axis: {
|
||||
* mode: 'log',
|
||||
* transform: function(v) {v <= 0 ? Math.log(v) / Math.LN10 : null},
|
||||
* inverseTransform: function(v) {Math.pow(10, v)}
|
||||
* }
|
||||
* The transform filters negative and zero values, because those are
|
||||
* invalid on logarithmic scales.
|
||||
* This plugin tries to create good looking logarithmic ticks, using
|
||||
* unicode superscript characters. If all data to be plotted is between two
|
||||
* powers of ten then the default flot tick generator and renderer are
|
||||
* used. Logarithmic ticks are places at powers of ten and at half those
|
||||
* values if there are not to many ticks already (e.g. [1, 5, 10, 50, 100]).
|
||||
* For details, see https://github.com/flot/flot/pull/1328
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
function log10(value) {
|
||||
/* Get the Log10 of the value
|
||||
*/
|
||||
return Math.log(value) / Math.LN10;
|
||||
}
|
||||
|
||||
function floorAsLog10(value) {
|
||||
/* Get power of the first power of 10 below the value
|
||||
*/
|
||||
return Math.floor(log10(value));
|
||||
}
|
||||
|
||||
function ceilAsLog10(value) {
|
||||
/* Get power of the first power of 10 above the value
|
||||
*/
|
||||
return Math.ceil(log10(value));
|
||||
}
|
||||
|
||||
|
||||
// round to nearby lower multiple of base
|
||||
function floorInBase(n, base) {
|
||||
return base * Math.floor(n / base);
|
||||
}
|
||||
|
||||
function getUnicodePower(power) {
|
||||
var superscripts = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"],
|
||||
result = "",
|
||||
str_power = "" + power;
|
||||
for (var i = 0; i < str_power.length; i++) {
|
||||
if (str_power[i] === "+") {
|
||||
}
|
||||
else if (str_power[i] === "-") {
|
||||
result += "⁻";
|
||||
}
|
||||
else {
|
||||
result += superscripts[str_power[i]];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function init(plot) {
|
||||
plot.hooks.processOptions.push(function (plot) {
|
||||
$.each(plot.getAxes(), function(axisName, axis) {
|
||||
|
||||
var opts = axis.options;
|
||||
|
||||
if (opts.mode === "log") {
|
||||
|
||||
axis.tickGenerator = function (axis) {
|
||||
|
||||
var ticks = [],
|
||||
end = ceilAsLog10(axis.max),
|
||||
start = floorAsLog10(axis.datamin),
|
||||
tick = Number.NaN,
|
||||
i = 0;
|
||||
|
||||
if (axis.datamin === null || axis.datamin <= 0) {
|
||||
// Bad minimum, make ticks from 1 (10**0) to max
|
||||
start = 0;
|
||||
axis.min = 0.6;
|
||||
}
|
||||
|
||||
if (end <= start) {
|
||||
// Start less than end?!
|
||||
ticks = [1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
|
||||
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6,
|
||||
1e7, 1e8, 1e9];
|
||||
}
|
||||
else if (log10(axis.max) - log10(axis.datamin) < 1) {
|
||||
// Default flot generator incase no powers of 10
|
||||
// are between start and end
|
||||
var prev;
|
||||
start = floorInBase(axis.min, axis.tickSize);
|
||||
do {
|
||||
prev = tick;
|
||||
tick = start + i * axis.tickSize;
|
||||
ticks.push(tick);
|
||||
++i;
|
||||
} while (tick < axis.max && tick !== prev);
|
||||
}
|
||||
else {
|
||||
// Make ticks at each power of ten
|
||||
for (; i <= (end - start); i++) {
|
||||
tick = Math.pow(10, start + i);
|
||||
ticks.push(tick);
|
||||
}
|
||||
|
||||
var length = ticks.length;
|
||||
|
||||
// If not to many ticks also put a tick between
|
||||
// the powers of ten
|
||||
if (end - start < 6) {
|
||||
for (var j = 1; j < length * 2 - 1; j += 2) {
|
||||
tick = ticks[j - 1] * 5;
|
||||
ticks.splice(j, 0, tick);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ticks;
|
||||
};
|
||||
|
||||
axis.tickFormatter = function (value, axis) {
|
||||
var formatted;
|
||||
if (log10(axis.max) - log10(axis.datamin) < 1) {
|
||||
// Default flot formatter
|
||||
var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
|
||||
formatted = "" + Math.round(value * factor) / factor;
|
||||
if (axis.tickDecimals !== null) {
|
||||
var decimal = formatted.indexOf(".");
|
||||
var precision = decimal === -1 ? 0 : formatted.length - decimal - 1;
|
||||
if (precision < axis.tickDecimals) {
|
||||
return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
var multiplier = "",
|
||||
exponential = parseFloat(value).toExponential(0),
|
||||
power = getUnicodePower(exponential.slice(2));
|
||||
if (exponential[0] !== "1") {
|
||||
multiplier = exponential[0] + "x";
|
||||
}
|
||||
formatted = multiplier + "10" + power;
|
||||
}
|
||||
return formatted;
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$.plot.plugins.push({
|
||||
init: init,
|
||||
name: "log",
|
||||
version: "0.9"
|
||||
});
|
||||
|
||||
})(jQuery);
|
Loading…
Add table
Add a link
Reference in a new issue