Skip to content
This repository has been archived by the owner on Nov 10, 2020. It is now read-only.

Commit

Permalink
Merge pull request #1921 from 18F/map-tooltips
Browse files Browse the repository at this point in the history
Map tooltips
  • Loading branch information
meiqimichelle authored Sep 14, 2016
2 parents a4c4587 + 4b7437d commit 78b9c71
Show file tree
Hide file tree
Showing 14 changed files with 505 additions and 86 deletions.
5 changes: 3 additions & 2 deletions _includes/maps/offshore-regions.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
{% for region in site.offshore_regions %}
{% if include.href %}<a xlink:href="{{ site.baseurl }}{{ include.href | format_url: region }}">{% endif %}
<g class="state offshore-area feature" fill><!--- FIXME: nix fill attribute -->
<title>{{ region.title }}</title>
<use xlink:href="{{ _svg_path }}#{{ region.id }}"></use>
<title desc="{{ region.title }}"
alt="{{ region.title }}">{{ state.title }}</title>
<use xlink:href="{{ _svg_path }}#{{ region.id }}" aria-label="{{ region.title }}"></use>
</g>
{% if include.href %}</a>{% endif %}
<g class="states mesh">
Expand Down
6 changes: 4 additions & 2 deletions _includes/maps/state-areas.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
<g class="state feature" {% if include.value %}
{% assign state_value = include.states[state.id] | get: include.value %}
data-value='{{ state_value | default: 0 | jsonify }}'{% endif %}>
<title>{{ state.title }}: {{ value }}</title>
<use xlink:href="{{ _svg_path }}#state-{{ state.id }}"></use>
<title desc="{{ state.title }}"
alt="{{ state.title }}">{{ state.title }}</title>
<use xlink:href="{{ _svg_path }}#state-{{ state.id }}" aria-label="{{ state.title }}"></use>
</g>

{% if include.href %}</a>{% endif %}
{% endfor %}

Expand Down
2 changes: 1 addition & 1 deletion _includes/state-map.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
{% assign states_svg = '/maps/states/all.svg' %}
{% assign offshore_svg = '/maps/offshore/all.svg' %}

<div class="state svg-container map-container wide"{% if _viewbox %} style="padding-bottom: {{ _viewbox | svg_viewbox_padding }}%;"{% endif %}>
<div is="eiti-tooltip-wrapper" class="state svg-container map-container wide"{% if _viewbox %} style="padding-bottom: {{ _viewbox | svg_viewbox_padding }}%;"{% endif %}>
<svg class="states map{% if include.case_studies %} case_studies {% endif %}{% if include.ownership %} ownership {% endif %}{% if include.no_outline %} no-outlines {% endif %}"{% if _viewbox %} viewBox="{{ _viewbox }}"{% endif %}>

{% if include.offshore_regions != false %}
Expand Down
1 change: 1 addition & 0 deletions _sass/components/_all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@
@import 'flowchart';
@import 'tabs';
@import 'sticky';
@import 'tooltip';
18 changes: 18 additions & 0 deletions _sass/components/_tooltip.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.eiti-tooltip {
background: $white;
border: 2px solid $greenest-land;
max-width: 300px;
padding: $base-padding-lite;
padding-bottom: ($base-padding-lite / 2);
padding-top: 0.23em; // to account for verticality of text
position: absolute;
z-index: 9000;

p {
@include heading('para-sm');

color: $greenest-land;
font-weight: $weight-bold;
margin: 0;
}
}
12 changes: 12 additions & 0 deletions _sass/elements/_maps.scss
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,22 @@ svg.map {

.feature.offshore-area use {
fill: $greenest-land;

&:hover,
&:active,
&:focus {
fill: darken($greenest-land, 5%);
}
}

.feature:not([fill]) use {
fill-opacity: 0;

&:hover,
&:active,
&:focus {
fill-opacity: 0.3;
}
}

.feature[fill] use {
Expand Down
122 changes: 122 additions & 0 deletions js/components/eiti-tooltip-wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
(function(exports) {

var depixelize = function(value) {
if (value.indexOf('px') > -1) {
return +value.substr(0, value.length - 2);
} else {
return value;
}
};

var pixelize = function(value) {
return value + 'px';
};

var hideTooltip = function (tooltip) {
tooltip.attr('aria-hidden', true);
};

var attached = function() {
var self = d3.select(this);
var svg = d3.select('svg');
var svgParent = self;
var titles = self.selectAll('title');
var tiles = self.selectAll('use');

var tooltip,
tooltipText;

var init = function(initialize) {
tooltip = self.select('.eiti-tooltip');

if (tooltip.empty()) {
tooltip = self.append('div')
.classed('eiti-tooltip', true);
}

tooltip
.attr('aria-hidden', true);

tooltipText = tooltip.select('p');

if (tooltipText.empty()) {
tooltipText = tooltip.append('p');
}

// clear <title> text
// if no javascript runs, <title> will serve as the tooltip
// otherwise, clear it so that it doesn't interfere with
// this tooltip
titles.text('');
};

var update = function() {
var event = event || d3.event || window.event;
var elem = event.target || event.srcElement;

var parentElement = d3.select(elem.parentElement);
var title = parentElement.select('title');

init();

tooltipText.text(function(){
return title.attr('desc');
});

tooltip
.attr('aria-hidden', false)
.attr('aria-label', function(){
return title.attr('alt');
})
.style('left', function() {
var tooltipWidth = depixelize(tooltip.style('width'));
var svgWidth = depixelize(svg.style('width'));

if (svgWidth <= tooltipWidth + event.layerX) {
return pixelize(event.layerX - tooltipWidth);
} else {
return pixelize(event.layerX);
}
})
.style('top', function() {
var tooltipHeight = depixelize(tooltip.style('height'));
var svgHeight = depixelize(svg.style('height'));

if (svgHeight <= tooltipHeight + event.layerY) {
return pixelize(event.layerY - tooltipHeight);
} else {
return pixelize(event.layerY);
}
});
};

var hide = function () {
var event = event || window.event;
var elem = event.target || event.srcElement;
if (elem.nodeName === 'svg') {
var tooltip = self.select('.eiti-tooltip');
hideTooltip(tooltip);
}
};

init(this);

tiles.on('mouseover', update);
svg.on('mouseout', hide);
};

var detached = function() { };

exports.EITITooltipWrapper = document.registerElement('eiti-tooltip-wrapper', {
extends: 'div',
prototype: Object.create(
HTMLElement.prototype,
{
attachedCallback: {value: attached},
detachdCallback: {value: detached}
}
)
});

})(this);

130 changes: 130 additions & 0 deletions js/lib/homepage.min.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
'use strict';

__webpack_require__(7);
__webpack_require__(41);

})(window);

