From 0d0256796f2f00f0daf796abc1ed24fcab06dfc5 Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 12 Jun 2018 15:05:35 +0200 Subject: [PATCH] [ML] Deprecates jQuery in favour of d3's axis component for the swimlanes axes. Adds support to remove overlapping labels. (#19800) - Deprecates the use of jQuery to render the swimlanes axis labels and uses d3's axis component instead. We already used d3 features like d3.scale and others to calculate the label positions but the DOM rendering was still done using jQuery. - Additionally, adds some logic to remove/fix overlapping labels. --- .../explorer/explorer_swimlane_directive.js | 54 ++++++++++++------- .../ml/public/explorer/styles/main.less | 25 ++++----- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/ml/public/explorer/explorer_swimlane_directive.js b/x-pack/plugins/ml/public/explorer/explorer_swimlane_directive.js index 3760c463e956..c75e165e9610 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_swimlane_directive.js +++ b/x-pack/plugins/ml/public/explorer/explorer_swimlane_directive.js @@ -131,7 +131,6 @@ module.directive('mlExplorerSwimlane', function ($compile, Private, mlExplorerDa const timeBuckets = new MlTimeBuckets(); timeBuckets.setInterval(`${stepSecs}s`); const xAxisTickFormat = timeBuckets.getScaledDateFormat(); - const xAxisTicks = xAxisScale.ticks(numTicksForDateFormat(scope.chartWidth, xAxisTickFormat)); function cellMouseover($event, laneLabel, bucketScore, index, time) { if (bucketScore === undefined || cellMouseoverActive === false) { @@ -263,26 +262,45 @@ module.directive('mlExplorerSwimlane', function ($compile, Private, mlExplorerDa $compile($lane)(rowScope); }); - const $laneTimes = $('
', { - class: 'time-tick-labels' - }); - _.each(xAxisTicks, (tick) => { - const $tickLabel = $('
', { - class: 'tick-label', - text: moment(tick).format(xAxisTickFormat) - }); - const $tickLabelWrapper = $('
', { - class: 'tick-label-wrapper', - css: { - 'margin-left': (xAxisScale(tick)) + 'px' - } - }); + const laneTimes = d3.select($swimlanes.get(0)) + .append('div') + .classed('time-tick-labels', true); - $tickLabelWrapper.append($tickLabel); - $laneTimes.append($tickLabelWrapper); + // height of .time-tick-labels + const svgHeight = 25; + const svg = laneTimes.append('svg') + .attr('width', scope.chartWidth) + .attr('height', svgHeight); + + const xAxis = d3.svg.axis() + .scale(xAxisScale) + .ticks(numTicksForDateFormat(scope.chartWidth, xAxisTickFormat)) + .tickFormat(tick => moment(tick).format(xAxisTickFormat)); + + const gAxis = svg.append('g').attr('class', 'x axis').call(xAxis); + + // remove overlapping labels + let overlapCheck = 0; + gAxis.selectAll('g.tick').each(function () { + const tick = d3.select(this); + const xTransform = d3.transform(tick.attr('transform')).translate[0]; + const tickWidth = tick.select('text').node().getBBox().width; + const xMinOffset = xTransform - (tickWidth / 2); + const xMaxOffset = xTransform + (tickWidth / 2); + // if the tick label overlaps the previous label + // (or overflows the chart to the left), remove it; + // otherwise pick that label's offset as the new offset to check against + if (xMinOffset < overlapCheck) { + tick.remove(); + } else { + overlapCheck = xTransform + (tickWidth / 2); + } + // if the last tick label overflows the chart to the right, remove it + if (xMaxOffset > scope.chartWidth) { + tick.remove(); + } }); - $swimlanes.append($laneTimes); mlExplorerDashboardService.swimlaneRenderDone.changed(); } diff --git a/x-pack/plugins/ml/public/explorer/styles/main.less b/x-pack/plugins/ml/public/explorer/styles/main.less index 534b8cc73a6f..867a3df4de2c 100644 --- a/x-pack/plugins/ml/public/explorer/styles/main.less +++ b/x-pack/plugins/ml/public/explorer/styles/main.less @@ -287,17 +287,20 @@ .time-tick-labels { height: 25px; - font-size:11px; - margin-top: 4px; + margin-top: 2px; margin-left: 175px; - .tick-label-wrapper { - position: absolute; - .tick-label { - position: relative; - text-align: center; - margin-left: -50%; - width: 100px; - } + /* hide d3's domain line */ + path.domain { + display: none; + } + /* hide d3's tick line */ + g.tick line { + display: none; + } + /* override d3's default tick styles */ + g.tick text { + font-size:11px; + fill: #555; } } } @@ -332,5 +335,3 @@ } } - -