Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Vislib Axis #7961

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/core_plugins/kbn_vislib_vis_types/public/area.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export default function HistogramVisType(Private) {
'effect on the series above it.',
params: {
defaults: {
shareYAxis: true,
addTooltip: true,
addLegend: true,
legendPosition: 'right',
Expand Down
1 change: 0 additions & 1 deletion src/core_plugins/kbn_vislib_vis_types/public/histogram.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export default function HistogramVisType(Private) {
'exact numbers or percentages. If you are not sure which chart you need, you could do worse than to start here.',
params: {
defaults: {
shareYAxis: true,
addTooltip: true,
addLegend: true,
legendPosition: 'right',
Expand Down
1 change: 0 additions & 1 deletion src/core_plugins/kbn_vislib_vis_types/public/line.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export default function HistogramVisType(Private) {
'Be careful with sparse sets as the connection between points can be misleading.',
params: {
defaults: {
shareYAxis: true,
addTooltip: true,
addLegend: true,
legendPosition: 'right',
Expand Down
1 change: 0 additions & 1 deletion src/core_plugins/kbn_vislib_vis_types/public/pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export default function HistogramVisType(Private) {
'Pro Tip: Pie charts are best used sparingly, and with no more than 7 slices per pie.',
params: {
defaults: {
shareYAxis: true,
addTooltip: true,
addLegend: true,
legendPosition: 'right',
Expand Down
228 changes: 228 additions & 0 deletions src/ui/public/vislib/lib/axis.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
import d3 from 'd3';
import _ from 'lodash';
import $ from 'jquery';
import ErrorHandlerProvider from 'ui/vislib/lib/_error_handler';
import AxisTitleProvider from 'ui/vislib/lib/axis_title';
import AxisLabelsProvider from 'ui/vislib/lib/axis_labels';
import AxisScaleProvider from 'ui/vislib/lib/axis_scale';

export default function AxisFactory(Private) {
const ErrorHandler = Private(ErrorHandlerProvider);
const AxisTitle = Private(AxisTitleProvider);
const AxisLabels = Private(AxisLabelsProvider);
const AxisScale = Private(AxisScaleProvider);
const defaults = {
show: true,
type: 'value',
elSelector: '.axis-wrapper-{pos} .axis-div',
position: 'left',
axisFormatter: null, // TODO: create default axis formatter
scale: 'linear',
expandLastBucket: true, //TODO: rename ... bucket has nothing to do with vis
inverted: false,
style: {
color: '#ddd',
lineWidth: '1px',
opacity: 1,
tickColor: '#ddd',
tickWidth: '1px',
tickLength: '6px'
}
};

const categoryDefaults = {
type: 'category',
position: 'bottom',
labels: {
rotate: 0,
rotateAnchor: 'end',
filter: true
}
};
/**
* Appends y axis to the visualization
*
* @class Axis
* @constructor
* @param args {{el: (HTMLElement), yMax: (Number), _attr: (Object|*)}}
*/
class Axis extends ErrorHandler {
constructor(args) {
super();
if (args.type === 'category') {
_.extend(this, defaults, categoryDefaults, args);
} else {
_.extend(this, defaults, args);
}

this._attr = args.vis._attr;
this.elSelector = this.elSelector.replace('{pos}', this.position);
this.scale = new AxisScale(this, {scale: this.scale});
this.axisTitle = new AxisTitle(this, this.axisTitle);
this.axisLabels = new AxisLabels(this, this.labels);
}

render() {
d3.select(this.vis.el).selectAll(this.elSelector).call(this.draw());
}

isHorizontal() {
return (this.position === 'top' || this.position === 'bottom');
}

getAxis(length) {
const scale = this.scale.getScale(length);

return d3.svg.axis()
.scale(scale)
.tickFormat(this.tickFormat(this.domain))
.ticks(this.tickScale(length))
.orient(this.position);
}

getScale() {
return this.scale.scale;
}

addInterval(interval) {
return this.scale.addInterval(interval);
}

substractInterval(interval) {
return this.scale.substractInterval(interval);
}

tickScale(length) {
const yTickScale = d3.scale.linear()
.clamp(true)
.domain([20, 40, 1000])
.range([0, 3, 11]);

return Math.ceil(yTickScale(length));
}

tickFormat() {
if (this.axisFormatter) return this.axisFormatter;
if (this.isPercentage()) return d3.format('%');
return d3.format('n');
}

getLength(el, n) {
if (this.isHorizontal()) {
return $(el).parent().width() / n - this._attr.margin.left - this._attr.margin.right - 50;
}
return $(el).parent().height() / n - this._attr.margin.top - this._attr.margin.bottom;
}

updateXaxisHeight() {
const self = this;
const selection = d3.select(this.vis.el).selectAll('.vis-wrapper');


selection.each(function () {
const visEl = d3.select(this);

if (visEl.select('.inner-spacer-block').node() === null) {
visEl.selectAll('.y-axis-spacer-block')
.append('div')
.attr('class', 'inner-spacer-block');
}

const height = visEl.select(`.axis-wrapper-${self.position}`).style('height');
visEl.selectAll(`.y-axis-spacer-block-${self.position} .inner-spacer-block`).style('height', height);
});
}

adjustSize() {
const self = this;
const xAxisPadding = 15;

return function (selection) {
const text = selection.selectAll('.tick text');
const lengths = [];

text.each(function textWidths() {
lengths.push((() => {
if (self.isHorizontal()) {
return d3.select(this.parentNode).node().getBBox().height;
} else {
return d3.select(this.parentNode).node().getBBox().width;
}
})());
});
const length = _.max(lengths);

if (self.isHorizontal()) {
selection.attr('height', length);
self.updateXaxisHeight();
if (self.position === 'top') {
selection.select('g')
.attr('transform', `translate(0, ${length - parseInt(self.style.lineWidth)})`);
selection.select('path')
.attr('transform', 'translate(1,0)');
}
} else {
selection.attr('width', length + xAxisPadding);
if (self.position === 'left') {
const translateWidth = length + xAxisPadding - 2 - parseInt(self.style.lineWidth);
selection.select('g')
.attr('transform', `translate(${translateWidth},${self._attr.margin.top})`);
}
}
};
}

draw() {
const self = this;

return function (selection) {
const n = selection[0].length;
if (self.axisTitle) {
self.axisTitle.render(selection);
}
selection.each(function () {
const el = this;
const div = d3.select(el);
const width = $(el).parent().width();
const height = $(el).height();
const length = self.getLength(el, n);

// Validate whether width and height are not 0 or `NaN`
self.validateWidthandHeight(width, height);

const axis = self.getAxis(length);

if (self.show) {
const svg = div.append('svg')
.attr('width', width)
.attr('height', height);

svg.append('g')
.attr('class', `axis ${self.id}`)
.call(axis);

const container = svg.select('g.axis').node();
if (container) {
svg.select('path')
.style('stroke', self.style.color)
.style('stroke-width', self.style.lineWidth)
.style('stroke-opacity', self.style.opacity);
svg.selectAll('line')
.style('stroke', self.style.tickColor)
.style('stroke-width', self.style.tickWidth)
.style('stroke-opacity', self.style.opacity);
// TODO: update to be depenent on position ...
//.attr('x1', -parseInt(self.style.lineWidth) / 2)
//.attr('x2', -parseInt(self.style.lineWidth) / 2 - parseInt(self.style.tickLength));

if (self.axisLabels) self.axisLabels.render(svg);
svg.call(self.adjustSize());
}
}
});
};
}
}

return Axis;
};
Loading