JQuery 滑块不与 d3 在垂直线上绘制的数据交互

JQuery slider doesn't interact with data drawn in vertical line with d3

我正在尝试让我的数据与 jQuery 滑块交互。我的数据用钢蓝色的垂直线表示,但 jQuery 滑块仅与浅灰色垂直线 xAxis 交互,因为我使用 xAxis x.axis 及其路径设置它。它只随滑块移动,而不是钢蓝中的实际垂直线。我不能使用 d3 滑块,我被这个 d3 v2 困住了。我问了一个关于垂直线的问题:(),但建议对这个滑块问题问一个单独的问题:(任何输入都会有帮助!这是代码:

// define dimensions of graph
var m = [80, 80, 80, 80]; // margins
var w = 1000 - m[1] - m[3]; // width
var h = 350 - m[0] - m[2]; // height

// create a simple data array that we'll plot with a line (this array represents only the Y values, X will just be the index location)
var data = [0];
for (var i = 1; i < 50; i++) {
  var sign = Math.random() > 0.5 ? +1 : -1;
  data.push(data[i - 1] + sign * Math.random());
}

// X scale will fit all values from data[] within pixels 0-w
var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
// Y scale will fit values from 0-10 within pixels h-0 (Note the inverted domain for the y-scale: bigger is up!)
var y = d3.scale.linear().domain([d3.min(data), d3.max(data)]).range([h, 0]);

// Add an SVG element with the desired dimensions and margin.
var graph = d3.select("#graph").append("svg:svg")
  .attr("width", w + m[1] + m[3])
  .attr("height", h + m[0] + m[2])
  .append("svg:g")
  .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

// create yAxis
var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(3);
// Add the x-axis.
graph.append("svg:g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + h + ")")
  .call(xAxis);

// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
  .attr("class", "y axis")
  .attr("transform", "translate(-25,0)")
  .call(yAxisLeft);

var circle = graph.selectAll("circle")
  .data(data);

circle.enter()
  .append("circle")
  .attr("cx", function(d, i) {
    return x(i)
  })
  .attr("cy", function(d) {
    return y(d)
  })
  .attr("class", "circle")
  .attr("r", 2)
  .attr("fill", "red");

var verticalLine = graph.selectAll(".vertical-line")
  .data(data);

verticalLine.enter()
  .append("line")
  .attr("x1", function(d, i) {
    return x(i)
  })
  .attr("x2", function(d, i) {
    return x(i)
  })
  .attr({
    y1: 0,
    y2: h,
    stroke: 'steelblue',
    class: 'vertical-line'
  });

function zoom(begin, end) {
  x.domain([begin, end - 1]);

  var t = graph.transition().duration(0);

  var size = end - begin;
  var step = size / 10;
  var ticks = [];
  for (var i = 0; i <= 10; i++) {
    ticks.push(Math.floor(begin + step * i));
  }

  xAxis.tickValues(ticks);

  t.select(".x.axis").call(xAxis);
  t.select('.path').attr("d", verticalLine);
}

$(function() {
  $("#slider-range").slider({
    range: true,
    min: 0,
    max: 1000,
    values: [0, 1000],
    slide: function(event, ui) {
      var begin = d3.min([ui.values[0], data.length]);
      var end = d3.max([ui.values[1], 0]);
      console.log("begin:", begin, "end:", end);

      zoom(begin, end);
    }
  });
});
path {
  stroke: steelblue;
  stroke-width: 1;
  fill: none;
}

.axis {
  shape-rendering: crispEdges;
}

.x.axis line {
  stroke: lightgrey;
}

.x.axis .minor {
  stroke-opacity: .5;
}

.x.axis path {
  display: none;
}

.y.axis line,
.y.axis path {
  fill: none;
  stroke: #000;
}
<script src="https://mbostock.github.com/d3/d3.v2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css" type="text/css" media="all" />
<div id="graph" class="aGraph"></div>
<div id="slider-range" style="width: 80%px; margin-left:10%; margin-right:10%"></div>

我建议使用 d3-brush,因为它本质上是您想要的,但由 d3 团队为 d3 构建。

但是,如果您不能,我已经在下面使用您的 jQuery 滑块使其工作。您正在摆弄轴刻度,但我建议您重新绘制轴并让 d3 为您完成。每次更新 x.domain(),然后调用 draw() 函数重绘垂直线和圆圈`并重绘 x-axis。我已将域外的所有线条和圆圈的不透明度设置为 0,因此它们被隐藏了。

var m = [40, 80, 40, 80]; // margins
var w = 1000 - m[1] - m[3]; // width
var h = 300 - m[0] - m[2]; // height

var data = [0];
for (var i = 1; i < 50; i++) {
  var sign = Math.random() > 0.5 ? +1 : -1;
  data.push(data[i - 1] + sign * Math.random());
}

var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
var y = d3.scale.linear().domain([d3.min(data), d3.max(data)]).range([h, 0]);

var graph = d3.select("#graph").append("svg:svg")
  .attr("width", w + m[1] + m[3])
  .attr("height", h + m[0] + m[2])
  .append("svg:g")
  .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(3);
var xAxisGroup = graph.append("svg:g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + h + ")");

var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");
graph.append("svg:g")
  .attr("class", "y axis")
  .attr("transform", "translate(-25,0)")
  .call(yAxisLeft);

function draw() {
  var circle = graph.selectAll("circle")
    .data(data);

  circle.exit().remove();
  circle.enter()
    .append("circle");

  circle
    .attr("cx", function(d, i) {
      return x(i)
    })
    .attr("cy", function(d) {
      return y(d)
    })
    .attr("opacity", function(d, i) {
      return x.domain()[0] <= i && i <= x.domain()[1] ? 1 : 0;
    })
    .attr("class", "circle")
    .attr("r", 2)
    .attr("fill", "red");

  var verticalLine = graph.selectAll(".vertical-line")
    .data(data);

  verticalLine.exit().remove();
  verticalLine.enter()
    .append("line");

  verticalLine
    .attr("x1", function(d, i) {
      return x(i)
    })
    .attr("x2", function(d, i) {
      return x(i)
    })
    .attr("opacity", function(d, i) {
      return x.domain()[0] <= i && i <= x.domain()[1] ? 1 : 0;
    })
    .attr({
      y1: 0,
      y2: h,
      stroke: 'steelblue',
      class: 'vertical-line'
    });

  xAxisGroup.call(xAxis);
}

draw();

function zoom(begin, end) {
  x.domain([begin, end]);
  draw();
}

$(function() {
  $("#slider-range").slider({
    range: true,
    min: 0,
    max: data.length,
    values: [0, data.length],
    slide: function(event, ui) {
      var begin = d3.min([ui.values[0], data.length]);
      var end = d3.max([ui.values[1], 0]);
      zoom(begin, end);
    }
  });
});
path {
  stroke: steelblue;
  stroke-width: 1;
  fill: none;
}

.axis {
  shape-rendering: crispEdges;
}

.x.axis line {
  stroke: lightgrey;
}

.x.axis .minor {
  stroke-opacity: .5;
}

.x.axis path {
  display: none;
}

.y.axis line,
.y.axis path {
  fill: none;
  stroke: #000;
}
<script src="https://mbostock.github.com/d3/d3.v2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/ui-lightness/jquery-ui.css" type="text/css" media="all" />
<div id="graph" class="aGraph"></div>
<div id="slider-range" style="width: 80%px; margin-left:10%; margin-right:10%"></div>