How to interact JQuery slider with d3 vertical lines for every data point

梦想的初衷 提交于 2020-12-13 03:20:25

问题


I am trying to create an interactive slider zooming and filtering into a data range using vertical line from each data point selected. I am not sure how to draw every vertical lines on each data point so the slider can zoom and filter vertical lines on this data range. Currently, I can draw circles on every data point and one vertical line (see attached output graph), but would like to draw vertical lines on top of those circles or just for each data point if d3 has some way to do it. I am new to d3 and I will appreciate your feedback! Here is what I have so far learning from other useful sites.

/* implementation heavily influenced by http://bl.ocks.org/1166403 */

// 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 < 1000; 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 clip = graph.append("defs").append("svg:clipPath")
  .attr("id", "clip")
  .append("svg:rect")
  .attr("id", "clip-rect")
  .attr("x", "0")
  .attr("y", "0")
  .attr("width", w)
  .attr("height", h);


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.append('line')
  .attr({
    'x1': 0,
    'y1': 0,
    'x2': 0,
    'y2': h
  })
  .attr("stroke", "steelblue")
  .attr('class', 'verticalLine');

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(data));
}

$(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);
    }
  });
});
/* tell the SVG path to be a thin blue line without any area fill */

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>

Output graph


回答1:


To add the lines, just repeat what you did with the circles one more time.

/* implementation heavily influenced by http://bl.ocks.org/1166403 */

// 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 clip = graph.append("defs").append("svg:clipPath")
  .attr("id", "clip")
  .append("svg:rect")
  .attr("id", "clip-rect")
  .attr("x", "0")
  .attr("y", "0")
  .attr("width", w)
  .attr("height", h);


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(data));
}

$(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);
    }
  });
});
/* tell the SVG path to be a thin blue line without any area fill */

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>


来源:https://stackoverflow.com/questions/64347150/how-to-interact-jquery-slider-with-d3-vertical-lines-for-every-data-point

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!