JSFiddle - React, Tailwind, and code Playground
by dylanmac
HTML
<div id="geographicExposure" class="ui-helper-clearfix">
<div id="geographicDataTables">
<div id="countryExposureTable" data-top-countries-length="16">
<p class="geo-title">Countries</p>
<table class="exposure-table product-data-list">
<tbody>
<tr data-countryId="country-36">
<td>
<span class="legend" style="background-color: rgb(32,93,0)"> </span>
</td>
<td>
<a class="zoom-country" href="#">Australia</a>
</td>
<td>77.09%</td>
</tr>
<tr data-countryId="country-76">
<td>
<span class="legend" style="background-color: rgb(183,220,165)"> </span>
</td>
<td>
<a class="zoom-country" href="#">Brazil</a>
</td>
<td>6.1%</td>
</tr>
<tr data-countryId="country-410">
<td>
<span class="legend" style="background-color: rgb(187,224,169)"> </span>
</td>
<td>
<a class="zoom-country" href="#">South Korea</a>
</td>
<td>4.41%</td>
</tr>
<tr data-countryId="country-156">
<td>
<span class="legend" style="background-color: rgb(190,226,172)"> </span>
</td>
<td>
<a class="zoom-country" href="#">China</a>
</td>
<td>3.17%</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="map"></div>
</div>
<script src="http://d3js.org/d3.v3.js"></script>
<script src="http://d3js.org/topojson.v1.js"></script>
CSS
p {
margin: 0;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
border-collapse: collapse;
content: "";
display: table;
}
.ui-helper-clearfix:after {
clear: both;
}
.ui-helper-clearfix:before,
.ui-helper-clearfix:after {
border-collapse: collapse;
content: "";
display: table;
}
.ui-helper-clearfix {
min-height: 0;
}
#geographicExposure {
width: 600px;
}
#geographicDataTables {
float: left;
height: 214px;
overflow: hidden;
padding-right: 17px;
width: 170px;
}
.product-data-list {
border-collapse: collapse;
border-spacing: 0;
border-top: medium none;
}
.product-data-list tr.selected,
.product-data-list tr.selected td {
background-color: #CCCCCC;
}
.product-data-list td {
font-size: 0.85em;
padding: 5px 0;
}
.product-data-list td .legend {
padding: 0 6px;
}
.product-data-list tr a {
display: block;
color: #0B68B6;
text-decoration: none;
}
.product-data-list tr td:last-child {
text-align: right;
}
table {
width: 100%;
}
#map {
float: left;
height: 400px;
position: relative;
width: 400px;
}
.country.active {
fill: red;
}
.country.hover {
fill: orange;
}
.country {
fill: #ccc;
stroke: #fff;
stroke-width: 1px;
stroke-linejoin: round;
cursor: pointer;
}
.hidden {
display: none;
}
.tooltip {
color: #222;
background: #fff;
padding: .5em;
text-shadow: #f5f5f5 0 1px 0;
border-radius: 2px;
box-shadow: 0px 0px 2px 0px #a6a6a6;
opacity: 0.9;
position: absolute;
}
rect {
fill: none;
pointer-events: all;
}
path {
stroke: black;
stroke-width: 0.25px;
}
JavaScript
if (typeof BLK === "undefined" || !BLK) {
var BLK = {};
}
// d3 namespace
BLK.d3 = BLK.d3 || {};
// Set SVG Container Dimentions
var width = 400,
height = 300;
//Set Map projection
var projection = d3.geo.mercator()
.translate([width/2, height/1.5])
.scale(70);
// Set paths for SVG rendering
var path = d3.geo.path()
.projection(projection);
// SVG
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
// SVG groups
var g = svg.append("g");
// Set tooltips div
var tooltip = d3.select("#map").append("div")
.attr("class", "tooltip");
// function includes zoom, country and corresponding table row highlighting
BLK.d3.clickMap = function(d) {
var countryId = d3.select(this).attr('id');
$("tr.selected").removeClass('selected');
$("tr[data-countryId=" + countryId + "]").addClass('selected');
g.selectAll(".active").classed("active", false);
d3.select(this).classed("active", active = d);
var b = path.bounds(d);
g.transition().duration(500).attr("transform",
//"translate(" + projection.translate() + ")"
"translate(" + width/2 + "," + height/2 + ")"
+ "scale(" + .95 / Math.max((b[1][0] - b[0][0]) / width, (b[1][1] - b[0][1]) / height) + ")"
+ "translate(" + -(b[1][0] + b[0][0]) / 2 + "," + -(b[1][1] + b[0][1]) / 2 + ")");
}
// function resets map to initial zoom, removes country and table row highlighting
BLK.d3.resetMap = function() {
g.selectAll(".active").classed("active", active = false);
$("tr.selected").removeClass('selected');
g.transition().duration(750).attr("transform", "");
}
// function handles table row and corresponding country highlighting and map zooming
$('tr').on('click', function(d) {
var countryId = $(this).attr('data-countryId');
var mapTargetArea = d3.select('#' + countryId);
$('.product-data-list tr').removeClass('selected');
$(this).addClass('selected');
$("tr[data-countryId=" + countryId + "]").addClass('selected');
g.selectAll(".active").classed("active",...