From 5b1323c9d514f26119430ce30d15d7d2f6b3df10 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Mon, 27 May 2019 23:21:12 +0300 Subject: [PATCH 01/10] add labels to bar chart --- .../public/editors/point_series.html | 14 +- .../kbn_vislib_vis_types/public/histogram.js | 3 + .../ui/public/vislib/lib/axis/axis_config.js | 10 +- .../ui/public/vislib/lib/axis/axis_scale.js | 5 +- .../point_series/column_chart.js | 122 +++++++++++++++++- 5 files changed, 146 insertions(+), 8 deletions(-) diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html index 751c75f9f2cd4..9d1a2dc01b57c 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html @@ -64,7 +64,19 @@ +
+ +
+ +
+
+ - + \ No newline at end of file diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js b/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js index 2dd40fe6f8ffd..8e5ad0ddc797a 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/histogram.js @@ -98,6 +98,9 @@ export default function PointSeriesVisType(Private) { legendPosition: 'right', times: [], addTimeMarker: false, + labels: { + show: false, + } }, }, editorConfig: { diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_config.js b/src/legacy/ui/public/vislib/lib/axis/axis_config.js index e1ac97da5e848..bc90d4b5a81fb 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis_config.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis_config.js @@ -60,9 +60,13 @@ const defaults = { title: { text: '', elSelector: '.visAxis__column--{pos} .axis-div', - } + }, + padForLabels: 0, }; +const padForLabelsX = 40; +const padForLabelsY = 15; + const categoryDefaults = { type: 'category', position: 'bottom', @@ -158,6 +162,10 @@ export class AxisConfig { this._values.scale.inverted = _.get(axisConfigArgs, 'scale.inverted', true); } + if (chartConfig.get('labels.show', false) && !isCategoryAxis) { + this._values.padForLabels = isHorizontal ? padForLabelsX : padForLabelsY; + } + let offset; let stacked = true; switch (this.get('scale.mode')) { diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js index a6322aa82cc4f..4a82e24695994 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js @@ -156,10 +156,11 @@ export class AxisScale { } getRange(length) { + const pad = this.axisConfig.get('padForLabels'); if (this.axisConfig.isHorizontal()) { - return !this.axisConfig.get('scale.inverted') ? [0, length] : [length, 0]; + return !this.axisConfig.get('scale.inverted') ? [0, length - pad] : [length - pad, 0]; } else { - return this.axisConfig.get('scale.inverted') ? [0, length] : [length, 0]; + return this.axisConfig.get('scale.inverted') ? [0 + pad, length] : [length, 0 + pad]; } } diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 6e0dd2851df84..27c02a4543b8a 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -18,14 +18,15 @@ */ import _ from 'lodash'; +import d3 from 'd3'; import { PointSeries } from './_point_series'; - const defaults = { mode: 'normal', showTooltip: true, color: undefined, fillColor: undefined, + showLabel: true, }; /** @@ -44,6 +45,15 @@ function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCou return datumWidth; } +function invertColor(hex) { + const d3rgb = d3.rgb(hex); + const r = d3rgb.r; + const g = d3rgb.g; + const b = d3rgb.b; + const a = 1.0 - (0.299 * r + 0.587 * g + 0.114 * b) / 255; + return a < 0.5 ? d3rgb.darker(1) : d3rgb.brighter(3); +} + /** * Vertical Bar Chart Visualization: renders vertical and/or stacked bars * @@ -58,6 +68,7 @@ export class ColumnChart extends PointSeries { constructor(handler, chartEl, chartData, seriesConfigArgs) { super(handler, chartEl, chartData, seriesConfigArgs); this.seriesConfig = _.defaults(seriesConfigArgs || {}, defaults); + this.labelOptions = _.defaults(handler.visConfig.get('labels', {}), defaults.showLabel); } addBars(svg, data) { @@ -124,8 +135,10 @@ export class ColumnChart extends PointSeries { const yScale = this.getValueAxis().getScale(); const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal(); const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain(); + const isLabels = this.labelOptions.show; const yMin = yScale.domain()[0]; const gutterSpacingPercentage = 0.15; + const chartData = this.chartData; const groupCount = this.getGroupedCount(); const groupNum = this.getGroupedNum(this.chartData); let barWidth; @@ -171,6 +184,18 @@ export class ColumnChart extends PointSeries { return Math.abs(yScale(d.y0) - yScale(d.y0 + d.y)); } + function hideText(d, i, selector) { + if (isHorizontal && selector.getBBox().width > widthFunc(d, i)) return true; + if (!isHorizontal && selector.getBBox().width > heightFunc(d)) return true; + if (isHorizontal && selector.getBBox().height > heightFunc(d)) return true; + if (!isHorizontal && selector.getBBox().height > widthFunc(d, i)) return true; + return false; + } + + function formatValue(d) { + return chartData.yAxisFormatter(d.y); + } + // update bars .attr('x', isHorizontal ? x : y) @@ -178,9 +203,48 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? y : x) .attr('height', isHorizontal ? heightFunc : widthFunc); + const data = this.chartData; + const color = this.handler.data.getColorFunc(); + const layer = d3.select(bars[0].parentNode); + const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { + return !_.isNull(d.y); + })); + + barLabels + .exit() + .remove(); + + if (isLabels) { + if (isHorizontal) { + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('x', (d, i) => x(d, i) + widthFunc(d, i) / 2) + .attr('y', (d) => y(d) + heightFunc(d) / 2) + .attr('dominant-baseline', 'central') + .attr('text-anchor', 'middle') + .attr('font-size', '8pt') + .attr('fill', () => invertColor(color(data.label))) + .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); + } else { + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('x', (d) => y(d) + heightFunc(d) / 2) + .attr('y', (d, i) => x(d, i) + widthFunc(d, i) / 2) + .attr('dominant-baseline', 'central') + .attr('text-anchor', 'middle') + .attr('font-size', '8pt') + .attr('fill', () => invertColor(color(data.label))) + .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); + } + } + return bars; } - + /** * Adds grouped bars to column chart visualization * @@ -191,15 +255,17 @@ export class ColumnChart extends PointSeries { addGroupedBars(bars) { const xScale = this.getCategoryAxis().getScale(); const yScale = this.getValueAxis().getScale(); + const chartData = this.chartData; const groupCount = this.getGroupedCount(); const groupNum = this.getGroupedNum(this.chartData); const gutterSpacingPercentage = 0.15; const isTimeScale = this.getCategoryAxis().axisConfig.isTimeDomain(); const isHorizontal = this.getCategoryAxis().axisConfig.isHorizontal(); const isLogScale = this.getValueAxis().axisConfig.isLogScale(); + const isLabels = this.labelOptions.show; let barWidth; let gutterWidth; - + if (isTimeScale) { const { min, interval } = this.handler.data.get('ordered'); let intervalWidth = xScale(min + interval) - xScale(min); @@ -235,6 +301,16 @@ export class ColumnChart extends PointSeries { const baseValue = isLogScale ? 1 : 0; return Math.abs(yScale(baseValue) - yScale(d.y)); } + + function hideText(d, i, selector) { + if (isHorizontal && selector.getBBox().width > widthFunc(d, i)) return true; + if (!isHorizontal && selector.getBBox().height > widthFunc(d)) return true; + return false; + } + + function formatValue(d) { + return chartData.yAxisFormatter(d.y); + } // update bars @@ -243,8 +319,46 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? y : x) .attr('height', isHorizontal ? heightFunc : widthFunc); + const data = this.chartData; + const color = this.handler.data.getColorFunc(); + const layer = d3.select(bars[0].parentNode); + const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { + return !_.isNull(d.y); + })); + + barLabels + .exit() + .remove(); + + if (isLabels) { + if (isHorizontal) { + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('x', (d, i) => x(d, i) + widthFunc(d, i) / 2) + .attr('y', (d, i) => y(d, i) - 4) + .attr('dominant-baseline', 'auto') + .attr('text-anchor', 'middle') + .attr('font-size', '8pt') + .attr('fill', () => color(data.label)) + .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); + } else { + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('x', (d) => y(d) + heightFunc(d) + 4) + .attr('y', (d, i) => x(d, i) + widthFunc(d, i) / 2) + .attr('dominant-baseline', 'central') + .attr('text-anchor', 'start') + .attr('font-size', '8pt') + .attr('fill', () => color(data.label)) + .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); + } + } return bars; - } + } /** * Renders d3 visualization From 29dac34a2c2ae41de8715d9a519099e80b68d9fe Mon Sep 17 00:00:00 2001 From: mmeshi Date: Fri, 7 Jun 2019 15:59:04 +0300 Subject: [PATCH 02/10] code simplification --- .../point_series/column_chart.js | 140 ++++++++---------- 1 file changed, 64 insertions(+), 76 deletions(-) diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 27c02a4543b8a..32aefb55240ed 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -167,6 +167,22 @@ export class ColumnChart extends PointSeries { return yScale(d.y0 + d.y); } + function labelX(d, i) { + return x(d, i) + widthFunc(d, i) / 2; + } + + function labelY(d) { + return y(d) + heightFunc(d) / 2; + } + + function labelDisplay(d, i) { + if (isHorizontal && this.getBBox().width > widthFunc(d, i)) return 'none'; + if (!isHorizontal && this.getBBox().width > heightFunc(d)) return 'none'; + if (isHorizontal && this.getBBox().height > heightFunc(d)) return 'none'; + if (!isHorizontal && this.getBBox().height > widthFunc(d, i)) return 'none'; + return 'block'; + } + function widthFunc(d, i) { if (isTimeScale) { return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount); @@ -180,18 +196,9 @@ export class ColumnChart extends PointSeries { if (d.y0 === 0 && yMin > 0) { return yScale(yMin) - yScale(d.y); } - return Math.abs(yScale(d.y0) - yScale(d.y0 + d.y)); } - function hideText(d, i, selector) { - if (isHorizontal && selector.getBBox().width > widthFunc(d, i)) return true; - if (!isHorizontal && selector.getBBox().width > heightFunc(d)) return true; - if (isHorizontal && selector.getBBox().height > heightFunc(d)) return true; - if (!isHorizontal && selector.getBBox().height > widthFunc(d, i)) return true; - return false; - } - function formatValue(d) { return chartData.yAxisFormatter(d.y); } @@ -203,43 +210,25 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? y : x) .attr('height', isHorizontal ? heightFunc : widthFunc); - const data = this.chartData; - const color = this.handler.data.getColorFunc(); - const layer = d3.select(bars[0].parentNode); - const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { - return !_.isNull(d.y); - })); - - barLabels - .exit() - .remove(); + const data = this.chartData; + const color = this.handler.data.getColorFunc(); + const layer = d3.select(bars[0].parentNode); + const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { + return !_.isNull(d.y); + })); if (isLabels) { - if (isHorizontal) { - barLabels - .enter() - .append('text') - .text(formatValue) - .attr('x', (d, i) => x(d, i) + widthFunc(d, i) / 2) - .attr('y', (d) => y(d) + heightFunc(d) / 2) - .attr('dominant-baseline', 'central') - .attr('text-anchor', 'middle') - .attr('font-size', '8pt') - .attr('fill', () => invertColor(color(data.label))) - .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); - } else { - barLabels - .enter() - .append('text') - .text(formatValue) - .attr('x', (d) => y(d) + heightFunc(d) / 2) - .attr('y', (d, i) => x(d, i) + widthFunc(d, i) / 2) - .attr('dominant-baseline', 'central') - .attr('text-anchor', 'middle') - .attr('font-size', '8pt') - .attr('fill', () => invertColor(color(data.label))) - .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); - } + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('x', isHorizontal ? labelX : labelY) + .attr('y', isHorizontal ? labelY : labelX) + .attr('dominant-baseline', 'central') + .attr('text-anchor', 'middle') + .attr('font-size', '8pt') + .attr('fill', () => invertColor(color(data.label))) + .attr('display', labelDisplay); } return bars; @@ -286,10 +275,29 @@ export class ColumnChart extends PointSeries { if ((isHorizontal && d.y < 0) || (!isHorizontal && d.y > 0)) { return yScale(0); } - return yScale(d.y); } + function labelX(d, i) { + return x(d, i) + widthFunc(d, i) / 2; + } + + function labelY(d) { + if (isHorizontal) { + return y(d) - 4; + } + return y(d) + heightFunc(d) + 4; + } + + function labelDisplay(d, i) { + if (isHorizontal && this.getBBox().width > widthFunc(d, i)) { + return 'none'; + } + if (!isHorizontal && this.getBBox().height > widthFunc(d)) { + return 'none'; + } + return 'block'; + } function widthFunc(d, i) { if (isTimeScale) { return datumWidth(barWidth, d, bars.data()[i + 1], xScale, gutterWidth, groupCount); @@ -301,12 +309,6 @@ export class ColumnChart extends PointSeries { const baseValue = isLogScale ? 1 : 0; return Math.abs(yScale(baseValue) - yScale(d.y)); } - - function hideText(d, i, selector) { - if (isHorizontal && selector.getBBox().width > widthFunc(d, i)) return true; - if (!isHorizontal && selector.getBBox().height > widthFunc(d)) return true; - return false; - } function formatValue(d) { return chartData.yAxisFormatter(d.y); @@ -331,31 +333,17 @@ export class ColumnChart extends PointSeries { .remove(); if (isLabels) { - if (isHorizontal) { - barLabels - .enter() - .append('text') - .text(formatValue) - .attr('x', (d, i) => x(d, i) + widthFunc(d, i) / 2) - .attr('y', (d, i) => y(d, i) - 4) - .attr('dominant-baseline', 'auto') - .attr('text-anchor', 'middle') - .attr('font-size', '8pt') - .attr('fill', () => color(data.label)) - .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); - } else { - barLabels - .enter() - .append('text') - .text(formatValue) - .attr('x', (d) => y(d) + heightFunc(d) + 4) - .attr('y', (d, i) => x(d, i) + widthFunc(d, i) / 2) - .attr('dominant-baseline', 'central') - .attr('text-anchor', 'start') - .attr('font-size', '8pt') - .attr('fill', () => color(data.label)) - .attr('display', function (d, i) { return hideText(d, i, this) ? 'none' : 'block'; }); - } + barLabels + .enter() + .append('text') + .text(formatValue) + .attr('font-size', '8pt') + .attr('x', isHorizontal ? labelX : labelY) + .attr('y', isHorizontal ? labelY : labelX) + .attr('dominant-baseline', isHorizontal ? 'auto' : 'central') + .attr('text-anchor', isHorizontal ? 'middle' : 'start') + .attr('fill', () => color(data.label)) + .attr('display', labelDisplay); } return bars; } From 8b6a34792ffe0934f4360946698cc1651442b983 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Fri, 7 Jun 2019 19:07:31 +0300 Subject: [PATCH 03/10] clean trailing spaces --- .../vislib/visualizations/point_series/column_chart.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 32aefb55240ed..940517595f5c7 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -233,7 +233,7 @@ export class ColumnChart extends PointSeries { return bars; } - + /** * Adds grouped bars to column chart visualization * @@ -254,7 +254,7 @@ export class ColumnChart extends PointSeries { const isLabels = this.labelOptions.show; let barWidth; let gutterWidth; - + if (isTimeScale) { const { min, interval } = this.handler.data.get('ordered'); let intervalWidth = xScale(min + interval) - xScale(min); @@ -346,7 +346,7 @@ export class ColumnChart extends PointSeries { .attr('display', labelDisplay); } return bars; - } + } /** * Renders d3 visualization From 27e23b5e6cf5b7d89442251f0c39244df887610e Mon Sep 17 00:00:00 2001 From: mmeshi Date: Wed, 12 Jun 2019 11:13:04 +0300 Subject: [PATCH 04/10] for stack mode label color will be w/b --- .../point_series/column_chart.js | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 940517595f5c7..36d3e73e1721c 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -19,6 +19,7 @@ import _ from 'lodash'; import d3 from 'd3'; +import { isColorDark } from '@elastic/eui/lib/services'; import { PointSeries } from './_point_series'; const defaults = { @@ -45,15 +46,6 @@ function datumWidth(defaultWidth, datum, nextDatum, scale, gutterWidth, groupCou return datumWidth; } -function invertColor(hex) { - const d3rgb = d3.rgb(hex); - const r = d3rgb.r; - const g = d3rgb.g; - const b = d3rgb.b; - const a = 1.0 - (0.299 * r + 0.587 * g + 0.114 * b) / 255; - return a < 0.5 ? d3rgb.darker(1) : d3rgb.brighter(3); -} - /** * Vertical Bar Chart Visualization: renders vertical and/or stacked bars * @@ -210,14 +202,16 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? y : x) .attr('height', isHorizontal ? heightFunc : widthFunc); - const data = this.chartData; - const color = this.handler.data.getColorFunc(); const layer = d3.select(bars[0].parentNode); - const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { + const barLabels = layer.selectAll('text').data(chartData.values.filter(function (d) { return !_.isNull(d.y); })); if (isLabels) { + const colorFunc = this.handler.data.getColorFunc(); + const d3Color = d3.rgb(colorFunc(chartData.label)); + const labelColor = isColorDark(d3Color.r, d3Color.g, d3Color.b) ? 'white' : 'black'; + barLabels .enter() .append('text') @@ -227,7 +221,7 @@ export class ColumnChart extends PointSeries { .attr('dominant-baseline', 'central') .attr('text-anchor', 'middle') .attr('font-size', '8pt') - .attr('fill', () => invertColor(color(data.label))) + .attr('fill', labelColor) .attr('display', labelDisplay); } @@ -321,10 +315,8 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? y : x) .attr('height', isHorizontal ? heightFunc : widthFunc); - const data = this.chartData; - const color = this.handler.data.getColorFunc(); const layer = d3.select(bars[0].parentNode); - const barLabels = layer.selectAll('text').data(data.values.filter(function (d) { + const barLabels = layer.selectAll('text').data(chartData.values.filter(function (d) { return !_.isNull(d.y); })); @@ -333,6 +325,8 @@ export class ColumnChart extends PointSeries { .remove(); if (isLabels) { + const labelColor = this.handler.data.getColorFunc()(chartData.label); + barLabels .enter() .append('text') @@ -342,7 +336,7 @@ export class ColumnChart extends PointSeries { .attr('y', isHorizontal ? labelY : labelX) .attr('dominant-baseline', isHorizontal ? 'auto' : 'central') .attr('text-anchor', isHorizontal ? 'middle' : 'start') - .attr('fill', () => color(data.label)) + .attr('fill', labelColor) .attr('display', labelDisplay); } return bars; From b480bef71ea9945888c05825d3d7597ee8e79de6 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Wed, 12 Jun 2019 11:15:10 +0300 Subject: [PATCH 05/10] change label message on option panel, and show the option only for histogram type --- .../kbn_vislib_vis_types/public/editors/point_series.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html index 9d1a2dc01b57c..47079b44e1453 100644 --- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html +++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/editors/point_series.html @@ -64,12 +64,12 @@ -
+
From affce12aac10dbc731a11de405df130f81ae6091 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Wed, 12 Jun 2019 12:25:43 +0300 Subject: [PATCH 06/10] better way to manipulate axis to make room for labels --- .../ui/public/vislib/lib/axis/axis_scale.js | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js index 4a82e24695994..ab9b21b4d5c71 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js @@ -155,12 +155,26 @@ export class AxisScale { return [Math.min(0, min), Math.max(0, max)]; } - getRange(length) { + getDomain(length) { + const domain = this.getExtents(); const pad = this.axisConfig.get('padForLabels'); + if (pad > 0) { + const domainLength = domain[1] - domain[0]; + const valuePerPixel = domainLength / length; + const padValue = valuePerPixel * pad; + if (domain[0] < 0) { + domain[0] -= padValue; + } + domain[1] += padValue; + } + return domain; + } + + getRange(length) { if (this.axisConfig.isHorizontal()) { - return !this.axisConfig.get('scale.inverted') ? [0, length - pad] : [length - pad, 0]; + return !this.axisConfig.get('scale.inverted') ? [0, length] : [length, 0]; } else { - return this.axisConfig.get('scale.inverted') ? [0 + pad, length] : [length, 0 + pad]; + return this.axisConfig.get('scale.inverted') ? [0, length] : [length, 0]; } } @@ -200,7 +214,7 @@ export class AxisScale { getScale(length) { const config = this.axisConfig; const scale = this.getD3Scale(config.getScaleType()); - const domain = this.getExtents(); + const domain = this.getDomain(length); const range = this.getRange(length); const padding = config.get('style.rangePadding'); const outerPadding = config.get('style.rangeOuterPadding'); From a0206c5eb3ea6a14ed7b4689648eda242a5a89ea Mon Sep 17 00:00:00 2001 From: mmeshi Date: Wed, 12 Jun 2019 15:28:02 +0300 Subject: [PATCH 07/10] fixes for user defined axis, and negative value --- src/legacy/ui/public/vislib/lib/axis/axis_scale.js | 2 +- .../public/vislib/visualizations/point_series/column_chart.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js index ab9b21b4d5c71..4f843967ef936 100644 --- a/src/legacy/ui/public/vislib/lib/axis/axis_scale.js +++ b/src/legacy/ui/public/vislib/lib/axis/axis_scale.js @@ -158,7 +158,7 @@ export class AxisScale { getDomain(length) { const domain = this.getExtents(); const pad = this.axisConfig.get('padForLabels'); - if (pad > 0) { + if (pad > 0 && this.canApplyNice()) { const domainLength = domain[1] - domain[0]; const valuePerPixel = domainLength / length; const padValue = valuePerPixel * pad; diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 36d3e73e1721c..2f99f101bf6fb 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -278,9 +278,9 @@ export class ColumnChart extends PointSeries { function labelY(d) { if (isHorizontal) { - return y(d) - 4; + return d.y >= 0 ? y(d) - 4 : y(d) + heightFunc(d) + this.getBBox().height; } - return y(d) + heightFunc(d) + 4; + return d.y >= 0 ? y(d) + 4 : y(d) - this.getBBox().width - 4; } function labelDisplay(d, i) { From 6eccff58cddf1025f47e06009b01cd96af6d3892 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Thu, 13 Jun 2019 23:50:32 +0300 Subject: [PATCH 08/10] fix label position in grouped vertical mode --- .../public/vislib/visualizations/point_series/column_chart.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 2f99f101bf6fb..687adc071471e 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -280,7 +280,7 @@ export class ColumnChart extends PointSeries { if (isHorizontal) { return d.y >= 0 ? y(d) - 4 : y(d) + heightFunc(d) + this.getBBox().height; } - return d.y >= 0 ? y(d) + 4 : y(d) - this.getBBox().width - 4; + return d.y >= 0 ? y(d) + heightFunc(d) + 4 : y(d) - this.getBBox().width - 4; } function labelDisplay(d, i) { From 3d18610b57533270fd4e690bc9f897aa4dbd0fce Mon Sep 17 00:00:00 2001 From: mmeshi Date: Tue, 18 Jun 2019 17:27:25 +0300 Subject: [PATCH 09/10] refactor label color style to css classes --- src/legacy/ui/public/vislib/_index.scss | 2 ++ .../public/vislib/visualizations/_index.scss | 1 + .../public/vislib/visualizations/_labels.scss | 22 +++++++++++++++++++ .../point_series/column_chart.js | 15 ++++++++----- 4 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 src/legacy/ui/public/vislib/visualizations/_index.scss create mode 100644 src/legacy/ui/public/vislib/visualizations/_labels.scss diff --git a/src/legacy/ui/public/vislib/_index.scss b/src/legacy/ui/public/vislib/_index.scss index f8045b7cf5d35..df45365c91036 100644 --- a/src/legacy/ui/public/vislib/_index.scss +++ b/src/legacy/ui/public/vislib/_index.scss @@ -1,3 +1,5 @@ @import './variables'; @import './lib/index'; + +@import './visualizations/index'; diff --git a/src/legacy/ui/public/vislib/visualizations/_index.scss b/src/legacy/ui/public/vislib/visualizations/_index.scss new file mode 100644 index 0000000000000..53fce786ecc15 --- /dev/null +++ b/src/legacy/ui/public/vislib/visualizations/_index.scss @@ -0,0 +1 @@ +@import './labels'; diff --git a/src/legacy/ui/public/vislib/visualizations/_labels.scss b/src/legacy/ui/public/vislib/visualizations/_labels.scss new file mode 100644 index 0000000000000..824f76fc88e1a --- /dev/null +++ b/src/legacy/ui/public/vislib/visualizations/_labels.scss @@ -0,0 +1,22 @@ +$visBarLabelDarkColor: $euiColorDarkShade; +$visBarLabelLightColor: $euiColorLightShade; + +.bar-label--normal { + font-size: 8pt; + pointer-events: none; +} + +.bar-label--stack { + font-size: 8pt; + pointer-events: none; + dominant-baseline: central; + text-anchor: middle; +} + +.bar-label--dark { + fill: $visBarLabelDarkColor; +} + +.bar-label--light { + fill: $visBarLabelLightColor; +} diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 687adc071471e..27d267187454c 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -210,18 +210,18 @@ export class ColumnChart extends PointSeries { if (isLabels) { const colorFunc = this.handler.data.getColorFunc(); const d3Color = d3.rgb(colorFunc(chartData.label)); - const labelColor = isColorDark(d3Color.r, d3Color.g, d3Color.b) ? 'white' : 'black'; + const labelClass = isColorDark(d3Color.r, d3Color.g, d3Color.b) ? 'bar-label--light' : 'bar-label--dark'; barLabels .enter() .append('text') .text(formatValue) + .attr('class', `${labelClass} bar-label--stack`) .attr('x', isHorizontal ? labelX : labelY) .attr('y', isHorizontal ? labelY : labelX) - .attr('dominant-baseline', 'central') - .attr('text-anchor', 'middle') - .attr('font-size', '8pt') - .attr('fill', labelColor) + + // display must apply last, because labelDisplay decision it based + // on text bounding box which depends on actual applied style. .attr('display', labelDisplay); } @@ -331,12 +331,15 @@ export class ColumnChart extends PointSeries { .enter() .append('text') .text(formatValue) - .attr('font-size', '8pt') + .attr('class', 'bar-label--normal') .attr('x', isHorizontal ? labelX : labelY) .attr('y', isHorizontal ? labelY : labelX) .attr('dominant-baseline', isHorizontal ? 'auto' : 'central') .attr('text-anchor', isHorizontal ? 'middle' : 'start') .attr('fill', labelColor) + + // display must apply last, because labelDisplay decision it based + // on text bounding box which depends on actual applied style. .attr('display', labelDisplay); } return bars; From c076009251f07c887e070eba0d57da55744b4158 Mon Sep 17 00:00:00 2001 From: mmeshi Date: Wed, 19 Jun 2019 08:40:36 +0300 Subject: [PATCH 10/10] cosmetic changes in label classes --- src/legacy/ui/public/vislib/_index.scss | 2 +- .../public/vislib/visualizations/_labels.scss | 22 ------------------- .../{ => point_series}/_index.scss | 0 .../visualizations/point_series/_labels.scss | 20 +++++++++++++++++ .../point_series/column_chart.js | 11 +++++++--- 5 files changed, 29 insertions(+), 26 deletions(-) delete mode 100644 src/legacy/ui/public/vislib/visualizations/_labels.scss rename src/legacy/ui/public/vislib/visualizations/{ => point_series}/_index.scss (100%) create mode 100644 src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss diff --git a/src/legacy/ui/public/vislib/_index.scss b/src/legacy/ui/public/vislib/_index.scss index df45365c91036..4e4ba8175444d 100644 --- a/src/legacy/ui/public/vislib/_index.scss +++ b/src/legacy/ui/public/vislib/_index.scss @@ -2,4 +2,4 @@ @import './lib/index'; -@import './visualizations/index'; +@import './visualizations/point_series/index'; diff --git a/src/legacy/ui/public/vislib/visualizations/_labels.scss b/src/legacy/ui/public/vislib/visualizations/_labels.scss deleted file mode 100644 index 824f76fc88e1a..0000000000000 --- a/src/legacy/ui/public/vislib/visualizations/_labels.scss +++ /dev/null @@ -1,22 +0,0 @@ -$visBarLabelDarkColor: $euiColorDarkShade; -$visBarLabelLightColor: $euiColorLightShade; - -.bar-label--normal { - font-size: 8pt; - pointer-events: none; -} - -.bar-label--stack { - font-size: 8pt; - pointer-events: none; - dominant-baseline: central; - text-anchor: middle; -} - -.bar-label--dark { - fill: $visBarLabelDarkColor; -} - -.bar-label--light { - fill: $visBarLabelLightColor; -} diff --git a/src/legacy/ui/public/vislib/visualizations/_index.scss b/src/legacy/ui/public/vislib/visualizations/point_series/_index.scss similarity index 100% rename from src/legacy/ui/public/vislib/visualizations/_index.scss rename to src/legacy/ui/public/vislib/visualizations/point_series/_index.scss diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss b/src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss new file mode 100644 index 0000000000000..8bcd17fd55ddf --- /dev/null +++ b/src/legacy/ui/public/vislib/visualizations/point_series/_labels.scss @@ -0,0 +1,20 @@ +$visColumnChartBarLabelDarkColor: #000; // EUI doesn't yet have a variable for fully black in all themes; +$visColumnChartBarLabelLightColor: $euiColorGhost; + +.visColumnChart__barLabel { + font-size: 8pt; + pointer-events: none; +} + +.visColumnChart__barLabel--stack { + dominant-baseline: central; + text-anchor: middle; +} + +.visColumnChart__bar-label--dark { + fill: $visColumnChartBarLabelDarkColor; +} + +.visColumnChart__bar-label--light { + fill: $visColumnChartBarLabelLightColor; +} diff --git a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js index 27d267187454c..d6c1d2b86f158 100644 --- a/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js +++ b/src/legacy/ui/public/vislib/visualizations/point_series/column_chart.js @@ -210,13 +210,18 @@ export class ColumnChart extends PointSeries { if (isLabels) { const colorFunc = this.handler.data.getColorFunc(); const d3Color = d3.rgb(colorFunc(chartData.label)); - const labelClass = isColorDark(d3Color.r, d3Color.g, d3Color.b) ? 'bar-label--light' : 'bar-label--dark'; + let labelClass; + if (isColorDark(d3Color.r, d3Color.g, d3Color.b)) { + labelClass = 'visColumnChart__bar-label--light'; + } else { + labelClass = 'visColumnChart__bar-label--dark'; + } barLabels .enter() .append('text') .text(formatValue) - .attr('class', `${labelClass} bar-label--stack`) + .attr('class', `visColumnChart__barLabel visColumnChart__barLabel--stack ${labelClass}`) .attr('x', isHorizontal ? labelX : labelY) .attr('y', isHorizontal ? labelY : labelX) @@ -331,7 +336,7 @@ export class ColumnChart extends PointSeries { .enter() .append('text') .text(formatValue) - .attr('class', 'bar-label--normal') + .attr('class', 'visColumnChart__barLabel') .attr('x', isHorizontal ? labelX : labelY) .attr('y', isHorizontal ? labelY : labelX) .attr('dominant-baseline', isHorizontal ? 'auto' : 'central')