kibana-123
Version:
Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic
201 lines (174 loc) • 5.58 kB
JavaScript
import _ from 'lodash';
import d3 from 'd3';
import SCALE_MODES from './scale_modes';
export default function AxisConfigFactory() {
const defaults = {
show: true,
type: 'value',
elSelector: '.axis-wrapper-{pos} .axis-div',
position: 'left',
scale: {
type: 'linear',
expandLastBucket: true,
inverted: false,
setYExtents: null,
defaultYExtents: null,
min: null,
max: null,
mode: SCALE_MODES.NORMAL
},
style: {
color: '#ddd',
lineWidth: '1px',
opacity: 1,
tickColor: '#ddd',
tickWidth: '1px',
tickLength: '6px',
rangePadding: 0.1,
rangeOuterPadding: 0
},
labels: {
axisFormatter: null,
show: true,
rotate: 0,
rotateAnchor: 'center',
filter: false,
color: '#ddd',
font: '"Open Sans", "Lato", "Helvetica Neue", Helvetica, Arial, sans-serif',
fontSize: '8pt',
truncate: 100
},
title: {
text: '',
elSelector: '.axis-wrapper-{pos} .axis-title'
}
};
const categoryDefaults = {
type: 'category',
position: 'bottom',
};
const valueDefaults = {
labels: {
axisFormatter: d3.format('n')
}
};
const horizontalDefaults = {
labels: {
rotate: 0,
rotateAnchor: 'end',
filter: true,
truncate: 0,
}
};
const verticalDefaults = {
labels: {
rotateAnchor: 'middle'
}
};
class AxisConfig {
constructor(chartConfig, axisConfigArgs) {
const typeDefaults = axisConfigArgs.type === 'category' ? categoryDefaults : valueDefaults;
// _.defaultsDeep mutates axisConfigArgs nested values so we clone it first
const axisConfigArgsClone = _.cloneDeep(axisConfigArgs);
this._values = _.defaultsDeep({}, axisConfigArgsClone, typeDefaults, defaults);
_.merge(this._values, this.isHorizontal() ? horizontalDefaults : verticalDefaults);
this._values.elSelector = this._values.elSelector.replace('{pos}', this._values.position);
this._values.rootEl = chartConfig.get('el');
this.data = chartConfig.data;
if (this._values.type === 'category') {
if (!this._values.values) {
this.values = this.data.xValues(chartConfig.get('orderBucketsBySum', false));
this.ordered = this.data.get('ordered');
} else {
this.values = this._values.values;
}
if (!this._values.labels.axisFormatter) {
this._values.labels.axisFormatter = this.data.data.xAxisFormatter || this.data.get('xAxisFormatter');
}
}
if (this.get('type') === 'value') {
const isWiggleOrSilhouette =
this.get('scale.mode') === SCALE_MODES.WIGGLE ||
this.get('scale.mode') === SCALE_MODES.SILHOUETTE;
// if show was not explicitly set and wiggle or silhouette option was checked
if (isWiggleOrSilhouette) {
this._values.scale.defaultYExtents = false;
if (!axisConfigArgs.show) {
this._values.show = false;
this._values.title.show = true;
}
}
// override axisFormatter (to replicate current behaviour)
if (this.isPercentage()) {
this._values.labels.axisFormatter = d3.format('%');
this._values.scale.defaultYExtents = true;
}
if (this.isLogScale()) {
this._values.labels.filter = true;
}
}
// horizontal axis with ordinal scale should have labels rotated (so we can fit more)
// unless explicitly overriden by user
if (this.isHorizontal() && this.isOrdinal()) {
this._values.labels.filter = _.get(axisConfigArgs, 'labels.filter', false);
this._values.labels.rotate = _.get(axisConfigArgs, 'labels.rotate', 90);
this._values.labels.truncate = _.get(axisConfigArgs, 'labels.truncate', 100);
}
let offset;
let stacked = true;
switch (this.get('scale.mode')) {
case SCALE_MODES.NORMAL:
offset = 'zero';
stacked = false;
break;
case SCALE_MODES.GROUPED:
offset = 'group';
break;
case SCALE_MODES.PERCENTAGE:
offset = 'expand';
break;
default:
offset = this.get('scale.mode');
}
this.set('scale.offset', _.get(axisConfigArgs, 'scale.offset', offset));
/* axis.scale.stacked means that axis stacking function should be run */
this.set('scale.stacked', stacked);
};
get(property, defaults) {
if (typeof defaults !== 'undefined' || _.has(this._values, property)) {
return _.get(this._values, property, defaults);
} else {
throw new Error(`Accessing invalid config property: ${property}`);
return defaults;
}
};
set(property, value) {
return _.set(this._values, property, value);
};
isHorizontal() {
return (this._values.position === 'top' || this._values.position === 'bottom');
};
isOrdinal() {
return !!this.values && (!this.isTimeDomain());
};
isTimeDomain() {
return this.ordered && this.ordered.date;
};
isPercentage() {
return this._values.scale.mode === SCALE_MODES.PERCENTAGE;
};
isUserDefined() {
return this._values.scale.setYExtents;
};
isYExtents() {
return this._values.scale.defaultYExtents;
};
isLogScale() {
return this.getScaleType() === 'log';
};
getScaleType() {
return this._values.scale.type;
};
}
return AxisConfig;
}