问题描述
我正在尝试创建一个交互式滑块,并使用从选定的每个数据点开始的垂直线将数据缩放到一个数据范围.我不确定如何在每个数据点上绘制每条垂直线,以便滑块可以缩放和过滤此数据范围上的垂直线.目前,我可以在每个数据点和一条垂直线上绘制圆(请参见随附的输出图),但是如果d3有某种方法可以在每个圆上绘制垂直线,或者仅在每个数据点上绘制垂直线.我是d3的新手,感谢您的反馈!到目前为止,这是我从其他有用的站点中学到的东西.
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>
输出
推荐答案
要添加线条,只需再重复一次对圆圈的操作即可.
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>
这篇关于如何将JQuery滑块与每个数据点的d3垂直线进行交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!