block by 1wheel da6c526602c05a5a77390620a6be3040

canvas-interaction

Full Screen

Scanning to find the closest point on canvas.

index.html

<!DOCTYPE html>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="style.css">

<div id='graph'></div>
<script src='d3_.js'></script>

<script type="text/javascript">
var ttSel = d3.select('body').selectAppend('div.tooltip.tooltip-hidden')

var sel = d3.select('#graph').html('')
var c = d3.conventions({
  sel, 
  margin: {left: 30},
  layers: 'cs',
})

var [ctx, svg] = c.layers
d3.drawAxis(c)

var colorScale = d3.scaleLinear().range(['#f0f', '#0f0'])

var data = d3.range(500000).map(() => {
  var r = Math.random()
  var px = c.x(r)
  var py = c.y(Math.random())
  var color = colorScale(r + Math.random()/5)

  ctx.fillStyle = color
  ctx.fillRect(px, py, 1, 1)

  return {px, py, color}
})

var highlightCircle = svg.append('circle')
  .at({r: 10, fill: 'none'})
  .st({pointerEvents: 'none'})

svg.append('rect')
  .at({width: c.width, height: c.height, fillOpacity: 0})
  .call(d3.attachTooltip)
  .on('mousemove', function(){
    var [px, py] = d3.mouse(this)

    var startT = new Date()
    var m = _.minBy(data, d => {
      var dx = d.px - px
      var dy = d.py - py

      return dx*dx + dy*dy
    })

    ttSel.text(m.color + ' found in ' + (new Date() - startT) + 'ms')

    highlightCircle
      .translate([m.px, m.py])
      .at({stroke: m.color, strokeWidth: 4})
  })
  .on('mouseout', function(){
    highlightCircle.at({strokeWidth: 0})
  })
</script>

style.css

body{
  font-family: menlo, Consolas, 'Lucida Console', monospace; 
  margin: 0px;
}

.tooltip {
  top: -1000px;
  position: fixed;
  padding: 10px;
  background: rgba(255, 255, 255, .90);
  border: 1px solid lightgray;
  pointer-events: none;
}
.tooltip-hidden{
  opacity: 0;
  transition: all .3s;
  transition-delay: .1s;
}

@media (max-width: 590px){
  div.tooltip{
    bottom: -1px;
    width: calc(100%);
    left: -1px !important;
    right: -1px !important;
    top: auto !important;
    width: auto !important;
  }
}

svg{
  overflow: visible;
}

.domain{
  display: none;
}

text{
  pointer-events: none;
  text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
}