Jak dodać obraz do kontenera SVG za pomocą D3.js.


Stworzyłem przykładową aplikację Asp.Net MVC 4, w której użyłem D3.js do dodania elementu SVG, a następnie wewnątrz SVG dodałem element tekstowy (patrz kod poniżej). To wszystko działa świetnie, dopóki nie spróbuję dodać obrazu do SVG za pomocą lokalnego pliku png. Img jest dodawany do DOM, ale nie jest wyświetlany na stronie. Jakieś pomysły, co tu robię źle i jak to naprawić?
@{
ViewBag.Title = "Home Page";
}<script src="~/Scripts/d3.v3.js"></script>
<script type="text/javascript">
var svg = d3.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 100)
.style("border", "1px solid black"); var text = svg.selectAll("text")
.data([0])
.enter()
.append("text")
.text("Testing")
.attr("x", "40")
.attr("y", "60"); var imgs = svg.selectAll("img").data([0]);
imgs.enter()
.append("img")
.attr("xlink:href", "@Url.Content("~/Content/images/icons/refresh.png")")
.attr("x", "60")
.attr("y", "60")
.attr("width", "20")
.attr("height", "20");</script>

@Richard Marr-Below to próba zrobienia tego samego w prostym HTML, co daje taki sam wynik. Nie mam pewności co do mojego kodu, aby w ten sposób pobrać plik refresh.png z dysku lokalnego.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script src="[url=http://d3js.org/d3.v2.js"></script>]http://d3js.org/d3.v2.js"></script>[/url] </head>
<body>
<script type="text/javascript">
var svg = d3.select("body")
.append("svg")
.attr("width", 200)
.attr("height", 100)
.style("border", "1px solid black"); var text = svg.selectAll("text")
.data([0])
.enter()
.append("text")
.text("Testing")
.attr("x", "40")
.attr("y", "60"); var imgs = svg.selectAll("img").data([0]);
imgs.enter()
.append("svg:img")
.attr("xlink:href", "file:///D:/d3js_projects/refresh.png")
.attr("x", "60")
.attr("y", "60")
.attr("width", "20")
.attr("height", "20"); </script>
</body>
</html>

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

nodeEnter.append("svg:image").attr('x', -9).attr('y', -12).attr('width', 20).attr('height', 24).attr("xlink:href", "resources/images/check.png")
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W SVG (w przeciwieństwie do HTML) lepiej będzie używać
& < image & >
zamiast
& < img & >
dla elementów.
Spróbuj zmienić swój ostatni blok za pomocą:
var imgs = svg.selectAll("image").data([0]);
imgs.enter()
.append("svg:image")
...
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mój zespół chciał również dodać obrazy wewnątrz okręgów narysowanych przez D3 i wymyślił (

fiddle
https://jsfiddle.net/duhaime/q51ok9jc/
):
index.html:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="timeline.css">
<script src="[url=https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>]https://cdnjs.cloudflare.com/a ... gt%3B[/url]
<script src="[url=https://code.jquery.com/jquery-2.2.4.js"]https://code.jquery.com/jquery-2.2.4.js"[/url]
integrity="sha256-iT6Q9iMJYuQiMWNd9lDyBUStIq/8PuOW33aOqmvFpqI="
crossorigin="anonymous"></script>
<script src="./timeline.js"></script>
</head>
<body>
<div class="timeline">
</body>
</html>

timeline.css:
.axis path,.axis line,.tick line,.line {
fill: none;
stroke: #000000;
stroke-width: 1px;
}

