JSFiddle - React, Tailwind, and code Playground

by Gabriel Z

CSS

.axis path, .axis line {
    fill:none;
    rendering:crispEdges;
    stroke:black;
    width:2.5;
}

g {
    pointer-events: all;
}

JavaScript

var width = 800,
    height = 600,
    padding = 30;

var randomX = [],
    randomY = [];
for (var i = 0; i <= 100; i++) {
    randomX[i] = Math.random() * 400;
    randomY[i] = Math.random() * 400;
}

var minX = d3.min(randomX),
    maxX = d3.max(randomX),
    minY = d3.min(randomY),
    maxY = d3.max(randomY);

var xScale = d3.scale.linear().domain([minX, maxX]).range([0, width - padding]);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
var yScale = d3.scale.linear().domain([minY, maxY]).range([height - padding, 0]);
var yAxis = d3.svg.axis().scale(yScale).orient("left");

var svgContainer = d3.select("body").append("div").append("svg").attr("width", width).attr("height", height);
var svg = svgContainer.append("g");

svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + "," + (height - padding) + ")").call(xAxis);
svg.append("g").attr("class", "axis").attr("transform", "translate(" + padding + ",0)").call(yAxis);

var canvas = svg.append("g").attr("transform", "translate(" + padding + ",0)");

canvas.append("g").attr("class", "dot").selectAll("scatter-dots")
    .data(randomY)
    .enter().append("svg:circle")
    .attr("cy", function (d) {
    return yScale(d);
})
    .attr("cx", function (d, i) {
    return xScale(randomX[i]);
})
    .style("fill", "brown")
    .attr("r", 3);

var crossHair = canvas.append("g").attr("class", "crosshair");
crossHair.append("line").attr("id", "h_crosshair") // horizontal cross hair
.attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", 0)
    .attr("y2", 0)
    .style("stroke", "gray")
    .style("stroke-width", "1px")
    .style("stroke-dasharray", "5,5")
    .style("display", "none");

crossHair.append("line").attr("id", "v_crosshair") // vertical cross hair
.attr("x1", 0)
    .attr("y1", 0)
    .attr("x2", 0)
    .attr("y2", 0)
    .style("stroke", "gray")
    .style("stroke-width", "1px")
    .style("stroke-dasharray", "5,5")
    .style("display",...