如何将 JQuery 滑块与每个数据点的 d3 垂直线交互
How to interact JQuery slider with d3 vertical lines for every data point
我正在尝试创建一个交互式滑块,使用来自每个所选数据点的垂直线缩放和过滤数据范围。我不确定如何在每个数据点上绘制每条垂直线,以便滑块可以缩放和过滤此数据范围内的垂直线。目前,我可以在每个数据点和一条垂直线上绘制圆圈(参见附加的输出图),但我想在这些圆圈顶部绘制垂直线,或者如果 d3 有某种方法可以只为每个数据点绘制垂直线。我是 d3 的新手,非常感谢您的反馈!以下是我到目前为止从其他有用网站学到的东西。
/* 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>
输出
要添加线条,只需再重复一次您对圆圈所做的操作。
/* 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>
我正在尝试创建一个交互式滑块,使用来自每个所选数据点的垂直线缩放和过滤数据范围。我不确定如何在每个数据点上绘制每条垂直线,以便滑块可以缩放和过滤此数据范围内的垂直线。目前,我可以在每个数据点和一条垂直线上绘制圆圈(参见附加的输出图),但我想在这些圆圈顶部绘制垂直线,或者如果 d3 有某种方法可以只为每个数据点绘制垂直线。我是 d3 的新手,非常感谢您的反馈!以下是我到目前为止从其他有用网站学到的东西。
/* 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>
输出
要添加线条,只需再重复一次您对圆圈所做的操作。
/* 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>