Селектор скользящего значения с D3 - PullRequest
1 голос
/ 17 июня 2020

enter image description here

Как я могу создать скользящий селектор значений, как указано выше, с помощью d3. Мне не нужно точное решение, но если кто-то может указать мне правильное направление. Я новичок в d3 и знаю только основы, такие как рисование линии, прямоугольников, кругов и т. Д. c.

В приведенном выше pi c круг можно перетаскивать слева направо, а обновления от 0 до 100 .

Подойдет любое решение, отличное от d3.

1 Ответ

3 голосов
/ 22 июня 2020

Думаю, плагин d3-fishey сделает то, что вам нужно:

https://github.com/d3/d3-plugins/tree/master/fisheye

Здесь вы можете найти пример, в котором область рыбьего глаза помещается внутри круг, который может быть ручкой вашего слайдера:

http://bl.ocks.org/fernoftheandes/8637581

Начальная точка может быть в следующих фрагментах:

(function () {
  d3.fisheye = {
    scale: function (scaleType) {
      return d3_fisheye_scale(scaleType(), 3, 0);
    },
    circular: function () {
      var radius = 200,
        distortion = 2,
        k0,
        k1,
        focus = [0, 0];

      function fisheye(d) {
        var dx = d.x - focus[0],
          dy = d.y - focus[1],
          dd = Math.sqrt(dx * dx + dy * dy);
        if (!dd || dd >= radius) return { x: d.x, y: d.y, z: 1 };
        var k = ((k0 * (1 - Math.exp(-dd * k1))) / dd) * 0.75 + 0.25;
        return {
          x: focus[0] + dx * k,
          y: focus[1] + dy * k,
          z: Math.min(k, 10)
        };
      }

      function rescale() {
        k0 = Math.exp(distortion);
        k0 = (k0 / (k0 - 1)) * radius;
        k1 = distortion / radius;
        return fisheye;
      }

      fisheye.radius = function (_) {
        if (!arguments.length) return radius;
        radius = +_;
        return rescale();
      };

      fisheye.distortion = function (_) {
        if (!arguments.length) return distortion;
        distortion = +_;
        return rescale();
      };

      fisheye.focus = function (_) {
        if (!arguments.length) return focus;
        focus = _;
        return fisheye;
      };

      return rescale();
    }
  };

  function d3_fisheye_scale(scale, d, a) {
    function fisheye(_) {
      var x = scale(_),
        left = x < a,
        range = d3.extent(scale.range()),
        min = range[0],
        max = range[1],
        m = left ? a - min : max - a;
      if (m == 0) m = max - min;
      return ((left ? -1 : 1) * m * (d + 1)) / (d + m / Math.abs(x - a)) + a;
    }

    fisheye.distortion = function (_) {
      if (!arguments.length) return d;
      d = +_;
      return fisheye;
    };

    fisheye.focus = function (_) {
      if (!arguments.length) return a;
      a = +_;
      return fisheye;
    };

    fisheye.copy = function () {
      return d3_fisheye_scale(scale.copy(), d, a);
    };

    fisheye.nice = scale.nice;
    fisheye.ticks = scale.ticks;
    fisheye.tickFormat = scale.tickFormat;
    return d3.rebind(fisheye, scale, "domain", "range");
  }
})();

let svg = d3.select("svg");
let g = svg.append("g");
let circle = g
  .append("circle")
  .attr("cx", 20)
  .attr("cy", 70)
  .attr("r", 10)
  .attr("fill", "transparent")
  .attr("stroke", "black")
  .attr("mousedown", false);

circle.on("mousedown", function () {
  d3.select(this).attr("mousedown", true);
});
circle.on("mouseup", function () {
  d3.select(this).attr("mousedown", false);
});
circle.on("mousemove", function () {
  let self = d3.select(this);
  if (self.attr("mousedown")=="true") {
    let coordinates = d3.mouse(this);
    let x = coordinates[0];
    let y = coordinates[1];
    d3.select(this).attr("cx", x);
  }
});

let points = [[{x:20, y:50},{x:30, y:50}],[{x:30, y:50},{x:50, y:50}],[{x:50, y:50},{x:70, y:50}], [{x:70, y:50},{x:90,y:50}],[{x:90, y:50},{x:110,y:50}],[{x:110, y:50},{x:130,y:50}],[{x:130, y:50},{x:150,y:50}],[{x:150, y:50},{x:170,y:50}],[{x:170, y:50},{x:200,y:50}]];
let line = g.selectAll('.line')
.data(points)
.enter()
.append('line')
  .attr('x1', d=>d[0].x)
  .attr('x2', d=>d[1].x)
  .attr('y1', d=>d[0].y)
  .attr('y2', d=>d[1].y)
  .attr("stroke", "black")
.attr("class", "line");

let fisheye = d3.fisheye.circular()
                .radius(30)
                .distortion(50);

circle.attr('r',fisheye.radius());

g.on('mousemove', function(){
  fisheye.focus(d3.mouse(this));
  let r = fisheye.radius();
  line      
      .attr("x1", function(d) { return fisheye(d[0]).x; })
      .attr("y1", function(d) { return fisheye(d[0]).y; })
      .attr("x2", function(d) { return fisheye(d[1]).x; })
      .attr("y2", function(d) { return fisheye(d[1]).y; });
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js"></script>
<svg heigth='200' width='200'>
</svg>

вы можете найти редактируемую версию здесь, в моем коде: https://codepen.io/lbrutti/pen/mdVmmpw

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...