[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.
This commit is contained in:
Walter Rafelsberger 2018-06-12 15:05:35 +02:00 committed by GitHub
parent 0b7367137b
commit 0d0256796f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 30 deletions

View file

@ -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 = $('<div>', {
class: 'time-tick-labels'
});
_.each(xAxisTicks, (tick) => {
const $tickLabel = $('<div>', {
class: 'tick-label',
text: moment(tick).format(xAxisTickFormat)
});
const $tickLabelWrapper = $('<div>', {
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();
}

View file

@ -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 @@
}
}