timeline.js:
// container target
var elem = ".timeline";var props = {
width: 1000,
height: 600,
class: "timeline-point",// margins
marginTop: 100,
marginRight: 40,
marginBottom: 100,
marginLeft: 60,// data inputs
data: [
{
x: 10,
y: 20,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "a"
},
{
x: 20,
y: 10,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "b"
},
{
x: 60,
y: 30,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "c"
},
{
x: 40,
y: 30,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "d"
},
{
x: 50,
y: 70,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "e"
},
{
x: 30,
y: 50,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "f"
},
{
x: 50,
y: 60,
key: "a",
image: "[url=https://unsplash.it/300/300"]https://unsplash.it/300/300"[/url],
id: "g"
}
],// y label
yLabel: "Y label",
yLabelLength: 50,// axis ticks
xTicks: 10,
yTicks: 10}// component start
var Timeline = {};/***
*
* Create the svg canvas on which the chart will be rendered
*
***/Timeline.create = function(elem, props) {// build the chart foundation
var svg = d3.select(elem).append('svg')
.attr('width', props.width)
.attr('height', props.height); var g = svg.append('g')
.attr('class', 'point-container')
.attr("transform",
"translate(" + props.marginLeft + "," + props.marginTop + ")"); var g = svg.append('g')
.attr('class', 'line-container')
.attr("transform",
"translate(" + props.marginLeft + "," + props.marginTop + ")"); var xAxis = g.append('g')
.attr("class", "x axis")
.attr("transform", "translate(0," + (props.height - props.marginTop - props.marginBottom) + ")"); var yAxis = g.append('g')
.attr("class", "y axis"); svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.attr("y", 1)
.attr("x", 0 - ((props.height - props.yLabelLength)/2) )
.attr("dy", ".75em")
.attr("transform", "rotate(-90)")
.text(props.yLabel);// add placeholders for the axes
this.update(elem, props);
};/***
*
* Update the svg scales and lines given new data
*
***/Timeline.update = function(elem, props) {
var self = this;
var domain = self.getDomain(props);
var scales = self.scales(elem, props, domain); self.drawPoints(elem, props, scales);
};
/***
*
* Use the range of values in the x,y attributes
* of the incoming data to identify the plot domain
*
***/Timeline.getDomain = function(props) {
var domain = {};
domain.x = props.xDomain || d3.extent(props.data, function(d) { return d.x; });
domain.y = props.yDomain || d3.extent(props.data, function(d) { return d.y; });
return domain;
};
/***
*
* Compute the chart scales
*
***/Timeline.scales = function(elem, props, domain) { if (!domain) {
return null;
} var width = props.width - props.marginRight - props.marginLeft;
var height = props.height - props.marginTop - props.marginBottom; var x = d3.scale.linear()
.range([0, width])
.domain(domain.x); var y = d3.scale.linear()
.range([height, 0])
.domain(domain.y); return {x: x, y: y};
};
/***
*
* Create the chart axes
*
***/Timeline.axes = function(props, scales) { var xAxis = d3.svg.axis()
.scale(scales.x)
.orient("bottom")
.ticks(props.xTicks)
.tickFormat(d3.format("d")); var yAxis = d3.svg.axis()
.scale(scales.y)
.orient("left")
.ticks(props.yTicks); return {
xAxis: xAxis,
yAxis: yAxis
}
};
/***
*
* Use the general update pattern to draw the points
*
***/Timeline.drawPoints = function(elem, props, scales, prevScales, dispatcher) {
var g = d3.select(elem).selectAll('.point-container');
var color = d3.scale.category10();// add images
var image = g.selectAll('.image')
.data(props.data) image.enter()
.append("pattern")
.attr("id", function(d) {return d.id})
.attr("class", "svg-image")
.attr("x", "0")
.attr("y", "0")
.attr("height", "70px")
.attr("width", "70px")
.append("image")
.attr("x", "0")
.attr("y", "0")
.attr("height", "70px")
.attr("width", "70px")
.attr("xlink:href", function(d) {return d.image}) var point = g.selectAll('.point')
.data(props.data);// enter
point.enter()
.append("circle")
.attr("class", "point")
.on('mouseover', function(d) {
d3.select(elem).selectAll(".point").classed("active", false);
d3.select(this).classed("active", true);
if (props.onMouseover) {
props.onMouseover(d)
};
})
.on('mouseout', function(d) {
if (props.onMouseout) {
props.onMouseout(d)
};
})// enter and update
point.transition()
.duration(1000)
.attr("cx", function(d) {
return scales.x(d.x);
})
.attr("cy", function(d) {
return scales.y(d.y);
})
.attr("r", 30)
.style("stroke", function(d) {
if (props.pointStroke) {
return d.color = props.pointStroke;
} else {
return d.color = color(d.key);
}
})
.style("fill", function(d) {
if (d.image) {
return ("url(#" + d.id + ")");
} if (props.pointFill) {
return d.color = props.pointFill;
} else {
return d.color = color(d.key);
}
});// exit
point.exit()
.remove();// update the axes
var axes = this.axes(props, scales);
d3.select(elem).selectAll('g.x.axis')
.transition()
.duration(1000)
.call(axes.xAxis); d3.select(elem).selectAll('g.y.axis')
.transition()
.duration(1000)
.call(axes.yAxis);
};
$(document).ready(function() {
Timeline.create(elem, props);
})
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie wiem dlaczego, ale obraz nie powinien być powielany, potrajany, itp ... powinien usunąć poprzedni i załadować go ponownie, ale z innymi danymi dotyczącymi rotacji. To jest mój kod.:
data.csv

wprowadź opis obrazu tutaj
https://i.stack.imgur.com/15vb8.png
d3.csv("data/data.csv").then(function(data){
//console.log(data);
// Clean data
formattedData = data.map(function(id){
id.rot_1 = +id.rot_1;
id.trans_1 = +id.trans_1;
return id;
});
// First run of the visualization
update(formattedData[0]);})$("#play-button").on("click", function(){
var button = $(this);
if (button.text() == "Play"){
button.text("Pause");
interval = setInterval(step, 1000);
}
else {
button.text("Play");
clearInterval(interval);
}})function step(){
// At the end of our data, loop back
time = (time < 76) ? time+1 : 0
update(formattedData[time]); }function update(data) {
// Standard transition time for the visualization
var t = d3.transition()
.duration(1000);//console.log(d3.selectAll(data));
//console.log(data)// original
var imgs1 = g.append("image")// en vez de g es svg.attr("xlink:href", "img/picturetest.png");// EXIT old elements not present in new data.
imgs1.exit()
.attr("class", "exit")
.selectAll("svg:image")
.remove();//console.log(data)// ENTER new elements present in new data.
imgs1.enter()
.append("svg:image")// svg:image
//.attr("xlink:href", "img/picturetest.png")
.attr("class", "enter")
.merge(imgs1)
.transition(t)
.attr("x", 0)// 150
.attr("y", 0)// 80
.attr("width", 200)
.attr("height", 200)
.attr("transform", "rotate("+data.rot_1+") translate("+data.trans_1+")" ); }`
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

var svg = d3.select("body")
.append("svg")
.style("width", 200)
.style("height", 100)

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się