score:1
Accepted answer
i've used your code to assemble a small example, which you can see below.
- inside
svg > defs
, create onepattern
per node and use thatpattern
(with the id of the company) to fetch the logo of that company; - reference the
pattern
for the node using the information you already have.
some pointers on your code:
- you already use es6 logic, so you can also use
array.prototype.map
and other functions. they're generally much more readable (and natively implemented!) thand3.map
; - there is no need to keep so many arrays of values, generally having fewer sources of truth for your data will make the code simpler to maintain and update in the future;
- use clear variable names! ls and lt are logical when you know the context, but when you revisit this code in 6 months you might not instantly know what you were talking about when you wrote it.
const nodes = [{
id: "amazon",
image: "https://images-eu.ssl-images-amazon.com/images/g/02/gc/designs/livepreview/a_generic_10_uk_noto_email_v2016_uk-main._cb485921599_.png"
},
{
id: "aurora",
image: "https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/oeagjbu7wau6o16zdhb1"
},
{
id: "zoox",
image: "https://res-4.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/kpc7mmk886nbbipbeqau"
}
];
const links = [{
src: 'amazon',
target: 'aurora'
},
{
src: 'amazon',
target: 'zoox'
},
{
src: 'aurora',
target: 'zoox'
}
];
const width = 500,
height = 500;
function forcegraph({
nodes, // an iterable of node objects (typically [{id}, …])
links // an iterable of link objects (typically [{src, target}, …])
}, {
nodeid = d => d.id, // given d in nodes, returns a unique identifier (string)
nodetitle, // given d in nodes, a title string
nodestroke = "teal", // node stroke color
nodestrokewidth = 2, // node stroke width, in pixels
nodestrokeopacity = 1, // node stroke opacity
noderadius = 20, // node radius, in pixels
nodestrength = -750,
linkdistance = 100,
linkstrokeopacity = 0.6, // link stroke opacity
linkstrokewidth = 7, // given d in links, returns a stroke width in pixels
linkstrokelinecap = "round", // link stroke linecap
linkstrength,
container
} = {}) {
// compute values.
const n = d3.map(nodes, nodeid);
// here: don't replace the input nodes using this complex method,
// just object.assign({}, n) to essentially perform a deep copy of a node.
// replace the input nodes and links with mutable objects for the simulation.
nodes = nodes.map(n => object.assign({}, n));
links = links.map(l => ({
source: l.src,
target: l.target
}));
const svg = d3.select('body')
.append("svg")
.attr("preserveaspectratio", "xminymin meet")
.attr("viewbox", [-width / 2, -height / 2, width, height])
.classed("svg-content-responsive", true)
const defs = svg.append('svg:defs');
// here: see we add one image per node
defs.selectall("pattern")
.data(nodes)
.join(
enter => {
// for every new <pattern>, set the constants and append an <image> tag
const patterns = enter
.append("pattern")
.attr("width", 48)
.attr("height", 48);
patterns
.append("image")
.attr("width", 48)
.attr("height", 48)
.attr("x", 0)
.attr("y", 0);
return patterns;
}
)
// for every <pattern>, set it to point to the correct
// url and have the correct (company) id
.attr("id", d => d.id)
.select("image")
.datum(d => {
debugger;
return d;
})
.attr("xlink:href", d => {
debugger;
return d.image;
})
const link = svg.append("g")
.attr("stroke-opacity", linkstrokeopacity)
.attr("stroke-width", linkstrokewidth)
.attr("stroke-linecap", linkstrokelinecap)
.selectall("line")
.data(links)
.join("line");
// construct the forces.
const forcenode = d3.forcemanybody();
const forcelink = d3.forcelink(links).id(({
index: i
}) => n[i]);
if (nodestrength !== undefined) forcenode.strength(nodestrength);
if (linkstrength !== undefined) forcelink.strength(linkstrength);
forcelink.distance(linkdistance)
const simulation = d3.forcesimulation(nodes)
.force(link, forcelink)
.force("charge", forcenode)
.force("x", d3.forcex())
.force("y", d3.forcey())
.on("tick", ticked);
const node = svg.append("g")
.attr("stroke", nodestroke)
.attr("stroke-opacity", nodestrokeopacity)
.attr("stroke-width", nodestrokewidth)
.selectall("circle")
.data(nodes)
.join("circle")
.style("fill", "#fff")
.style("fill", d => `url(#${d.id})`)
.attr("r", noderadius);
function ticked() {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
}
} // forcegraph
forcegraph({
nodes,
links
});
line {
stroke: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>
Source: stackoverflow.com
Related Query
- Using D3 to fill an svg with a background image
- SVG image in rect or circle show as black
- Loading a huge image (5mb) into svg background leads to pixelation and performance issues
- Background image to SVG choropleth map using D3
- D3.js CodeFlower Image as circle background
- Image blurry when using url fill pattern for svg circle
- Background image inside foreignObject hides other svg elements on Firefox
- Converting svg rect with background image to black-white
- image as circle background (d3.js svg)
- d3: svg image in zoom circle packing bis
- D3.js: How can I put an image on the background of a circle with the remaining parts trimmed and make it resize along with the circle onclick?
- Prevent image rotation into SVG circle on d3 radial tree
- Adding a line on an svg with image in background in d3
- How to create variable number of image or circle elements in an SVG element using a loop in D3 js(v3)
- Background image not filling circle - D3/JavaScript
- D3 - Select SVG center path when drilled into and display zoom out background image
- data uri as background image of svg not converted to canvas on safari live site
- d3: svg image in zoom circle packing
- Not able to see the background image in svg rect
- Add text on hover, image on the svg circle and make the nodes less sticky in a d3 graph
- How to add an image to an svg container using D3.js
- Adding an image within a circle object in d3 javascript?
- Auto width and height for SVG image
- d3 append an image with svg extension
- how to use svg file for image source in D3
- Can I have a SVG Pattern with background color?
- Add image inside a circle D3
- Best way to preload SVG image tags?
- How can I display a placeholder image in my SVG until the real image is loaded?
- d3.js download graph as svg image
More Query from same tag
- Is there a way to make interactive standalone SVGs in a webpage?
- How to save d3 graph as image on local machine?
- d3.js mouseover events clashing
- Convert Excel file to JSON: design of JSON code check
- how to get silbling elements in sunburst
- d3 change text bound to data
- Print text on two lines on the node of mobile patent suit D3
- Angular2 xlink:href url() issue
- nvd3.js ugly labels in pieChart
- Colour transition in d3 always starting with black
- Null/Empty vs Zero/0 in the defined line
- Selecting element in external SVG
- How to apply d3.zoom() to a HTML element
- trying to understand javascript code
- drag circle area rather than border
- Call Perl script using D3 Xhr
- Map custom value field to x value when using a stacked layout
- D3 manually zoom,how to set the translate for zoom
- Using dc.js on the clientside with crossfilter on the server
- Display multiple d3.js charts in a single html page
- d3 data update CSV - can't figure out how to update table cells
- Using d3.interpolateString for a MM:SS transition
- How to implement a transition duration using D3.js?
- x axis labels overlapping for grouped category bar chart in d3
- Prevent Rickshaw/D3 from showing x axis labels above a given zoom level
- d3.js drag node boundaries not working for linked path
- Make a specific column bold in an html table
- combining class="{{...}}" expression w/ ng-class="{'className' : boolean}" expression?
- D3 - Event binding inside another event
- Animate objects in force layout in D3.js