问题描述
我刚刚开始学习 D3 和 JavaScript。我正在尝试制作一个可缩放的流图,并且可以选择为用户指示特定的数据值。 所以我开始首先选择和显示数据点的注释,效果很好。然后我学会了如何缩放流图。但是当把它们放在一起时,我发现选择/注释功能不再起作用了。有人有什么建议吗?
这里有两张图片,一张显示 zoom function,另一张显示 annotation function。
非常感谢!
(function () {
// first,load the dataset from a CSV file
d3.csv("https://raw.githubusercontent.com/FeisNowflakes/zoomtest222/main/streamgraph-test/Los_Angeles_International_Airport_-_Passenger_Traffic_By_Terminal.csv")
.then(data => {
// log csv in browser console
console.log(data);
var advanceVisData = {};
var airport = new Set();
data.forEach(d => {
airport.add(d['Terminal']);
var period = new Date(d['ReportPeriod']);
if (period in advanceVisData) {
if (d['Terminal'] in advanceVisData[period]) {
advanceVisData[period][d['Terminal']] += Number(d['Passenger_Count']);
}
else {
advanceVisData[period][d['Terminal']] = Number(d['Passenger_Count']);
}
}
else {
advanceVisData[period] = {};
advanceVisData[period][d['Terminal']] = Number(d['Passenger_Count']);
}
});
console.log(airport);
console.log(advanceVisData);
// reformat the advanceVisData for d3.stack()
var formattedData = [];
Object.keys(advanceVisData).forEach(d => {
var item = {};
item['year'] = d;
airport.forEach(terminal => {
if (terminal in advanceVisData[d]) {
item[terminal] = advanceVisData[d][terminal];
} else {
item[terminal] = 0;
}
});
formattedData.push(item);
});
console.log(formattedData);
/*********************************
* Visualization codes start here
* ********************************/
var width = 1000;
var height = 300;
var margin = { left: 60,right: 20,top: 20,bottom: 60 };
//set the dimensions and margins of the graph
// append the svg object to the body of the page
var svg = d3.select('#container')
.append("svg")
.attr("width",width + margin.left + margin.right)
.attr("height",height + margin.top + margin.bottom)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
// List of groups = header of the csv files
var keys = Array.from(airport);
//stack the data?
var stackedData = d3.stack()
//.offset(d3.stackOffsetSilhouette)
.keys(keys)
(formattedData);
console.log(stackedData);
var max_val = 0;
var min_val = 0;
stackedData.forEach(terminal => {
terminal.forEach(year => {
if (year[0] < min_val) min_val = year[0];
if (year[1] < min_val) min_val = year[1];
if (year[0] > max_val) max_val = year[0];
if (year[1] > max_val) max_val = year[1];
})
});
//console.log(max_val,min_val);
// Add X axis
var x = d3.scaleTime()
.domain(d3.extent(formattedData,function (d) {
return new Date(d.year);
}))
.range([0,width]);
var xAxis = svg.append("g")
.attr("transform","translate(0," + height + ")")
.call(d3.axisBottom(x).ticks(20));
// Add Y axis
var y = d3.scaleLinear()
.domain([min_val,max_val])
.range([height,0]);
var yAxis = svg.append("g")
.call(d3.axisLeft(y));
// color palette
var color = d3.scaleOrdinal()
.domain(keys)
.range(['#e41a1c','#377eb8','#4daf4a','#984ea3','#ff7f00','#f781bf',"#87sbf","#ff981bf","#d6a3b6",'#b3afb0','#ddd8c2']);
// create a tooltip
var Tooltip = svg
.append("text")
.attr("x",0)
.attr("y",0)
.style("opacity",0)
.style("font-size",17)
//Add a clipPath: everything out of this area won't be drawn.
var clip = svg.append("defs").append("svg:clipPath")
.attr("id","clip")
.append("svg:rect")
.attr("width",width)
.attr("height",height)
.attr("x",0);
const itemmouSEOver = (selectedTerminal) => {
d3.selectAll(".myStreamArea").style("opacity",.3);
d3.selectAll(".myStreamArea")
.each(function (d) {
if (d.key === selectedTerminal) {
d3.select(this)
.style("stroke","black")
.style("opacity",1);
}
});
};
const itemmouseLeave = () => {
d3.selectAll(".myStreamArea")
.style("opacity",1)
};
// Show the areas
var stream = svg.append("g")
.attr("clip-path","url(#clip)")
stream
.selectAll(".myStreamArea")
.data(stackedData)
.enter()
.append("path")
.attr("class","myStreamArea")
.style("fill",function (d) {
return color(d.key);
})
.style("opacity",1)
.attr("d",d3.area()
.x(function (d) {
return x(new Date(d.data.year));
})
.y0(function (d) {
return y(d[0]);
})
.y1(function (d) {
return y(d[1]);
})
)
.on("mouSEOver",function (d,i) {
itemmouSEOver(i.key);
})
.on("mousemove",i) {
var selectedDate = x.invert(d3.pointer(event,this)[0]);
var displayVal = null;
i.forEach(k => {
var tmpDate = new Date(k.data.year);
if (tmpDate.getFullYear() === selectedDate.getFullYear()
&& tmpDate.getMonth() === selectedDate.getMonth()) {
displayVal = (k.data)[i.key];
}
});
console.log(displayVal);
d3.select('#mouse_move_text')
.remove();
svg.append("text")
.attr("id","mouse_move_text")
.attr("x",width / 2)
.attr("y",0)
.style("font-size","12px")
.attr("font-weight","bold")
.text("passenger count:" + displayVal)
;
})
.on("mouseleave",i) {
d3.select('#mouse_over_text')
.remove();
itemmouseLeave();
});
// Set the zoom and Pan features: how much you can zoom,on which part,and what to do when there is a zoom
var zoom = d3.zoom()
.scaleExtent([1,9]) // This control how much you can unzoom (x0.5) and zoom (x20)
.extent([[0,0],[width,height]])
.on("zoom",updateChart);
// This add an invisible rect on top of the chart area. This rect can recover pointer events: necessary to understand when the user zoom
svg.append("rect")
.attr("width",height)
.style("fill","none")
.style("pointer-events","all")
.call(zoom);
// Now the user can zoom and it will trigger the function called updateChart
// A function that updates the chart when the user zoom and thus new boundaries are available
function updateChart() {
// recover the new scale
var transform = d3.zoomTransform(this);
var newX = transform.rescaleX(x);
// update axes with these new boundaries
xAxis.call(d3.axisBottom(newX)); //.ticks(20)
stream
.selectAll(".myStreamArea")
.attr("d",d3.area()
.x(function (d) {
return newX(new Date(d.data.year));
})
.y0(function (d) {
return y(d[0]);
})
.y1(function (d) {
return y(d[1]);
}));
//);
}
})
})();
<!DOCTYPE html>
<html lang="en">
<head>
<Meta charset="utf-8">
<script src="https://d3js.org/d3.v6.min.js"></script>
<style>
#tooltip {
min-width: 100px;
min-height: 50px;
background-color: white;
}
</style>
</head>
<body>
<div id="container"> <div id="tooltip"></div></div>
<script src="selectzoom.js"></script>
<!-- <script src="select.js"></script> -->
</body>
</html>
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)