svg = {
const svg = d3.select(DOM.svg(width + (hexRadius * 5), height));
const g = svg.append('g').attr('transform', `translate(${hexRadius*4},${hexRadius * 10})`);
const modelRuns = g.selectAll('.run-time')
.data( points.slice(0, 24 ))
.join('text')
.text((d, i) => {
return moment.utc(mostRecentModelRunData).subtract( mapColumns, 'hour').add( i, 'hour').format( 'YYYY-MM-DD HH')
})
.attr('class', 'run-time')
.attr('x', d => d.x - hexRadius)
.attr('y', -hexRadius)
.attr('transform', d => ( 'rotate(60 ' + (d.x - hexRadius ) + ' ' + -hexRadius + ')'))
.style('text-anchor', 'end')
.style('fill', 'black')
.style('stroke', 'none');
const rowLabels = g.selectAll('.row-label')
.data( dataArray[0] ).enter()
.append('text')
.text((d,i) => i === 0 ? 'Observed Dst' : 'T+' + i + ' difference' )
.attr('class', 'row-label')
.attr('x', (d,i) => ( mapColumns * hexRadius * SQRT3 ) + (i * (hexRadius * SQRT3 / 2)))
.attr('y', (d,i) => (i * hexRadius * 1.5) + 3)
.style('fill', 'black')
.style('stroke', 'none')
.style('text-anchor', 'start')
const hexagons = g.selectAll('.hexagon')
.data(hexbin(points))
.join('path')
.attr('class', 'hexagon')
.style('stroke', 'white')
.style('stroke-width', 1.5)
.style('fill', (d) => {
return d.y === 0 ? 'goldenrod' : isNaN(d[0].difference) ? 'gainsboro' : color(d[0].difference);
})
.style('fill-opacity', d => isNaN(d[0].difference) ? 1 : 0.6)
.attr('d', (d, i) => {
return 'M' + d.x + ',' + d.y + hexbin.hexagon()
});
// Add difference value to hexagon content
const values = g.selectAll('.value')
.data( points ).enter()
.append('text')
.text(d => isNaN(d.difference) ? d.value : d.difference )
.attr('class', 'value')
.attr('x', d => d.x.toFixed(0))
.attr('y', d => d.y + 3)
.style('fill', d => isNaN(d.difference) ? 'goldenrod' : 'black')
.style('stroke', 'white')
.style('stroke-width', 0.1)
.style('text-anchor', 'middle')
.on('mouseover', hover)
.on('mouseout', leave);
// Mouseover a value
function hover(d) {
hexagons.style( 'fill-opacity', h => !isNaN(d.difference) && d.time === h[0].time ? 1 : 0.6)
.style('stroke-width', h => !isNaN(d.difference) && d.time === h[0].time ? 5 : 1.5);
modelRuns.style( 'fill', m => d.time === m.time ? 'goldenrod' : 'black');
d3.select(this)
.transition().duration(10)
.text( d => d.value)
.style('fill', 'goldenrod')
.style('cursor', 'default')
}
// Mouseout function
function leave(d) {
hexagons.style( 'fill-opacity', 0.6)
.style('stroke-width', 1.5);
modelRuns.style( 'fill', 'black');
d3.select(this)
.transition().duration(500)
.style('fill-opacity', 0.6)
.style('fill', d => d.difference ? 'black' : 'goldenrod' )
.text( d => isNaN(d.difference) ? d.value : d.difference)
}
return svg.node()
}