我遵循这个D3示例:http://bl.ocks.org/mbostock/1667367。在该示例中,存在焦点和上下文。当上下文发生变化时,焦点将在上下文中显示数据。我的目标是增加另一个焦点(焦点2)。为了使其更容易,focus2(此刻)的功能与焦点(原始焦点)相同。预期的结果是:当画笔移动时,两个焦点(焦点和焦点2在代码中)将改变。这是代码:
<!DOCTYPE html>
<meta charset="utf-8">
<!--head>
<link rel="stylesheet" type= "text/css" href="angle_view.css">
</head-->
<style>
svg {
font: 10px sans-serif;
}
.area {
fill: steelblue;
clip-path: url(#clip);
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.brush .extent {
stroke: #fff;
fill-opacity: .125;
shape-rendering: crispEdges;
}
</style>
<body>
<!--script type = "text/javascript" src = "../d3/d3.min.js"> </script-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.7/d3.min.js"></script>
<p>Select a dataset from the list.</p>
<select id = "datasetSelect" onchange = "datasetSelectFunction()">
<option value="load_small_data_set">small dataset</option>
<option value="load_whole_data_set">whole dataset</option>
</select>
<!--script type = "text/javascript" src = "angle_view.js"> </script -->
<script>
// main script
var g_fn = null;
var g_pan = null;
var g_feature = null;
var g_fn_pan = null;
// init_angle_feature_view();
var margin = {top: 10, right: 30, bottom: 370, left: 40};
var margin2 = {top: 250, right: 30, bottom: 130, left: 40};
var margin3 = {top: 500, right: 30, bottom: 20, left: 40};
var width = 960 - margin.left - margin.right;
var height = 600 - margin.top - margin.bottom;
var height2 = 600 - margin2.top - margin2.bottom;
var height3 = 600 - margin3.top - margin3.bottom;
// set scales
var x = d3.scale.linear().range([0, width]);
var x2 = d3.scale.linear().range([0, width]);
var x3 = d3.scale.linear().range([0, width]);
var y = d3.scale.linear().range([height, 0]);
var y2 = d3.scale.linear().range([height2, 0]);
var y3 = d3.scale.linear().range([height3, 0]);
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var xAxis2 = d3.svg.axis().scale(x2).orient("bottom");
var xAxis3 = d3.svg.axis().scale(x3).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");
var brush = d3.svg.brush()
.x(x3) // x scale
.on("brush", brushed);
var area = d3.svg.area() // area on the top, detailed view of pan angle
.interpolate("monotone")
.x(function(d) { return x(d.frame_number); })
.y0(height)
.y1(function(d) { return y(d.pan); });
var area2 = d3.svg.area() // area in the middle, detailed view of feature
.interpolate("monotone")
.x(function(d){return x2(d.frame_number);})
.y0(height2)
.y1(function(d){return y2(d.pan); });
var area3 = d3.svg.area() // area on the bottom, global view of pan angle
.interpolate("monotone")
.x(function(d) { return x3(d.frame_number); })
.y0(height3)
.y1(function(d) { return y3(d.pan); });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath") // what is defs?, defs is not directly rendered. what is clipPath? draw only inside width x height
.attr("id", "clip") // what is clip and id do
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("class", "focus") // where does focus come from?
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var focus2 = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin3.left + "," + margin3.top + ")");
function datasetSelectFunction(){
var x = document.getElementById("datasetSelect").value;
//console.log(x);
if (x == "load_small_data_set")
{
// load frame number, pan data
d3.csv("https://dl.dropboxusercontent.com/u/54750216/javascript/sampled_fn_pan_small.csv", function(error, data) {
if (error) throw error;
// sparse data
data.forEach(function(d){
d.frame_number = parseInt(d.frame_number);
d.pan = parseFloat(d.pan);
});
g_fn_pan = data;
d3.csv("https://dl.dropboxusercontent.com/u/54750216/javascript/sampled_fn_dim_feature_small.csv", function(error, feature) {
if (error) throw error;
// Coerce the CSV data to the appropriate types.
feature.forEach(function(d) {
d.fn = parseInt(d.frame_number);
d.dim = parseInt(d.dim);
d.feature = parseFloat(d.feature);
});
g_feature = feature;
angle_feature_view(g_fn_pan, g_feature);
});
});
console.log("load_small_data_set");
// load frame number, feature data
}
else if (x == "load_whole_data_set")
{
// load frame number, pan data
d3.csv("sampled_data/sampled_fn_pan.csv", function(error, data) {
if (error) throw error;
// sparse data
data.forEach(function(d){
d.frame_number = parseInt(d.frame_number);
d.pan = parseFloat(d.pan);
});
g_fn_pan = data;
d3.csv("sampled_data/sampled_fn_dim_feature.csv", function(error, feature) {
if (error) throw error;
// Coerce the CSV data to the appropriate types.
feature.forEach(function(d) {
d.fn = parseInt(d.frame_number);
d.dim = parseInt(d.dim);
d.feature = parseFloat(d.feature);
});
g_feature = feature;
// angle_feature_view(g_fn_pan, g_feature);
});
});
console.log("load_whole_data_set");
}
}
// visualize frame number, pan angle and feature
function angle_feature_view(fn_pan, feature)
{
var fn_min = d3.min(fn_pan, function(d){return d.frame_number});
var fn_max = d3.max(fn_pan, function(d){return d.frame_number});
var pan_min = d3.min(fn_pan, function(d){return d.pan});
var pan_max = d3.max(fn_pan, function(d){return d.pan});
x.domain([fn_min, fn_max]);
y.domain([pan_min, pan_max]);
x2.domain(x.domain());
y2.domain(y.domain());
// bottom
x3.domain(x.domain());
y3.domain(y.domain());
// draw fn pan detail view
focus.append("path")
.datum(fn_pan)
.attr("class", "area")
.attr("d", area);
focus.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "y axis")
.call(yAxis);
// add focus2 in this place
focus2.append("path")
.datum(fn_pan)
.attr("class", "area")
.attr("d", area2);
focus2.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
focus2.append("g")
.attr("class", "y axis")
.call(yAxis);
// brush?
context.append("path")
.datum(fn_pan)
.attr("class", "area")
.attr("d", area3);
context.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height3 + ")")
.call(xAxis3);
context.append("g")
.attr("class", "x brush")
.call(brush)
.selectAll("rect")
.attr("y", -6)
.attr("height", height3 + 7);
}
function brushed() {
x.domain(brush.empty() ? x3.domain() : brush.extent());
focus.select(".area").attr("d", area);
focus.select(".x.axis").call(xAxis);
focus2.select(".area").attr("d", area2); // I add focus2 in this place
focus2.select(".x.axis").call(xAxis2);
console.log("call brushed");
}
</script>
</body>
&#13;
请注意焦点,焦点2和上下文相关区域。 问题是当上下文改变时,focus2视图不会改变。它总是显示整个数据集。
答案 0 :(得分:0)
你几乎拥有它,你只是忘了更新第二个比例的领域。
将x2.domain(brush.empty() ? x3.domain() : brush.extent());
添加到brushed()
函数中解决了这个问题。