The bug is that the images only show after hight light the continent dot on the right.
And the blur effect of the countries in Asia is abnormal: they don't have the slow reclear effect as other countries.
Built with blockbuilder.org
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js"></script>
<title>Basic Scatter Plot</title>
<style>
body {
margin: 0px;
}
.domain {
display: none;
}
.tick line {
stroke: #C0C0BB;
}
.tick text, .legendCells text {
fill: #8E8883;
font-size: 13pt;
font-family: sans-serif;
}
.axis-label, .legend-label {
fill: #635F5D;
font-size: 15pt;
font-family: sans-serif;
}
</style>
</head>
<body>
<svg width="960" height="500"></svg>
<script>
const xValue = d => d.income;
const xLabel = 'Income Per Person, ($/year)';
const yValue = d => d.health;
const yLabel = 'Health Expectancy, (years)';
const rValue = d => d.population;
const rLabel = 'Size of spots stand for population';
const colorLabel = 'region';
const margin = {left: 120, right: 250, top: 30, bottom: 100};
const svg = d3.select('svg');
const width = svg.attr('width');
const height = svg.attr('height');
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
let hoveredColorValue;
const hoveredStrokeColor = "black";
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
// This is the layer where the bars are drawn.
const baseBarLayer = g.append("g");
// This layer contains a semi-transparent overlay
// that fades out the base bars.
const overlayRect = g.append("g")
.append("rect")
.attr("width", innerWidth)
.attr("height", innerHeight)
.attr("fill", "none")
.style("pointer-events", "none");
// This contains the subset of bars rendered on top
// when you hover over the entries in the color legend.
const foregroundBarLayer = g.append("g");
const xAxisG = g.append('g')
.attr('transform', `translate(0, ${innerHeight})`);
const yAxisG = g.append('g');
const colorLegendG = g.append('g')
.attr("class", "color-legend")
.attr('transform', `translate(${innerWidth + 60}, 150)`);
xAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', innerWidth / 2)
.attr('y', 70)
.text(xLabel);
yAxisG.append('text')
.attr('class', 'axis-label')
.attr('x', -innerHeight / 2)
.attr('y', -60)
.attr('transform', `rotate(-90)`)
.style('text-anchor', 'middle')
.text(yLabel);
colorLegendG.append('text')
.attr('class', 'legend-label')
.attr('x', -30)
.attr('y', -40);
const xScale = d3.scaleLog();
const yScale = d3.scaleLinear();
const rScale = d3.scaleSqrt();
const colorScale = d3.scaleOrdinal()
.range(d3.schemeCategory10);
const xAxis = d3.axisBottom()
.scale(xScale)
.ticks(11, ",.1s")
.tickPadding(15)
.tickSize(-innerHeight);
const yAxis = d3.axisLeft()
.scale(yScale)
.ticks(5)
.tickPadding(15)
.tickSize(-innerWidth);
const colorLegend = d3.legendColor()
.scale(colorScale)
.shape('circle');
const row = d => {
d.income = +d.income;
d.health = +d.health;
d.population = +d.population;
return d;
};
function render(data) {
const nested = d3.nest()
.key(function (d) {
return d[colorLabel];
})
.entries(data);
xScale
.domain(d3.extent(data, xValue))
.range([0, innerWidth])
.nice;
yScale
.domain(d3.extent(data, yValue))
.range([innerHeight, 0])
.nice();
rScale
.domain(d3.extent(data, rValue))
.range([4, 18]);
colorScale.domain(nested.map(function (nested) {
return nested.key;
}));
xAxisG.call(xAxis);
yAxisG.call(yAxis);
renderBars(baseBarLayer, nested);
if (hoveredColorValue) {
setOverlayTransparency(0.8);
renderBars(foregroundBarLayer, nested.filter(function (layer) {
return layer.key === hoveredColorValue;
}));
} else {
setOverlayTransparency(0.0);
renderBars(foregroundBarLayer, nested);
}
colorLegendG.call(colorLegend)
.selectAll('.cell text')
.attr('dy', '0.1em');
listenForHover(colorLegendG.selectAll("circle"), data);
listenForHover(colorLegendG.selectAll("text"), data);
}
function renderBars(g, layers) {
const layerGs = g.selectAll(".layer").data(layers);
layerGs.enter().append("g").attr("class", "layer");
layerGs.exit().remove();
layerGs.style("fill", function (d) {
return colorScale(d.key);
});
const circles = layerGs.selectAll('.mark').data(function (d) {
return d.values;
});
circles.enter().append('circle')
.attr('class', 'mark')
.merge(circles)
.attr('cx', d => xScale(xValue(d)))
.attr('cy', d => yScale(yValue(d)))
.attr('fill-opacity', 0.8)
.attr('r', d => rScale(rValue(d)));
circles.exit().remove();
}
function listenForHover(selection, data) {
selection
.on("mouseover", function (d) {
hoveredColorValue = d;
render(data);
})
.on("mouseout", function (d) {
hoveredColorValue = null;
render(data);
})
.style("cursor", "pointer");
}
function setOverlayTransparency(alpha) {
overlayRect
.transition().duration(400)
.attr("fill", "rgba(255, 255, 255, " + alpha + ")");
}
d3.csv('income_health.csv', row, render);
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://cdnjs.cloudflare.com/ajax/libs/d3-legend/2.24.0/d3-legend.min.js