Expand Down Expand Up @@ -193,6 +194,135 @@
});


/***/ },

/***/ 41:
/***/ function(module, exports) {

(function(exports) {

var depixelize = function(value) {
if (value.indexOf('px') > -1) {
return +value.substr(0, value.length - 2);
} else {
return value;
}
};

var pixelize = function(value) {
return value + 'px';
};

var hideTooltip = function (tooltip) {
tooltip.attr('aria-hidden', true);
};

var attached = function() {
var self = d3.select(this);
var svg = d3.select('svg');
var svgParent = self;
var titles = self.selectAll('title');
var tiles = self.selectAll('use');

var tooltip,
tooltipText;

var init = function(initialize) {
tooltip = self.select('.eiti-tooltip');

if (tooltip.empty()) {
tooltip = self.append('div')
.classed('eiti-tooltip', true);
}

tooltip
.attr('aria-hidden', true);

tooltipText = tooltip.select('p');

if (tooltipText.empty()) {
tooltipText = tooltip.append('p');
}

// clear <title> text
// if no javascript runs, <title> will serve as the tooltip
// otherwise, clear it so that it doesn't interfere with
// this tooltip
titles.text('');
};

var update = function() {
var event = event || d3.event || window.event;
var elem = event.target || event.srcElement;

var parentElement = d3.select(elem.parentElement);
var title = parentElement.select('title');

init();

tooltipText.text(function(){
return title.attr('desc');
});

tooltip
.attr('aria-hidden', false)
.attr('aria-label', function(){
return title.attr('alt');
})
.style('left', function() {
var tooltipWidth = depixelize(tooltip.style('width'));
var svgWidth = depixelize(svg.style('width'));

if (svgWidth <= tooltipWidth + event.layerX) {
return pixelize(event.layerX - tooltipWidth);
} else {
return pixelize(event.layerX);
}
})
.style('top', function() {
var tooltipHeight = depixelize(tooltip.style('height'));
var svgHeight = depixelize(svg.style('height'));

if (svgHeight <= tooltipHeight + event.layerY) {
return pixelize(event.layerY - tooltipHeight);
} else {
return pixelize(event.layerY);
}
});
};

var hide = function () {
var event = event || window.event;
var elem = event.target || event.srcElement;
if (elem.nodeName === 'svg') {
var tooltip = self.select('.eiti-tooltip');
hideTooltip(tooltip);
}
};

init(this);

tiles.on('mouseover', update);
svg.on('mouseout', hide);
};

var detached = function() { };

exports.EITITooltipWrapper = document.registerElement('eiti-tooltip-wrapper', {
extends: 'div',
prototype: Object.create(
HTMLElement.prototype,
{
attachedCallback: {value: attached},
detachdCallback: {value: detached}
}
)
});

})(this);



/***/ }

/******/ });
Loading

0 comments on commit 78b9c71

Please sign in to comment.