Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3.js v3 to v4 Brush changes

Tags:

d3.js

I'm looking to migrate from d3v3 to d3v4. In particular i'm having difficulties in migrating brushes.

Can someone please have a look at below link and let me know the changes? http://bl.ocks.org/zanarmstrong/ddff7cd0b1220bc68a58

Some changes i have identified:

d3.time.format -> d3.timeFormat

d3.time.scale -> d3.scaleTime

Facing issues in migrating:

d3.svg.brush -> d3.brushX

Thanks & Regards,

Naishav

like image 645
Naishav Mehta Avatar asked Mar 14 '17 08:03

Naishav Mehta


2 Answers

Quick guide for migrating d3-brush from D3 v3 to D3 v4 (example for brushX)

  1. Replace d3.svg.brush() with d3.brushX().
  2. Rename brushstart event to start, brushend to end.
  3. Don't pass scale to .x(xScale), this method is now missing. Pass brush borders as .extent([[xScale.range()[0], 0], [xScale.range()[1], brushHeight]]).
  4. In event handler you can get selection as d3.event.selection, for getting selected values use d3.event.selection.map(xScale.invert).
  5. To setup selection do .move(brushContainer, selectedDomain.map(xScale)). To clear selection do .move(brushContainer, null). Note that this will fire event handlers.
  6. .empty() method is now missing, use d3.event.selection === null.
  7. Update your CSS, .extent is now .selection, .resize is .handle and became a rect instead of g containing rect.
like image 122
Alexander Shutau Avatar answered Nov 07 '22 17:11

Alexander Shutau


It seems rather strange to abuse the d3.brush like that when you can code this so much more straightforward with regular events:

<!DOCTYPE html>
<html>

<head>
  <style>
      body {
      background-color: #393939;
      font-size: 14px;
      font-family: 'Raleway', sans-serif;
    }
    
    p {
      color: white;
      margin: 50px;
    }
    
    a {
      color: #4FDEF2;
    }
    
    .axis {
      fill: gray;
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;
    }
    
    .axis .halo {
      stroke: gray;
      stroke-width: 4px;
      stroke-linecap: round;
    }
    
    .handle path {
      stroke: white;
      stroke-width: 3px;
      stroke-linecap: round;
      pointer-events: none;
    }
    
    .handle text {
      fill: white;
      text-align: center;
      font
  </style>
</head>

<body>

  <script src="https://d3js.org/d3.v4.min.js"></script>

  <script>
    // parameters
    var margin = {
        top: 50,
        right: 50,
        bottom: 50,
        left: 50
      },
      width = 960 - margin.left - margin.right,
      height = 300 - margin.bottom - margin.top;


    // scale function
    var timeScale = d3.scaleTime()
      .domain([new Date('2012-01-02'), new Date('2013-01-01')])
      .range([0, width])
      .clamp(true);

    var formatDate = d3.timeFormat("%b %d");

    var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      // classic transform to position g
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
      

    svg.append("rect")
      .style("pointer-events", "all")
      .style("fill", "none")
      .attr("width", width)
      .attr("height", height)
      .style("cursor", "crosshair")
      .on("mousedown", function(){
        updatePos(this);
      })
      .on("mousemove", function(){
        if (d3.event.which === 1){
          updatePos(this);
        }
      });

    function updatePos(elem){
      var xPos = d3.mouse(elem)[0];
      handle.attr('transform', 'translate(' + xPos + ",0)");
      text.text(formatDate(timeScale.invert(xPos)));
    }

    svg.append("g")
      .attr("class", "x axis")
      // put in middle of screen
      .attr("transform", "translate(0," + height / 2 + ")")
      // inroduce axis
      .call(d3.axisBottom()
        .scale(timeScale)
        .tickFormat(function(d) {
          return formatDate(d);
        })
        .tickSize(0)
        .tickPadding(12)
        .tickValues([timeScale.domain()[0], timeScale.domain()[1]]))
      .select(".domain")
      .select(function() {
        console.log(this);
        return this.parentNode.appendChild(this.cloneNode(true));
      })
      .attr("class", "halo");

    var handle = svg.append("g")
      .attr("class", "handle")
      
    handle.append("path")
      .attr("transform", "translate(0," + height / 2 + ")")
      .attr("d", "M 0 -20 V 20")

    var text = handle.append('text')
      .text(formatDate(timeScale.domain()[0]))
      .attr("transform", "translate(" + (-18) + " ," + (height / 2 - 25) + ")");

  </script>
</body>

</html>
like image 3
Mark Avatar answered Nov 07 '22 18:11

Mark