Skip to content

Instantly share code, notes, and snippets.

@eesur
Last active September 13, 2019 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save eesur/11f85e7981c7b203768e to your computer and use it in GitHub Desktop.
Save eesur/11f85e7981c7b203768e to your computer and use it in GitHub Desktop.
d3 | hotspots

Hotspots with D3

Just a play with hotspots to make an image 'interactive' in D3 and an excuse to reminisce.

Process:

  • Find a pic, choose The Grand Budapest Hotel, it was an awesome film
  • Made a grid, so I can quickly reference the pixels
  • Made the data (my son helped me here)
  • Draw some transparent rects

Issues

Should have used a full size image, or one that at least had Zero in it. And I'm repeating what's on the pic already but hey …

(function() {
'use strict';
var width = 960,
height = 678;
// margin not used as want it to be flush
var svg = d3.select('#vis').append('svg')
.attr({
class: 'axis',
width: width,
height: height
});
function renderXAxis() {
var scale = d3.scale.linear()
.domain([0, 100])
.range([0, width]);
var xAxis = d3.svg.axis()
.scale(scale)
.orient('top');
svg.append('g')
.attr({
class: 'x-axis',
transform: function() {
return 'translate(0,' + height + ')';
}
})
.call(xAxis);
d3.selectAll('g.x-axis g.tick')
.append('line')
.classed('grid-line', true)
.attr({
x1: 0,
y1: 0,
x2: 0,
y2: -height
});
}
function renderYAxis() {
var scale = d3.scale.linear()
.domain([0, 100]) // want to keep y as it is
.range([0, height]);
var yAxis = d3.svg.axis()
.scale(scale)
.orient('right');
svg.append('g')
.attr({
class: 'y-axis',
transform: 'translate(0, 0)'
})
.call(yAxis);
d3.selectAll('g.y-axis g.tick')
.append('line')
.classed('grid-line', true)
.attr({
x1: 0,
y1: 0,
x2: width,
y2: 0
});
}
d3.select('#grid-bt').on('click', function() {
var grid = d3.selectAll('g.tick');
if (grid.empty()) {
renderYAxis();
renderXAxis();
} else {
grid.remove();
}
});
})();
(function() {
'use strict';
// var data = d3.range(0, 12); // [0, 1, 2, 3, 4 etc]
var data = [
{ realName: 'Ralph Fiennes', filmName: 'M. Gustave' },
{ realName: 'F. Murray Abraham', filmName: 'Mr. Moustafa' },
{ realName: 'Mathieu Amalric', filmName: 'Serge X.' },
{ realName: 'Adrien Brody', filmName: 'Dmitri' },
{ realName: 'Willem Dafoe', filmName: 'Jopling' },
{ realName: 'Jeff Goldblum', filmName: 'Deputy Kovacs' },
{ realName: ' Harvey Keitel', filmName: 'Ludwig' },
{ realName: 'Jude Law', filmName: 'Young Writer' },
{ realName: ' Bill Murray', filmName: ' M. Ivan' },
{ realName: 'Edward Norton', filmName: 'Henckels' },
{ realName: ' Saoirse Ronan', filmName: 'Agatha' },
{ realName: 'Jason Schwartzman', filmName: 'M. Jean' }
]
console.log('number of items in array: ' + data);
// vars
var rectWidth = 140,
rectHeight = 280,
amountInRow = 5;
var svg = d3.select('svg'); // already added via the grid
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr({
width: rectWidth,
height: rectHeight,
x: function(d,i) {
// use the index and width to place rect
// check the amount in row to set `i` to 0
if (i <= amountInRow) return (rectWidth+10)*i + 40;
else return (rectWidth+10)*(i-(amountInRow+1)) + 40;
},
y: function(d,i) {
// check the amount in row to make new row
if (i <= amountInRow) return 70;
else return rectHeight + 110;
}
})
.style({
fill: 'transparent',
stroke: 'none'
})
.on('mouseover', function(d, i) {
d3.select('header h1').text(d.realName);
d3.select('header p').text(d.filmName);
});
})();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>d3 | hotspots</title>
<meta name="author" content="Sundar Singh | eesur.com">
<link rel="stylesheet" href="main.css">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<header>
<h1>move over pic</h1>
<p></p>
<nav><button id="grid-bt">GRID</button></nav>
</header>
<section id="vis"></section>
<script src="d3_code_grid.js" charset="utf-8"></script>
<script src="d3_code_hotspots.js" charset="utf-8"></script>
</body>
</html>
@import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600);
body {
font-family: "Source Code Pro", Consolas, monaco, monospace;
line-height: 1.5;
font-weight: 400;
background-color: #130C0E;
padding: 20px;
}
h1 {
font-size: 48px;
color: #7AC143;
font-weight: 400;
margin: 0;
padding: 0;
line-height: 100%;
}
p {
font-size: 18px;
color: #7AC143;
font-weight: 400;
margin: 0;
padding: 0;
letter-spacing: 6px;
text-transform: uppercase;
}
text {
font-size: 14px;
fill: #7AC143;
}
#vis {
width: 960px;
height: 678px;
background-image: url("https://dl.dropboxusercontent.com/s/xgthuas2pxnga1s/The-Grand-Budapest-Hotel-Poster-slice.jpg");
background-size: 960px 678px;
background-repeat: no-repeat;
}
header {
width: 960px;
background: #130C0E;
z-index: 22;
position: relative;
height: 88px;
}
button {
font-family: "Source Code Pro", Consolas, monaco, monospace;
font-size: 14px;
background: #130C0E;
color: #7AC143;
border: none;
outline:none;
padding: 4px 8px;
letter-spacing: 1px;
}
button:hover {
background: #7AC143;
color: #130C0E;
}
#grid-bt {
position: absolute;
right: 0;
top: 10px;
}
.axis path, .axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis line {
stroke: black;
}
.axis text {
font: 10px sans-serif;
}
.axis .grid-line{
stroke: #7AC143;
shape-rendering: crispEdges;
stroke-opacity: .8;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment