Skip to content

Commit

Permalink
Fix: ensure tooltip stays in container, default parentElement for too…
Browse files Browse the repository at this point in the history
…ltip no longer body it is now App container. Added aria-live and role attr to tooltip
  • Loading branch information
joewdavies committed Jul 7, 2023
1 parent b209fee commit bc5f382
Show file tree
Hide file tree
Showing 6 changed files with 190 additions and 144 deletions.
70 changes: 45 additions & 25 deletions dist/gridviz.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/gridviz.min.js

Large diffs are not rendered by default.

183 changes: 89 additions & 94 deletions docs/reference.md

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions examples/test/test.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,17 @@
}
)

//add legend
app.layers[0].styles[0].legends.push(
new gviz.ColorLegend({
title: 'Number of inhabitants',
width: 400,
ticks: 5,
colorRamp: d3.interpolateYlOrRd,
fun: (t, r, s) => s.max * gviz.sExpRevInverse(t, -7),
})
)

/*app.addBackgroundLayer({
urlFun: (x, y, z) => "https://webgate.ec.europa.eu/inspireec/arcgis/rest/services/Basemaps/Natural_Earth_3035/MapServer/tile/" + z + "/" + y + "/" + x,
resolutions: [66145.9656252646, 26458.386250105836, 13229.193125052918, 6614.596562526459, 2645.8386250105837, 1322.9193125052918,],
Expand Down
6 changes: 5 additions & 1 deletion src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ export class App {
this.legendDivId = opts.legendDivId || 'gvizLegend'
this.legend = select('#' + this.legendDivId)
if (this.legend.empty()) {
this.legend = select('body')
this.legend = select('#' + container.id)
.append('div')
.attr('id', this.legendDivId)
.style('position', 'absolute')
Expand All @@ -206,6 +206,10 @@ export class App {

//tooltip

// set App container as default parent element for tooltip
if (!opts.tooltip) opts.tooltip = {}
if (!opts.tooltip.parentElement) opts.tooltip.parentElement = container

/**
* @private
* @type {Tooltip} */
Expand Down
62 changes: 39 additions & 23 deletions src/Tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,17 @@ export class Tooltip {
this.yMouseOffset = opts.yMouseOffset || 0
/** @type {number} */
this.xMouseOffset = opts.xMouseOffset || 0
/** @type {HTMLElement} */
this.parentElement = opts.parentElement || document.body

/**
* @private
* @type {import("d3-selection").Selection} */
this.tooltip = select('#' + this.div)
if (this.tooltip.empty()) this.tooltip = select('body').append('div').attr('id', this.div)
if (this.tooltip.empty())
this.tooltip = select('#' + this.parentElement.id)
.append('div')
.attr('id', this.div)

//initialise
this.tooltip.style('max-width', this.maxWidth)
Expand All @@ -64,6 +69,9 @@ export class Tooltip {
this.tooltip.style('position', 'absolute')
this.tooltip.style('pointer-events', 'none')
this.tooltip.style('opacity', '0')

// aria-labels (thanks to wahlatlas)
this.tooltip.attr('role', 'tooltip').attr('aria-live', 'polite')
}

/** Show the tooltip */
Expand Down Expand Up @@ -94,19 +102,21 @@ export class Tooltip {
this.tooltip
.style('left', event.pageX + this.xOffset + 'px')
.style('top', event.pageY - this.yOffset + 'px')

this.ensureTooltipInsideContainer(event)
}

/*
my.mouseover = function (event, html) {
if (html) my.html(html);
my.setPosition(event);
my.show()
//this.ensureTooltipOnScreen();
//this.ensureTooltipInsideContainer();
};
my.mousemove = function (event) {
my.setPosition(event);
//this.ensureTooltipOnScreen();
//this.ensureTooltipInsideContainer();
};
my.mouseout = function () {
Expand All @@ -126,25 +136,31 @@ export class Tooltip {
}

/**
* @function ensureTooltipOnScreen
* @description Prevents the tooltip from overflowing off screen
* @function ensureTooltipInsideContainer
* @description Prevents the tooltip from overflowing out of the App container (ensures that the tooltip is inside the gridviz container)
* @param {MouseEvent} event
*/
/*my.ensureTooltipOnScreen = function () {
// TODO: parent needs to be the all-encompassing container, not the map SVG id otherwise it just uses the last SVG which will be an inset SVG.
let parent = document.getElementById(config.parentContainerId);
let bbox = parent.getBBox();
let parentWidth = bbox.width;
let parentHeight = bbox.height;
let node = tooltip.node();
//too far right
if (node.offsetLeft > parentWidth - node.clientWidth) {
node.style.left = node.offsetLeft - (node.clientWidth + config.xOffset * 2) + "px";
}
//too far down
if (node.offsetTop + node.clientHeight > parentHeight) {
node.style.top = node.offsetTop - (node.clientHeight + config.yOffset * 2) + "px";
}
}*/
ensureTooltipInsideContainer = function (event) {
let node = this.tooltip.node()
let rect = this.parentElement.getBoundingClientRect()
let parentWidth = rect.width
let parentHeight = rect.height

//too far right
if (node.offsetLeft > rect.left + parentWidth - node.clientWidth) {
let left = event.x - node.clientWidth - this.xOffset
node.style.left = left + 'px'
// check if mouse covers tooltip
if (node.offsetLeft + node.clientWidth > event.x) {
//move tooltip left so it doesnt cover mouse
let left2 = event.x - (node.clientWidth + this.xOffset)
node.style.left = left2 + 'px'
}
}

//too far down
if (node.offsetTop + node.clientHeight > rect.top + parentHeight) {
node.style.top = node.offsetTop - node.clientHeight + 'px'
}
}
}

0 comments on commit bc5f382

Please sign in to comment.