I would very much appreciate support on Mike Bostocks' Box Plots
Until now, I have been unable to figure how to add specific text annotations - for example with .append("text") - adjacent to each of the boxTick and whiskerTick for example to describe to the viewer what these values are, like "Q3" or whatever.
What would be a good way to achieve this?
Here's a working demo:
Plunkr with description for box and whisker ticks in a box plot
I'm just using the same logic (using index i) used to determine the position of the tick i.e. dx
Relevant code changes:
For box ticks:
.text(function(d, i) {
var quartile = i & 1 ? 'Median' : !i ? 'Q1' : 'Q3';
return quartile + ': ' + format(d);
})
For whisker texts:
.text(function(d, i) {
return (!i ? 'LW: ' : 'UW: ') + format(d);
})
Let me know if you have any questions. Hope this helps.
Related
I've created a scatter graph using the following code as a basis:
http://bl.ocks.org/peterssonjonas/4a0e7cb8d23231243e0e
However I'd like to change the background of the tooltip either based upon the colour of the selected element, or by adding a data column related to colour (i.e. d.colour).
The code currently generates tooltip text based upon the selected element via the following lines:
var tip = d3.tip()
.attr("class", "d3-tip")
.offset([-10, 0])
.html(function(d) {
return xCat + ": " + d[xCat] + "<br>" + yCat + ": " + d[yCat];
});
I was hoping that by adding something like:
.style("background", function(d) { return d.colour; })
I'd be able to achieve this. However when I do this I find that d is undefined (by adding a console.log before returning).
I'm a super novice when it comes to this kind of thing, so any advice anyone could give me would be super helpful.
Thanks!
Here is a positive criticism: don't use d3-tip or any other plugin to create your tooltips. Create them yourself. That way, you can have better control over them and customise them the way you want.
Back to the question: without even looking at that plugin's documentation, you can select the element (in this case, a <div>) by class:
d3.select(".d3-tip").style("background-color", color(d[colorCat]));
Here is the updated bl.ocks: http://bl.ocks.org/GerardoFurtado/70f2608e455b61514cc96dff6fe41ea6/65c940cb987ae1cbda5dc352cda54a382a945ae8
Regarding the undefined: the tip.style is not receiving the datum when the event is fired, apparently only tip.html does. To be sure about that you have to check their source code.
I am using the example Zoomable Circle Packing by Mike Bostock and I try to change the radius of some circles, which are identified by the type "secteur" in the dataset.
To do that, I tried to use the following line:
circle.filter(function(d) { return d.type === "secteur"; }).attr("r", function(d) { return d.r * 1.5 ; });
The example is available here.
Even without filtering by datum type (I tried to remove the .filter part) the line seems to have no effect on any radiuses, I didn't see any changes in the console.
I do not understand why, and I would appreciate insights if any
Thank you
Your zoomTo function set's the radius again after you set it with your filter.
You call:
zoomTo([root.x, root.y, root.r * 2 + margin]);
Which does:
circle.attr("r", function(d) { return d.r * k; });
I am looking for help to override default tooltip functionality for nvd3 bar (discrete) chart.
The default tooltip picks yAxis ticks and show in the tooltip.
However, in my case i don't want to show yAxis data (formatted in currency) in tooltip rather than i would like show actual yAxis value (original value without currency).
This is how i am pushing values to my data[].
#foreach (var item in Model.BarChart)
{
string yvalue = item.Cost== 0 ? "undefined" : item.Cost.ToString();
string xvalue = item.Date.ToString("yyyy/MM/dd");
#:data[0].values.push({y: #yvalue, x: '#xvalue'});
}
I am formatting yAxis tick using the following line of code
chart.yAxis.tickFormat(function(d) { return d3.format(".1s")(d) + " USD" });
Any hint?
Let me know if you need more info?
After googling, i found the following way but in this example 'y' is yAxis value and not the original value. So, how i can replace this 'y' with orginal value?
chart.tooltip(function (key, x, y, e, graph) {
return '<p><strong>' + key + '</strong></p>' +
'<p>' + y + ' in the month ' + x + '</p>';
});
Try e.value instead of y.
chart.tooltipContent(function (key, x, y, e, graph) {
return '<p><strong>' + key + '</strong></p>' +
'<p>' + e.value + ' in the month ' + x + '</p>';
});
e.point should also contain the original data, including any extra attributes. For example, if your input data has an "extra" attribute (like { label : "A" , value : -29.76, extra: 123 }), then you can use e.point.extra.
I'm trying to draw a network topology using D3sj force directed layout. I did a basic topology with link and node. However, now i want to show the interface name for each link on each node as the following picture. Could you guys guide me how i can do that?
Thank you in advance!
P/S I attached my topology here!1
Ideally you should present the javascript that you have already written, and explained what it does do, and what is missing. Having said that, I recently finished work on a similar project to what you describe, so had the following results handy.
Does this jsfiddle do what you are attempting?
There are two key components. The first is in defining the text elements (here I append them to an SVG element):
var text = svg.selectAll('text')
.data(force.nodes())
.enter().append('text')
.text(function (d) { return d.name });
Here I'm assuming that the nodes[] array contains objects with a .name property that is to be displayed.
The second component is to translate the text elements to their appropriate positions, inside the tick handler:
function tick () {
text.attr('transform', function (d) {
return 'translate(' + d.x + ',' + d.y + ')';
});
// Other code for nodes and links
}
See the jsfiddle for a complete working example, including commented code that should allow you to add images at the nodes if you want to try to reproduce your sample image more closely.
Code link: http://jsfiddle.net/mj58659094/yKUsQ/;
When clicked on a person (node), it selects the spouse also. I only want to select (highlight) the person I clicked on (husband or wife or child). (When I inspect the html in FireBug, spouse nodes (g transform="translate(0,70)") are inside the person nodes. I think they should be outside, but within g class="node" group). I don't know how to fix this. Anyone, please help. Thanks.
Updated: Edit below
I think you are right in that the best way to solve your onclick problem is to keep a person's spouses in the same group as the person (instead of in a nested group). In addition to that, I think you are applying the onclick in the wrong place. My advice is to
Change lines 325-330 to the following
var node = g.append("svg:g").attr("class", "node")
.selectAll("g")
.data(function (d) { return d.nodes; })
.enter().append("svg:g");
node.append("svg:rect")
.on("click", clickedNode);
Currently, you were applying the onclick to the group containing both the person and his/her spouses, while instead you want to use the onclick on each person/spouse separately. Note that once you make this change, you will need to update your code to test each node's rect (instead of the node's group g) as to whether it is selected (lines 355-365). You will also have to update your CSS to style .node rect.normal and .node rect.selected on lines 25 and 29 of your CSS file.
The second issue is that you are only drawing the first spouse for each person. Currently the updateSpouses function is iterating over each person, and then adding a group with a rectangle for just the first spouse. What you need to do is first add a group for each person with spouses, and then over each person's spouses. Here's a rough draft of how to modify updateSpouses to get you started:
var node = svgTree.selectAll(".node g")
.append("svg:g").attr("transform", function (d, i) {
if (i == d3.familyTree.rootGeneration)
return "translate(" + (d.spouseX) + "," + (d3.familyTree.gapBetweenSpouses) + ")";
else
return "translate(" + 0 + "," + (d3.familyTree.gapBetweenSpouses) + ")";
})
.filter(function (d, i) { return personSpouses" in d });
var spouses = node.selectAll(".spouse")
.data(function(d){ return d.personSpouses }).enter()
.append("rect")
.on("click", clickedNode);
Edit
In response to your comment, I went ahead and modified your original code http://jsfiddle.net/mdml/xJBXm/. Here's a quick summary of the changes I made:
I put each person in a group, which then has its own onclick attribute (lines 141-146), so that when you click on the rectangle/text clickedNode is called.
I also put each set of spouses in a group (as described above) so that each of them are individually clickable as well (lines 229-232).
I modified the resetNodePersonSelected and setNodePersonSelected functions so that they search/update spouses in addition to children.
I've described the changes in high-level above but let me know if you have any more questions on the implementation.