Масштаб по порядковому номеру d3 по прямоугольнику не работает

После долгих поисков в Google я не смог найти, как реализовать масштабирование путем рисования прямоугольника при наличии порядковой шкалы как для оси x, так и для оси y.

используя d3.behaviour.zoom() по умолчанию, я могу масштабировать / панорамировать с помощью колесика мыши / двойного щелчка. Но я пытаюсь нарисовать прямоугольник на диаграмме, а затем запустить увеличение выбранной области.

в основном, я пытаюсь увеличить диаграмму тепловой карты с порядковыми шкалами, нарисовав прямоугольник. jsfiddle

var zoom = d3.behavior.zoom().on("zoom", zoomHandler);

xRange = d3.scale.ordinal().rangeBands([0, width]);
  yRange = d3.scale.ordinal().rangeBands([height, 0]);

function zoomHandler(){
  console.log('zoomed');
  var translate = zoom.translate(),
               scale = zoom.scale();

   var tx = Math.min(0, Math.max(translate[0], width - width * scale));
   var ty = Math.min(0, Math.max(translate[1], height - height * scale));

   zoom.translate([tx, ty]);

   xRange.rangeBands([d3.event.translate[0], d3.event.translate[0] + (width * d3.event.scale)])
   yRange.rangeBands([d3.event.translate[1] + (height * d3.event.scale), d3.event.translate[1]])

   svg.select(".x.axis").call(xAxis)
   svg.select(".y.axis").call(yAxis)

   svg.selectAll(".tile")
           .attr("width", xRange.rangeBand())
           .attr("height", yRange.rangeBand())
           .attr("x", function (d) {
               return xRange(d.x);
           })
           .attr("y", function (d) {
               return yRange(d.y);
           })

}

svg.on("mousedown", function() {
    console.log('mousedown ####');
    var e = this,
        origin = d3.mouse(e),
        rect = svg.append("rect").attr("class", "zoom");
    d3.select("body").classed("noselect", true);
    origin[0] = Math.max(0, Math.min(width, origin[0]));
    origin[1] = Math.max(0, Math.min(height, origin[1]));
    d3.select(window)
        .on("mousemove.zoomRect", function() {
          var m = d3.mouse(e);
          m[0] = Math.max(0, Math.min(width, m[0]));
          m[1] = Math.max(0, Math.min(height, m[1]));
          rect.attr("x", Math.min(origin[0], m[0]))
              .attr("y", Math.min(origin[1], m[1]))
              .attr("width", Math.abs(m[0] - origin[0]))
              .attr("height", Math.abs(m[1] - origin[1]));
        })
        .on("mouseup.zoomRect", function() {
          d3.select(window).on("mousemove.zoomRect", null).on("mouseup.zoomRect", null);
          d3.select("body").classed("noselect", false);
          var m = d3.mouse(e);
          m[0] = Math.max(0, Math.min(width, m[0]));
          m[1] = Math.max(0, Math.min(height, m[1]));
          if (m[0] !== origin[0] && m[1] !== origin[1]) {
            console.log('zoom rect');
            //here i need to trigger zoom translate/scale event, don't know how to trigger that.
          }
          rect.remove();
          refresh();
        }, true);
    d3.event.stopPropagation();
  });

Любая помощь будет высоко ценится.

Спасибо

Было бы здорово увидеть определение ваших глобальных объектов, таких как svg, и, возможно, иметь некоторый HTML, чтобы сделать функциональный пример этого.

Mark Schultheiss 31.10.2018 11:49

прекратите использовать d3v3, ​​используйте d3v5 brushXY, чтобы нарисовать прямоугольник и получить обратные вызовы, и установить масштаб соответственно в зависимости от выбранной области или просто используйте d3.zoom

rioV8 31.10.2018 12:06

вот jsfiddle jsfiddle.net/dhrubs/hzyqek1n

reactdev 31.10.2018 12:21

Ищу решение в d3v3. Что-то похожее на bl.ocks.org/jasondavies/3689931, но в порядковой шкале.

reactdev 31.10.2018 12:30
0
4
174
0

Другие вопросы по теме