var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click)
.on("mouseover",function (d){
if(d.name=="Purchased"){
jQuery.getJSON("RequestHandler?usercommand=jsoncompany&subcommand=propCount&useraction=d3Tree_frm&mgmtId="+d.id+"&type="+d.name, function(json){
var count=JSON.stringify(json.prop_purchased_count);
result="Purchased Property :"+count;
});
}
var g = d3.select(this);
var info = g.append("text")
.classed('info', true)
.attr('x', 30)
.attr('y', 30)
.text(result); //result="Amount":200\n"Amount":300\n"Amount":400
})
.on("mouseout", function() {
d3.select(this).select('text.info').remove();
});
//result="Amount":200\n"Amount":300\n"Amount":400
i want to display tooltip such that after \n it appears in a new line within that tooltip.
How to achieve it ?
Thanks in advance
I can see result being set in the code you posted, however what we cannot see is where result is being set to get the content you are 'saying' it contains. That way we could help you interpret the application of these proven recommendations a lot better. But in anycase, have a look at these resources to help you in your quest.
http://bl.ocks.org/mbostock/7555321
How to dynamically display a multiline text in D3.js?
In the else part add "Amount:"+ count + "\n" while you are concatenating the newline
Related
I'm using D3.js for my personal project.
But, I faced with some troubles.
bubble.nodes(root)
svg = d3.select("svg").attr("class", "bubble")
var node = svg.selectAll(".node")
.data(bubble.nodes(root)
.filter(function(d) {
return !d.children;
}))
.enter()
.append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
})
In the picture, I want to get "r" value in the circle.
How can I get this value?
Also, this circle is one part of bubble chart node.
Using vanilla JS... getElementsByTagName('circle'), then getAttribute('r') to find the value of r
let circle = document.getElementsByTagName('circle');
let target = circle[0].getAttribute('r');
console.log(target);
<circle r="0.75847397430597"></circle>
I've got this linechart, on each value in the chart I am placing a dot.
when hovering over the dot I would like to show the value using a d3-tip tooltip.
Here is what I got so far:
var svg = chart.append("svg")
.attr("width", outerWidth)
.attr("height", outerHeight)
.append("g")
.attr("transform", "translate(0,10)");
newData.graphSeries.forEach(function (current, index, all) {
//current = this exact part of the array
//index = the array index nr [0][1][2] etc
//all = the complete array
var graph = current.Values,
color = current.Color;
var nextLine = d3.svg.line()
.interpolate(current.Interpolate)
.x(function (d) {
return x(d.x);
})
.y(function (d) {
return y(d.y);
});
svg.append("path")
.datum(graph)
.attr("transform", "translate(" + yAxisWidth + ",0)")
.attr("class", "line stroke-" + color)
.attr("d", nextLine);
//Placing tooltips
if (current.Tooltips == true) {
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong> TEST: " + newData.y.Unit + "</strong><span>" + d.x + "</span>"
});
//create circles to place the tooltip on
svg.selectAll('dot')
.data(graph)
.enter().append("circle")
.attr("r", 3,5)
.attr("style", "cursor: pointer")
.attr("class", "circle-" + color)
.attr("transform", "translate(" + yAxisWidth + ",0)")
.attr("cx", function(d) { return x(d.x) })
.attr("cy", function(d) { return y(d.y) })
.on('mouseover', tip.show )
.on('mouseout', tip.hide);
svg.call(tip);
}
});
I checked if d3-tip exists in the code and it does.
I can console.log the tip variable, also the dots are showing and even the mouseover and mouseout are working correctly.
Still somehow tip.show doesn't seem to work.
I thought maybe it would show somewhere else in the document, but can't see it anywhere.
Could you please help out.
Best,
Bart
The problem was actually easier to solve then expected.
The tooltip might be 'pushed' away by all other html code.
Adding .style('z-index', '99999999999'); will help to get that straight.
See:
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.style('z-index', '99999999')
.html(function(d) {
return "<strong> TEST: " + newData.y.Unit + "</strong><span>" + d.x + "</span>"
});
I would like to make the labelling of the x axis clickable so that the text includes links.
Here is a fiddle of my code so far: http://jsfiddle.net/3gLfb401/
The x axis labelling consists of the date and a build number. The build number should be a link.
In this example it should be enough if it links to google.com or something.
I already searched in the internet and found some things, that might do it but I don't know how to place it.
I thought something like this could work:
x.html(d3.time.format("%Y-%m-%d")(d.date) + '' + "#" + d.buildNb + "")
This is the method which forms at the moment the text of the labelling:
function formatDataToTick(d) {
return d3.time.format("%Y-%m-%d")(d.date) + " #" + d.buildNb;
}
Try this.
var xLabels = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", function(d) {
return "rotate(-65)"
});
var insertTspans = function(a) {
var b = a.split(" ");
var textNode = d3.select(this);
textNode.text("");
textNode.append("tspan").text(b[0]);
var link = textNode.append("tspan").text(b[1]);
link.style("cursor", "pointer")
.style("fill","blue")
.style("text-decoration","underline")
.on("click", function(a) {
document.location.href = "http://www.example.com/" + a;
});
};
xLabels.each(insertTspans);
currently I'm fiddling with D3.js. It looks awesome!I was wondering if D3.js is suitable to draw multiple svg elements in a webpage. I found the d3.xml method and got it working.
Initially I was playing with Raphaeljs but, for me as a JS-newbie, useful tuts/docs are hard to find. I was converting SVG's to JSON-objects with webtool and then inculde them in 1 js-file it's a lot of work stripping tags and stuff. This saves HTTP-requests. Now I want to try the same with D3.js and see which one will suit me.
Any ideas for importing a multiple-SVG-file with D3?
There is no limit number of SVGs you can write using D3. All D3 does is access the DOM and modify it so that the browser knows to draw an SVG, or how to manipulate the SVG. D3 simply allows you to more easily access the elements and work with them.
If you are reading the SVGs from JSON objects, you just need to read in the multiple JSONS.
Take the first two examples from the D3js.org website as an example...
d3.csv("morley.csv", function(error, csv) {
var data = [];
csv.forEach(function(x) {
var e = Math.floor(x.Expt - 1),
r = Math.floor(x.Run - 1),
s = Math.floor(x.Speed),
d = data[e];
if (!d) d = data[e] = [s];
else d.push(s);
if (s > max) max = s;
if (s < min) min = s;
});
chart.domain([min, max]);
var svg = d3.select("body").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "box")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
d3.select("button").on("click", function() {
svg.datum(randomize).call(chart.duration(1000)); // TODO automatic transitions
});
});
This, from the Box Plot example, will open up "morley.csv" and work with the data.
d3.json("flare.json", function(error, root) {
var node = svg.selectAll(".node")
.data(bubble.nodes(classes(root))
.filter(function(d) { return !d.children; }))
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
node.append("title")
.text(function(d) { return d.className + ": " + format(d.value); });
node.append("circle")
.attr("r", function(d) { return d.r; })
.style("fill", function(d) { return color(d.packageName); });
node.append("text")
.attr("dy", ".3em")
.style("text-anchor", "middle")
.text(function(d) { return d.className.substring(0, d.r / 3); });
});
This, from the Bubble Chart example, will open up "flare.json" and start doing stuff with that. There is nothing stopping you from doing both of these actions in the same file.
What you will have to look out for is variable references, as with any other program. Each SVG will need its own reference. The above two code blocks use the same variable names for several things, so they'd step on each other. If you wanted both these on one page, you would simply need to rename the variables so they are unique.
d3.xml("./svgs.xml", "application/xml", function(xml, error) {
var data = xml.documentElement,
sections = data.getElementsByTagName("section"),
svgWrapper = "center";
for (var i = 0, lenS = sections.length; i < lenS; i++) {
var name = sections[i].getElementsByTagName("name")[0].childNodes[0].nodeValue,
images = sections[i].getElementsByTagName("image");
for (var j = 0, lenI = images.length; j < lenI ; j++) {
//<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
var image = images[j].firstElementChild;
//assuming I only target 1 unique HTML5-element
if (document.getElementsByTagName(name)[0] !== undefined) {
//in search of wrapper-class and append data to it
document.getElementsByTagName(name)[0].getElementsByClassName(svgWrapper)[0].appendChild(image);
// If node "name" is not a element then it's an id
} else if (document.getElementById(name) !== undefined) {
document.getElementById(name).getElementsByClassName(svgWrapper)[0].appendChild(image);
} else {
console.alert("what the hell went wrong while inserting svgs?!");
alert("What the hell went wrong while inserting svgs?!");
}
}
}
});
If somebody got pointers to maybe improve this for like IE9 cause only test this for Chrome and Firefox (have to install Windows VM). How do I catch and handle the error-parameter in the XHR?
I am having a very hard time since there is not much documentation on d34raphael tool.
I am trying to reproduce this example from d3.js: http://bl.ocks.org/d/1249394/ using raphael. The idea is to be able to run this into ie8 which doesn't support svg.
My biggest concern is replacing the "g" svg nodes with raphael code.
For example how to convert these statemetns into d34raphael:
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
or
var nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
I have read the documentation on d34raphael but it hasn't been useful.
Thanks for the help.
Raphael doesn't use the g element but has some notions of a set. d34raphael uses it directly:
paper.setStart()
...
paper.setFinish().transform(["t", margins.top, margins.left]);
But that's not very useful for a direct translation of d3 code. I suggest you flatten your data and all the logic to position your elements, instead of having your elements has children of a group.