#javascript #html #d3.js #visualization
#javascript #HTML #d3.js #визуализация
Вопрос:
Я пытаюсь добавить изображение в d3.js элемент svg по частям, чтобы составить сетку размером 12×12. У меня есть сетка 12×12, но я могу только понять, как загрузить все изображение в каждый раздел сетки, а не добавлять изображение по частям, чтобы создать одно плиточное изображение в конце. Любые мысли о том, как это можно решить, будут оценены, спасибо.
Примечание: данные в файле csv — это просто координаты, которые составляют сетку 12×12.
var data = d3.range(36).map(function(i) {
return {
x_coordinate: (i % 6) * 12,
y_coordinate: Math.floor(i / 6) * 12,
};
});
// set the dimensions and margins of the graph
var margin = {
top: 1,
bottom: 15,
left: 0,
right: 0
},
width = 350,
height = 350;
// append the svg object to the body of the page
var svg = d3.select("#tile_photo")
.append("svg")
.attr("width", width margin.left)
.attr("height", height margin.top margin.bottom)
.append("g")
.attr("transform",
"translate(" margin.left "," margin.top ")");
// Labels of row and columns -> unique identifier of the column called 'xCoordinate' and 'yCoordinate'
var xCoordinate = d3.map(data, function(d) {
return d.x_coordinate;
}).keys(),
yCoordinate = d3.map(data, function(d) {
return d.y_coordinate;
}).keys();
// Build X and Y scales and axis:
var x = d3.scaleBand()
.range([0, width])
.domain(xCoordinate)
.padding(0.025),
y = d3.scaleBand()
.range([0, height])
.domain(yCoordinate)
.padding(0.025);
// adding the 12x12 rects that will make up the tile photo
var tileImage = svg.selectAll()
.data(data, function(d) {
return d.x_coordinate ':' d.y_coordinate;
})
.enter();
tileImage.append("svg:image")
.attr("x", function(d) {
return x(d.x_coordinate)
})
.attr("y", function(d) {
return y(d.y_coordinate)
})
.attr("rx", 0)
.attr("ry", 0)
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.attr("xlink:href", "https://via.placeholder.com/72");
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- Create a div where the graph will take place -->
<div id="tile_photo" align="center"></div>
Ответ №1:
Если вас интересует только визуальная часть, вы можете сделать это, добавив изображение только один раз и используя clipPath
. Это создает фильтр, который накладывается на изображение и позволяет отображать только пиксели в определенных местах.
Я не уверен, позволит ли это вам обнаруживать клики по отдельным плиткам. Если вы этого хотите, я действительно рекомендую использовать сервер для нарезки и подачи изображения в виде плиток для вас.
var data = d3.range(36).map(function(i) {
return {
x_coordinate: (i % 6) * 12,
y_coordinate: Math.floor(i / 6) * 12,
};
});
// set the dimensions and margins of the graph
var margin = {
top: 1,
bottom: 15,
left: 0,
right: 0
},
width = 350,
height = 350;
// append the svg object to the body of the page
var svg = d3.select("#tile_photo")
.append("svg")
.attr("width", width margin.left)
.attr("height", height margin.top margin.bottom)
.append("g")
.attr("transform",
"translate(" margin.left "," margin.top ")");
// Labels of row and columns -> unique identifier of the column called 'xCoordinate' and 'yCoordinate'
var xCoordinate = d3.map(data, function(d) {
return d.x_coordinate;
}).keys(),
yCoordinate = d3.map(data, function(d) {
return d.y_coordinate;
}).keys();
// Build X and Y scales and axis:
var x = d3.scaleBand()
.range([0, width])
.domain(xCoordinate)
.padding(0.025),
y = d3.scaleBand()
.range([0, height])
.domain(yCoordinate)
.padding(0.025);
var clipPath = svg
.append("clipPath")
.attr("id", "crop")
.selectAll("rect")
.data(data, function(d) {
return d.x_coordinate ':' d.y_coordinate;
})
.enter()
.append("svg:rect")
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.attr("x", function(d) {
return x(d.x_coordinate)
})
.attr("y", function(d) {
return y(d.y_coordinate)
});
var tileImage = svg.append("svg:image")
.attr("width", width)
.attr("height", height)
.attr("clip-path", "url(#crop)")
.attr("xlink:href", "https://via.placeholder.com/72");
<script src="https://d3js.org/d3.v4.min.js"></script>
<!-- Create a div where the graph will take place -->
<div id="tile_photo" align="center"></div>