Skip to content

Commit 42b79a8

Browse files
authored
[ML] Deprecates jQuery in favour of d3's axis component for the swimlanes axes. Adds support to remove overlapping labels. (#19800) (#19821)
- 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.
1 parent 2a0bdbc commit 42b79a8

File tree

2 files changed

+50
-31
lines changed

2 files changed

+50
-31
lines changed

x-pack/plugins/ml/public/explorer/explorer_swimlane_directive.js

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,6 @@ module.directive('mlExplorerSwimlane', function ($compile, Private, mlExplorerDa
131131
const timeBuckets = new MlTimeBuckets();
132132
timeBuckets.setInterval(`${stepSecs}s`);
133133
const xAxisTickFormat = timeBuckets.getScaledDateFormat();
134-
const xAxisTicks = xAxisScale.ticks(numTicksForDateFormat(scope.chartWidth, xAxisTickFormat));
135134

136135
function cellMouseover($event, laneLabel, bucketScore, index, time) {
137136
if (bucketScore === undefined || cellMouseoverActive === false) {
@@ -263,26 +262,45 @@ module.directive('mlExplorerSwimlane', function ($compile, Private, mlExplorerDa
263262
$compile($lane)(rowScope);
264263
});
265264

266-
const $laneTimes = $('<div>', {
267-
class: 'time-tick-labels'
268-
});
269-
_.each(xAxisTicks, (tick) => {
270-
const $tickLabel = $('<div>', {
271-
class: 'tick-label',
272-
text: moment(tick).format(xAxisTickFormat)
273-
});
274-
const $tickLabelWrapper = $('<div>', {
275-
class: 'tick-label-wrapper',
276-
css: {
277-
'margin-left': (xAxisScale(tick)) + 'px'
278-
}
279-
});
280-
281-
$tickLabelWrapper.append($tickLabel);
282-
$laneTimes.append($tickLabelWrapper);
265+
const laneTimes = d3.select($swimlanes.get(0))
266+
.append('div')
267+
.classed('time-tick-labels', true);
268+
269+
// height of .time-tick-labels
270+
const svgHeight = 25;
271+
const svg = laneTimes.append('svg')
272+
.attr('width', scope.chartWidth)
273+
.attr('height', svgHeight);
274+
275+
const xAxis = d3.svg.axis()
276+
.scale(xAxisScale)
277+
.ticks(numTicksForDateFormat(scope.chartWidth, xAxisTickFormat))
278+
.tickFormat(tick => moment(tick).format(xAxisTickFormat));
279+
280+
const gAxis = svg.append('g').attr('class', 'x axis').call(xAxis);
281+
282+
// remove overlapping labels
283+
let overlapCheck = 0;
284+
gAxis.selectAll('g.tick').each(function () {
285+
const tick = d3.select(this);
286+
const xTransform = d3.transform(tick.attr('transform')).translate[0];
287+
const tickWidth = tick.select('text').node().getBBox().width;
288+
const xMinOffset = xTransform - (tickWidth / 2);
289+
const xMaxOffset = xTransform + (tickWidth / 2);
290+
// if the tick label overlaps the previous label
291+
// (or overflows the chart to the left), remove it;
292+
// otherwise pick that label's offset as the new offset to check against
293+
if (xMinOffset < overlapCheck) {
294+
tick.remove();
295+
} else {
296+
overlapCheck = xTransform + (tickWidth / 2);
297+
}
298+
// if the last tick label overflows the chart to the right, remove it
299+
if (xMaxOffset > scope.chartWidth) {
300+
tick.remove();
301+
}
283302
});
284303

285-
$swimlanes.append($laneTimes);
286304
mlExplorerDashboardService.swimlaneRenderDone.changed();
287305
}
288306

x-pack/plugins/ml/public/explorer/styles/main.less

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -287,17 +287,20 @@
287287

288288
.time-tick-labels {
289289
height: 25px;
290-
font-size:11px;
291-
margin-top: 4px;
290+
margin-top: 2px;
292291
margin-left: 175px;
293-
.tick-label-wrapper {
294-
position: absolute;
295-
.tick-label {
296-
position: relative;
297-
text-align: center;
298-
margin-left: -50%;
299-
width: 100px;
300-
}
292+
/* hide d3's domain line */
293+
path.domain {
294+
display: none;
295+
}
296+
/* hide d3's tick line */
297+
g.tick line {
298+
display: none;
299+
}
300+
/* override d3's default tick styles */
301+
g.tick text {
302+
font-size:11px;
303+
fill: #555;
301304
}
302305
}
303306
}
@@ -332,5 +335,3 @@
332335
}
333336

334337
}
335-
336-

0 commit comments

Comments
 (0)