block by shimizu f23890cfb55eb52dc1629b3cd96e3d51

Change Axis Example

Full Screen

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html lang="jp">
  <head>
    <style>
      html, body {
        margin: 0px;
        padding: 0px;
        width:100%;
        height:100%;
      }

      #chart {
        width: 100%;
        height: 90%;
      }
      #chart svg{
        width: 100%;
        height: 100%;
        cursor: default;
      }

      .grid .tick line {
        stroke:gray;
        stroke-dasharray:1;
      }

      .button-radio {
        margin: 10px;
      }

      .button-radio input[type="radio"] {
        display:none; 
      }

      .button-radio label {
        width: 100px;
        text-align: center;
        display:inline-block;
        color:#000;
        border: 1px solid black;
        background-color:#fff;
        padding:5px 10px;
      }

      .button-radio input[type="radio"]:checked + label {
        color:white;
        background-color:#000;
      }

    </style>

    <script src="//unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    <script src="//unpkg.com/d3@4.12.2/build/d3.min.js"></script>    
  </head>
  <body>
    <div class="button-radio">
      切り替えボタン
      <input id="btn1" type="radio" name="index" value="身長" checked/><label for="btn1">身長</label>
      <input id="btn2" type="radio" name="index" value="体重" /><label for="btn2">体重</label>
    </div>
    <div id="chart">
      <svg></svg>
    </div>



    <script type="text/babel">
      let data = null;    


      const btn = d3.select(".button-radio");

      const svg = d3.select("#chart").select("svg");
      const grid = svg.append("g").classed("grid", true)
      const plot = svg.append("g").classed("plot", true)
      const axis = svg.append("g").classed("axis", true);
      const yScale = d3.scaleLinear().domain([15, 0]);
      const xScale =  d3.scaleLinear();

      const xAxisUnit = {
        "身長":"cm",
        "体重":"kg"
      }


      let t = d3.transition().duration(10);

      let xIndex = "身長";
      let yIndex = "年齢";


      const cast = d => {
        Object.keys(d).forEach(key => {
          if(!isNaN(+d[key])) d[key] = +d[key];
        });
        return d 
      }

      d3.tsv("data.tsv", tsv =>{
        data = tsv.map(cast);
        render();
        t = d3.transition().duration(1400);
      });


      btn.on("change", function(){
        xIndex = btn.selectAll("input").nodes().filter(d => d.checked)[0].value;
        render();
      });

      function render(){


        const w = svg.node().clientWidth || svg.node().parentNode.clientWidth;
        const h = svg.node().clientHeight || svg.node().parentNode.clientHeight;

        const m = {top:40, left:40, right:40, bottom:40};

        const r = 6;

        const yTicks =  11; 
        const xTicks =  9; 

        const pw = w - (m.left + m.right);
        const ph = h - (m.top + m.bottom);


        yScale.range([0, ph]);
        xScale.range([0, pw]);

        const yMax = d3.max(data, d => d[yIndex]) * 1.2;
        const xMax = d3.max(data, d => d[xIndex]) * 1.2;

        console.log(data)

        yScale.domain([yMax, 0])
        xScale.domain([0, xMax])


        //update axis layer
        axis.attr("transform", `translate(${m.left}, ${m.top})`);

        //y axis    
        const yAxisUpdate = axis.selectAll(".yAxis").data([null]);
        const yAxisEnter = yAxisUpdate.enter().append("g").classed("yAxis", true);
        const yAxisCall = d3.axisLeft()
        .scale(yScale)
        .ticks(yTicks)
        .tickFormat(d => d+"歳")


        yAxisUpdate.merge(yAxisEnter)
          .transition(t)
          .call(yAxisCall);

        //x axis
        const xAxisUpdate = axis.selectAll(".xAxis").data([null]);
        const xAxisEnter = xAxisUpdate.enter().append("g").classed("xAxis", true);
        const xAxisCall = d3.axisBottom()
        .scale(xScale)
        .ticks(xTicks)
        .tickFormat(d => d + xAxisUnit[xIndex])


        xAxisUpdate.merge(xAxisEnter)
          .transition(t)
          .call(xAxisCall)
          .attr("transform", `translate(0, ${ph})`);


        //update grid layer   
        grid.attr("transform", `translate(${m.left}, ${m.top})`);

        //y grid
        const yGridUpdate = grid.selectAll(".yGrid").data([null]);
        const yGridEnter = yGridUpdate.enter().append("g").classed("yGrid", true);

        yGridUpdate.merge(yGridEnter)
          .transition(t)
          .call( d3.axisLeft().scale(yScale).tickSizeInner(-pw).tickFormat( ()=> null) )


        //x grid    
        const xGridUpdate = grid.selectAll(".xGrid").data([null]);
        const xGridEnter = xGridUpdate.enter().append("g").classed("xGrid", true);

        xGridUpdate.merge(xGridEnter)
          .transition(t)
          .call( d3.axisBottom().scale(xScale).tickSizeInner(-ph).tickFormat( ()=> null) )
          .attr("transform", `translate(0, ${ph})`);


        //update plot layer 
        plot.attr("transform", `translate(${m.left}, ${m.top})`);

        //dot
        const dotsUpdate = plot.selectAll(".dot").data(data);
        const dotsEnter = dotsUpdate.enter().append("circle").classed("dot", true);

        const dots = dotsUpdate.merge(dotsEnter)
        .transition(t)
        .attr("r", r)
        .attr("cx", d => xScale(d[xIndex]) )
        .attr("cy", d => yScale(d[yIndex]) )


        }





    </script>


  </body>
</html>

data.tsv

年齢	身長	体重
5	110.4	18.9
6	116.5	21.3
7	122.5	23.9
8	128.1	26.9
9	133.5	30.4
10	138.9	34
11	145.2	38.2
12	152.6	43.9
13	159.8	48.8
14	165.1	53.9
15	168.3	59
16	169.8	60.6
17	170.7	62.5