我正在使用d3最终创建一个带有时间序列域的区域图表。随着图表,我想包括一系列与日期对齐的图像。图像太宽,无法显示全宽并与x轴对齐,因此我剪裁它们。我希望剪裁在我放大时展开。我尝试使用svg图像元素,但缩放太慢了。所以现在我用帆布尝试它。但我被卡住了,因为我不知道如何重新绘制多个图像而不重新加载它们。这是我的代码:
var imageWidth = 427,
imageHeight = 240;
var imageDirectory = "data/solarImages/solarImage",
imageExtension = "jpg";
var parseDate = d3.timeParse("%Y/%m/%d %H:%M");
var canvas = d3.select('canvas');
var context = canvas.node().getContext("2d");
var width = canvas.property("width");
var height = canvas.property("height");
// svg = ...
var x =
d3.scaleTime()
.range([0, width]);
var y =
d3.scaleLinear()
.range([height, 0]);
// data
d3.csv("data/kW_test.csv", type).then(function(data) {
var dataLength = data.length,
clipWidth = width/dataLength,
sx = (imageWidth - clipWidth)/2,
zoomLimit = imageWidth/clipWidth;
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, height]);
canvas
.call(d3.zoom().scaleExtent([1, zoomLimit]).on("zoom", zoomed));
// loading and drawing the clipped images
data.forEach(function(o){
d3.image(o.image).then(function(img) {
context.drawImage(img, sx, 0, clipWidth, imageHeight, x(o.date) - clipWidth / 2, 0, clipWidth, imageHeight);
});
});
function zoomCanvas() {
var xdom = x.domain();
var zoomedDataArray = data.filter(function(d) {
return d.date >= xdom[0] && d.date <= xdom[1];
});
dataLength = zoomedDataArray.length;
context.clearRect(0, 0, width, height);
clipWidth = width/dataLength;
sx = (imageWidth - clipWidth)/2;
// how do I access the images in the zoomed domain??
context.drawImage(img, sx, 0, clipWidth, imageHeight, x(o.date) - clipWidth / 2, 0, clipWidth, imageHeight);
}
function zoomed() {
zoomCanvas();
}
});
//helper functions
function splitDateString(dateString) {
var stringArray = dateString.split(/\/|:|\s/);
stringArray[0] = stringArray[0].substring(2);
return stringArray;
}
function type(d, _, columns) {
var dateArray = splitDateString(d.date);
d.image = `${imageDirectory}${dateArray[1]}_${dateArray[2]}_${dateArray[0]}_${dateArray[3]}.${imageExtension}`;
d.date = parseDate(d.date);
for (var i = 1, n = columns.length, c; i < n; ++i) d[c = columns[i]] = +d[c];
return d;
}
答案 0 :(得分:1)
如何使用地图?
const imageCache = new Map();
...
d3.image(o.image).then(function(img) {
imageCache.set(o.image, img);
...
function zoomCanvas() {
...
zoomedDataArray.forEach(o => {
const img = imageCache.get(o.image);
context.drawImage(img, sx, 0, clipWidth, imageHeight,
...
})
...