D3 Diagram : how may i assign images inside a node - javascript

you can find something like below in the jsFiddle demo included in this question, and i am wondering how may I assign images into each node.
var graph = {
"nodes":[
{"name":"1","rating":90,"id":2951},
]
}
I have jsFiddle Demo in this link : http://jsfiddle.net/JSDavi/qvco2Ljy/
Update 1 :
node.append("circle")
.attr("r", function(d) { return d.weight * 2+ 12; })
.style("fill", function(d) { return color(1/d.rating); });
node.append("image")
.attr("xlink:href", d=> d.url)
//people icon's location (x,y)
.attr("x", function(d) { return d.weight * 2+ 12; })
.attr("y", function(d) { return d.height * 2+ 12; })
//people icon's size
.attr("width", width/10)
.attr("height", height/10);
The codes above is how I set the circle and images
but they never stick together.
this is my updated demo : http://jsfiddle.net/qvco2Ljy/116/

For each object, set the URL of the image:
{name: "1", rating: 90, id: 2951, url: "someUrl"},
Then, instead of appending circles, append an image
node.append("image")
.attr("xlink:href", d=> d.url)
.attr("x", -width/2)
.attr("y", -height/2)
.attr("width", width)
.attr("height", height);
Where width and height are the corresponding image width and height.
PS: have in mind that I'm simply answering your question ("how may I assign images into each node?"). If giving up the circles is not an option for you, you'll have to use a pattern.

Related

d3v4 inverse bubble chart with animation/screen size adaptation

I am trying to convert a bubble chart from d3v3 to v4. Running into x,y,d missing variables?
In this version -- a rect is applied to the svg - and then a circle is cut -- so its like an inverse bubble chart.
I am keen to work out a set radius for the chart as a maxium -- if it should act like a score between 0 and 100? What kind of math to apply that a max radius has been reached to signify that the value is very big?
I also tried to have the svg mask adapt - if the browser or its container changed size -- ideally would want it to response during the change - rather than resizeEnd
//version 3
https://jsfiddle.net/8ag1vf6e/1/
//current version 4
https://jsfiddle.net/d56g9r0y/
// filters go in defs element
var defs = innversebubble.append("defs");
var mask = defs.append("mask")
.attr("id", "myMask");
mask.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("fill", "white")
.style("opacity", 1);
var invisiblebubble = mask.append("circle")
.data(data);
//create a fixed bubble first
invisiblebubble
.attr("cx", "50%")
.attr("cy", "50%")
.attr("r", function(d) {
return d.value - 20;
});
//now mask the fixed circle
var masker = defs.append(function() {
return mask.node().cloneNode(true)
})
.attr("id", "myMaskForPointer")
.select("rect")
.style("fill", "white")
.style("opacity", 1);
invisiblebubble
.attr("r", 10);
//apply the rest of the chart elements
var rect = innversebubble
.attr("class", "series")
.append("g")
.attr("transform", "translate(0,0)")
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", "100%")
.attr("height", "100%")
.attr("mask", "url(#myMask)")
.style("fill", backcolor)
.style("opacity", backopacity);
//animate this circle
invisiblebubble
.attr("cx", "50%")
.attr("cy", "50%")
.transition()
.duration(1800)
.attr("r", 10)
.transition()
.duration(900)
.attr("r", function(d) {
return d.value;
});
latest jsfiddle - 15th June -- needs fixing
https://jsfiddle.net/xmrtahns/
"I am keen to work out a set radius for the chart as a maxium -- if it should act like a score between 0 and 100? What kind of math to apply that a max radius has been reached to signify that the value is very big?
I also tried to have the svg mask adapt - if the browser or its container changed size -- ideally would want it to response during the change - rather than resizeEnd"
I've fixed the conversion and the data source - but still need issues to resolve.
var backcolor = $this.data("color");
var backopacity = $this.data("opacity");
var width = $this.data("width");
var height = $this.data("height");
var data = [{
"label": $this.data("label-name"),
"centralLabel": $this.data("central-label"),
"xPer": $this.data("displace-left"),
"yPer": $this.data("displace-top"),
"value": $this.data("bubble-value")
}];
http://jsfiddle.net/hLymw8et/2/
--I am keen to work out a set radius for the chart as a maximum -- if it should act like a score between 0 and 100?
--What kind of math to apply that a max radius has been reached to signify that the value is very big?
--I also tried to have the svg mask adapt - if the browser or its container changed size -- ideally would want it to response during the change - rather than resizeEnd –

Why are the old bars still visible after transition

I have a D3 barchart which has 5 bars. When I update it I can see it transitioning to the correct 3 bars but some of the original bars are left visible - how do I make them exit?
This is what it initially looks like:
This is what it ends up looking like:
The dark blue bars are correct. The current code for updating the "rect" objects is the following:
var plot = d3.select("#barChartPlot")
.datum(currentDatasetBarChart);
/* Note that here we only have to select the elements - no more appending! */
plot.selectAll("rect")
.data(currentDatasetBarChart)
.transition()
.duration(750)
.attr("x", function (d, i) {
return xScale(i);
})
.attr("width", width / currentDatasetBarChart.length - barPadding)
.attr("y", function (d) {
return yScale(+d.measure);
})
.attr("height", function (d) {
return height - yScale(+d.measure);
})
.attr("fill", colorChosen);
You only have 3 new bars, so the number of elements on your data has changed.
You need to use the update pattern.
var rects = plot.selectAll("rect")
.data(currentDatasetBarChart);
rects.enter()
.append("rect")
//Code to style and define new rectangles.
//Update
rects.update()
.transition()
.duration(750)
.attr("x", function (d, i) {
return xScale(i);
})
.attr("width", width / currentDatasetBarChart.length - barPadding)
.attr("y", function (d) {
return yScale(+d.measure);
})
.attr("height", function (d) {
return height - yScale(+d.measure);
})
.attr("fill", colorChosen);
// Remove unused rects
rects.exit().remove();

