block by shimizu 808e0f5cadb6a63f28bb00082dc8fe3f

Inversion with ordinal scale

Full Screen

Ordiran scaleにinvertメソッドがなかったので、代価案を考えた。

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>D3 ver.4 - ordinal scale invert</title>

<style>
html, body {
    position:fixed;
    top:0;right:0;bottom:0;left:0;
    width: 100%;
    height: 100%;
    padding: 0px;
    margin: 0px;
}
    
svg {
    width: 900px;
    height:500px;
}
</style>

</head>

<body>
<svg id="example"></svg>


<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script>    

<script>
var width = document.querySelector("svg").clientWidth
var height = document.querySelector("svg").clientHeight
var margin = {top:50, left:50, bottom:50, right:50 }


var svg = d3.select("#example")

var AxisLayer = svg.append("g").attr("class", "AxisLayer")
var chartLayer = svg.append("g").attr("class", "chartLayer")
    .attr("transform", "translate("+[margin.left, margin.top]+")")

var overLayer = svg.append("g").attr("class", "overLayer")
    .attr("transform", "translate("+[margin.left, margin.top]+")")
    

var guideLine = overLayer.append("line")
            .attr("class", "guideLine")
            .attr("x1", 0)
            .attr("y1", 0)
            .attr("x2", 0)
            .attr("y2", height-(margin.top+margin.bottom))
            .attr("stroke", "red")
    
var eventCapture = chartLayer.append("rect")
    .attr("width", width-(margin.left+margin.right))
    .attr("height", height-(margin.top+margin.bottom))
    .attr("opacity", 0)


        
var xScale = d3.scaleBand()
var yScale = d3.scaleLinear()

var xAxis = d3.axisBottom()
var yAxis = d3.axisLeft()
    
xScale.domain(["A", "B", "C", "D", "E", "F", "G", "H"]).range([0, width-(margin.top+margin.bottom)])
yScale.domain([0, 1000]).range([height-(margin.top+margin.bottom), 0])

// custom invert function
xScale.invert = (function(){
    var domain = xScale.domain()
    var range = xScale.range()
    var scale = d3.scaleQuantize().domain(range).range(domain)

    return function(x){
        return scale(x)
    }
})()

xAxis.scale(xScale)
yAxis.scale(yScale)    
drawAxis()

eventCapture
    .on("mousemove", function(e){
         var xy = d3.mouse(eventCapture.node())
         var d = xScale.invert(xy[0]) 
         var nx = xScale(d) + (xScale.bandwidth()/2)
         
        guideLine.transition().duration(100).attr("x1", nx).attr("x2", nx)
    })
            
        
function drawAxis(){
    var t = d3.transition()
        .duration(500)
    
    var x = AxisLayer.selectAll(".x")
        .data(["dummy"])
        
    var newX = x.enter().append("g")
        .attr("class", "x axis")
        .attr("transform", "translate("+[margin.left, height-margin.top]+")")

    x.merge(newX).transition(t).call(xAxis)

    var y = AxisLayer.selectAll(".y")
        .data(["dummy"])
        
    var newY = y.enter().append("g")
        .attr("class", "y axis")
        .attr("transform", "translate("+[margin.left, margin.top]+")")

    y.merge(newY).transition(t).call(yAxis)
    
    
}    
     
    
</script>

    
</body>
</html>