使用 d3js 将图像放置在网格中
place image inside grid using d3js
我想根据使用 d3.js 的数据对象在每个网格内放置图像。
这里使用数据将每个正方形渲染成使用 d3js 库的网格。这里的问题是图像没有显示在每个网格内,但它在每个适当的网格内正确渲染。您可以在下面的图像中找到当前结果和预期结果。
这是代码:
var data = [
[{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
}, {
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"
}],
[{
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
}, {
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}]
]
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row");
var column = row
.selectAll(".square")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.style("fill", "#fff")
.style("stroke", "#222")
.attr("transform", "translate(50,50)scale(0.5)")
.append("svg:image")
.attr("xlink:href", function(d) {
return d.image;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
});
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>
图像在 rect
内渲染,但未显示。
这是当前结果:
这是预期的结果:
谁能弄清楚这里的问题是什么?感谢您的帮助。
参见 here and here - meaning you can solve your issue by setting up 4 <patterns>
in the <defs>
for your svg and then use them as fill
s for each rect
. There's a good d3 approach for that here。
工作示例:
// your OP code for data
var data = [
[
{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
},
{
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"}
],
[
{
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
},
{
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}
]
]
// your OP code for the svg
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
// NEW code to add defs with patterns containing images
// See this post:
var defs = grid.append("svg:defs");
for (let r=0; r<data.length; r++) {
for (let c=0; c<data[r].length; c++) {
let gridItem = data[r][c];
gridItem.imgId = `img_${r}_${c}`;
defs.append("svg:pattern")
.attr("id", gridItem.imgId)
.attr("width", gridItem.width)
.attr("height", gridItem.height)
.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", gridItem.image)
.attr("width", gridItem.width)
.attr("height", gridItem.height)
.attr("x", 0)
.attr("y", 0);
}
}
// your OP code for rows
var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row");
// your adjusted OP code for columns
var column = row
.selectAll(".square")
.data(function(d) {return d;})
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {return d.x;})
.attr("y", function(d) {return d.y;})
.attr("width", function(d) {return d.width;})
.attr("height", function(d) {return d.height;})
.style("fill", "#fff")
.style("stroke", "#222")
.attr("transform", "translate(50,50)scale(0.5)")
// instead of adding svg:image use the defs instead
.style("fill", function(d) {return "url(#" + d.imgId + ")";})
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>
也可以通过以下方式实现:
var data = [{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
}, {
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"
}, {
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
}, {
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}]
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
/* var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row"); */
var column = grid
.selectAll(".square")
.data(data)
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.style("fill", "#fff")
.style("stroke", "#222");
var images = grid
.selectAll("image")
.data(data)
.enter()
.append("svg:image")
.attr("xlink:href", function(d) {
return d.image;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
//remove invalid image tags
d3.selectAll("image").filter(function() {
return d3.select(this).attr("href") == null
}).remove()
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>
我想根据使用 d3.js 的数据对象在每个网格内放置图像。 这里使用数据将每个正方形渲染成使用 d3js 库的网格。这里的问题是图像没有显示在每个网格内,但它在每个适当的网格内正确渲染。您可以在下面的图像中找到当前结果和预期结果。 这是代码:
var data = [
[{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
}, {
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"
}],
[{
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
}, {
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}]
]
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row");
var column = row
.selectAll(".square")
.data(function(d) {
return d;
})
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.style("fill", "#fff")
.style("stroke", "#222")
.attr("transform", "translate(50,50)scale(0.5)")
.append("svg:image")
.attr("xlink:href", function(d) {
return d.image;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
});
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>
图像在 rect
内渲染,但未显示。
这是当前结果:
这是预期的结果:
谁能弄清楚这里的问题是什么?感谢您的帮助。
参见 here and here - meaning you can solve your issue by setting up 4 <patterns>
in the <defs>
for your svg and then use them as fill
s for each rect
. There's a good d3 approach for that here。
工作示例:
// your OP code for data
var data = [
[
{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
},
{
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"}
],
[
{
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
},
{
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}
]
]
// your OP code for the svg
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
// NEW code to add defs with patterns containing images
// See this post:
var defs = grid.append("svg:defs");
for (let r=0; r<data.length; r++) {
for (let c=0; c<data[r].length; c++) {
let gridItem = data[r][c];
gridItem.imgId = `img_${r}_${c}`;
defs.append("svg:pattern")
.attr("id", gridItem.imgId)
.attr("width", gridItem.width)
.attr("height", gridItem.height)
.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", gridItem.image)
.attr("width", gridItem.width)
.attr("height", gridItem.height)
.attr("x", 0)
.attr("y", 0);
}
}
// your OP code for rows
var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row");
// your adjusted OP code for columns
var column = row
.selectAll(".square")
.data(function(d) {return d;})
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {return d.x;})
.attr("y", function(d) {return d.y;})
.attr("width", function(d) {return d.width;})
.attr("height", function(d) {return d.height;})
.style("fill", "#fff")
.style("stroke", "#222")
.attr("transform", "translate(50,50)scale(0.5)")
// instead of adding svg:image use the defs instead
.style("fill", function(d) {return "url(#" + d.imgId + ")";})
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>
也可以通过以下方式实现:
var data = [{
"x": 1,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/wAPeTvxh_EwOisF8kMR2L2eOrIOzjfA5AjE28W5asyfGeH85glwrO6zyqL71dCC26R63chADTO7DLOjnqRoXXOAB8t2f4C3QnU6o0BA"
}, {
"x": 401,
"y": 1,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/Skyrdo9OUfXzZ-1N-jdhGbmpkx6G7r9QYfA3p6EKhb0u9ES4cZD9Z9C92BxM3A9VyLgHJHB7ALTPOlIfJxVLrpzYrLzPIUZsQX9mD4U"
}, {
"x": 1,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/0cDOOJjp8pUGDDFLqHFITEi35uMGZ5wHpZ9KTKridxk71kpR9MfeydpQqG5n8Mvetvkg5iVuZGeL2xMvxgBY_UL-T9p0x_Eo4EAh"
}, {
"x": 401,
"y": 401,
"width": 400,
"height": 400,
"image": "https://lh3.googleusercontent.com/IsGCHOz6W_CthCyx28PlKaZSzTHMY-nzZVBu0UUKTkhfD52WmJ-xvOIverssPjgBAGeSIBGwbP2qt7OJ-HpI7t-mToRc_xSFhCDv"
}]
var grid = d3
.select("#grid")
.append("svg")
.attr("width", "1350px")
.attr("height", "1350px");
/* var row = grid
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row"); */
var column = grid
.selectAll(".square")
.data(data)
.enter()
.append("rect")
.attr("class", "square")
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.style("fill", "#fff")
.style("stroke", "#222");
var images = grid
.selectAll("image")
.data(data)
.enter()
.append("svg:image")
.attr("xlink:href", function(d) {
return d.image;
})
.attr("width", function(d) {
return d.width;
})
.attr("height", function(d) {
return d.height;
})
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
});
//remove invalid image tags
d3.selectAll("image").filter(function() {
return d3.select(this).attr("href") == null
}).remove()
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="grid"></div>
<script src="stack.js" type="text/javascript"></script>
</body>
</html>