How to set up a reference index on horizontal bar chart and transition control

here is my code
var w = ($ ( ".column" ).width());
var h = ($ ( ".column" ).width());
var barPadding = 15;
var dataset = [ ['Graphic Design' , 7], ['Branding' , 8], ['Digital Animation' , 10], ['Web Design' , 9], ['Typography' , 7], ['AV Production' , 9] ];
//Create SVG element
var bars = d3.select(".column")
.append("svg")
.attr("width", w)
.attr("height", h)
//starting rects
var graph = bars.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("width", 0)
.attr("fill", "#636363");
//labels
var text = bars.selectAll("text")
.data(dataset)
.enter()
.append("text");
//Add SVG Text Element Attributes
var textLabels = text
.attr("x", 10)
.attr("y", function(d, i) {
return 35 + i * (h / dataset.length); })
.text( function (d) { return d[0]; })
.attr("font-family", "Quicksand, sans-serif;")
.attr("font-weight", "bold")
.attr("font-size", "0px")
.attr("fill", "#1c1d1e");
//transition at waypoint
$('#slide-4').waypoint(function(){
//transform the bars
graph.transition()
.duration(1000) // this is 1s
.delay(400) // this is 0.1s
.attr("y", function(d, i) {
return i * (h / dataset.length);
})
.attr("x", 0)
.attr("height", h / dataset.length - barPadding)
.attr("width", function(d) {
return (w * d[1] / 10);
})
.attr("fill", "#F05D5C");
//transform the labels
text.transition()
.duration(1000) // this is 1s
.delay(400) // this is 0.1s
.attr("font-size", "20px")
},{ offset: '-100%' }
);
And a little demo: http://jsfiddle.net/65qNa/6/
Everything works as it should be but if you follow the link you can see some bars and their labels spawning all together from nowhere.
1) I'd love those bars to have each one a reference index behind them in the shape of a plain boring grey rect the same height but with the width of the whole div containing the script.
I've tried a few solutions: creating another svg I was unable to put it behind my existing one; putting a div behind the div I'm working on didn't work well on my page for some reason.
2) It would also be lovely if those bars and labels could span one by one and not altogether.
Can you guys please help me?
Thank you!
2)
try something like (I haven't tested it):
graph.transition()
.duration(1000) // this is 1s
.delay(400*function(d,i) {return i;}) // this is 0.1s
.attr("y", function(d, i) {
return i * (h / dataset.length);
})
2)
because of how d3 handles data:
.delay(function(d,i){return i * 300}
Like this the rect at [0] won't have any transition though.
It's enough to tweak it manually and write:
.delay(function(d,i){return **300 +** i * 300}
to make it work.

D3js - can't change style for svg text elemets

I am using d3.js to create text elements on svg canvas. And I'm trying to change the style of the text. But somehow it doesn't seem to work. Only the x-y coordinate can be changed successfully, but other attributes like font size and color wouldn't change. I've also tried using .attr instead of .style. Nothing happened. Can anyone help? Really appreciate it!!
//create canvas
var canvas = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500);
//text data
var textSpec = [{"content" : "testing", "font-family" : "sans-serif","font-size" : "80px", "color" : "red" , "x" : 100 , "y" : 15}];
//text display
var text = canvas.selectAll("text")
.data(textSpec)
.enter()
.append("text")
.attr("x", function(d) { return d.x;})
.attr("y", function(d) { return d.y;})
.text(function(d) { return d.content})
.style("font-family", function(d) { return d.font-family;})
.style("font-size", function(d) { return d.font-size;})
.style("stroke", red)
.style('fill', function(d) { return d.color;});
There is error reported:
Uncaught ReferenceError: family is not defined
because d.font-family is not treated as property font-family of variable d but as property font of variable d minus family.
Also, red is used like variable which is not defined.
You have to change the code to:
...
.style("font-family", function(d) { return d['font-family'];})
.style("font-size", function(d) { return d['font-size'];})
.style("stroke", 'red')
.style('fill', function(d) { return d.color;});

d3.js replace nodes with images

Here's the code I am running http://jsfiddle.net/a7as6/14/
I know that I can use this code to change node to image:
node.append("svg:image")
.attr("class", "circle")
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("x", "-8px")
.attr("y", "-8px")
.attr("width", "16px")
.attr("height", "16px");
But when I use it and my nodes are still not images. Any idea why?
And I am wondering how to change each nodes with different images?
Thx.
You've got the right idea for appending the images, but you need to operate on node.enter() as in:
node.enter().append("image")
.attr("class", function (d) {
return "node " + d.id;
})
.attr("xlink:href", "https://github.com/favicon.ico")
.attr("width", "16px")
.attr("height", "16px");
You then need to get your tick function to place the images, as in:
function tick() {
node.attr("x", function (d) {
return d.x;
})
.attr("y", function (d) {
return d.y;
})
And here's the working fiddle. Not that you'll need to move the images around so they look right, you can use the dx and dy properties to bump them.

Categories

Resources