d3.js force directed graph search - javascript

I am trying to implement a search function on a d3 force directed graph example.
When I type in the search query in the text field, relevant items will be shown and the irrelevant ones will fade out.
I have implemented the methods searchUpdate and count as shown in the following jsfiddle.
I need some help to fade the items. Currently d3.select("svg") fades the whole graph, while d3.select("#"+n.id) produces an error.

When you d3.select("svg") you're selecting the SVG canvas and setting its opacity. What you want to do is
d3.selectAll("circle")
or
d3.selectAll("circle.node")
and apply the opacity there.
Then what you want to do is select the circles that match by ID using d3.select("#"+n.id) but to do so you'll have to create an id when you create the circles, like
.attr("id", function(d,i) {return "circle"+i})
Otherwise you don't have an id to select with.

Related

Removing old text labels when bar chart is updated

I am trying to build a D3 bar chart visualization that can be updated using a drop down menu.
So far, I have successfully created the bar chart and the drop down menu such that when I change the selection in the menu, the bars are updated to their new values.
However, I am having problems with the bar labels updating appropriately. Even though I include the same .exit.remove() function for the labels as for the bars, the old labels remain on the newly updated chart.
Image of the updated chart w/ problem labels
Test csv file
Test code
Apologies for the links. I'm new to JSFiddle, and I couldn't figure out how to easily transfer my example.
You forgot to add class attribute while appending the text
You also need to change the text while updating
Hope this helps
bartexts.transition().duration(250)
.attr("y", function(d, i) {return yScale(d) - 10})
.text(function(d) {return d});

How to add controls and buttons to map?

This is probably a really basic question, but I can't figure it out. I'm building a map using D3. My code creates and svg, appends a g element to it and then draws the map within it. What I want is to render a set of buttons and controls that are positioned inside the map viewer. They would be zoom buttons, a dropdown to display different sets of data and a timeline slider.
For example, with the dropdown selector I want placed I did this:
I tried using d3 as in:
svg.append("select")
.attr("class", "field_dropdown")
.data(['housing_unit', 'tenure', 'median_contract_rent', 'median_value', 'median_income'])
.enter()
.append("option")
.attr("value", function(d) {
return d
});
but this rendered the select item and option items separate from each other, and not even visible within the map container.
As mentioned, not only do I wanna add a dropdown, but also buttons for zoom and a slider, among other items. How do I render and position them in the map container?
Thanks
This has been asked several times (surely a duplicate): you cannot append HTML elements ("div", "p", "select", "h1" etc) to an SVG. It will simply not work.
The best solution, in your case, is creating the drop down menu and the other controls outside the SVG, in the HTML.
But, if you really want to create this drop down inside the SVG (which I don't advise), you can use foreignObject (which will not work on IE):
var foreign = svg.append("foreignObject")
.attr("width", 100)
.attr("height", 100)
.append("xhtml:body");
var select = foreign.append('select')
.attr("class", "field_dropdown")
//the rest of your code

D3 sunburst sequence colors and sunburst arc colors not matching

I am working with a zoomable sunburst in D3 that also has some breadcrumbs. First time working with D3 so I don't know all of the intricacies yet, but I am having trouble getting the colors of the arcs in the sunburst and the breadcrumbs in the sequence to match up. It only ever happens on the leaf nodes too which is weird. I can click on the inner circle and the breadcrumb shows up with the same color, and so on until I click on a leaf node.
Originally I set the color like this var colors = d3.scale.category10(); and the in the chart options like color: colors, When trying to set the colors for the polygon for the bread crumb I thought it'd be as simple as this which I had seen from a few examples,
entering.append("svg:polygon")
.attr("points", breadcrumbPoints)
.style("fill", function(d) {
return colors(d.name);
});
But this results in the explanation above. So to clarify in the picture below, either the outer arc on the sunburst should be pink, or the lowest bread crumb should be red. (I'm not sure which is correct, probably the former):
I have a working plunker I am almost done with, but can't get this part. Also part two kind of, but is it possible to set the color of individual arcs based on a certain value?
EDIT Okay well after looking at some more examples, it appears the red on red is okay in the picture for example. So I guess the solution I am looking for is to correct the behavior of the breadcrumbs.

Linking two elements on mouseover and dual tooltips

I'm looking for some advice on how to get two elements in a visualization, which are linked by a common data value, to respond simultaneously.
Here is the visualization as it stands now.
http://bl.ocks.org/natemiller/2686e5c0d9a1a4bb0895
Note that the different colored points are for the 50 US states in 2005 (green) and 2013 (blue), so there is a blue point and a green point for each state. I have two things I would like to get working here.
I would like to be able to mouseover either a blue point or a green point and have the corresponding point (for the same state) highlighted.
I would like a tooltip with some basic data to appear next to both points, providing point specific data.
Regarding the first point above. Right now when you mouseover a blue point the corresponding green point is highlighted, however, when you mouseover a green point only that point is highlighted and not its corresponding blue point. I imagine this is a simple fix, but for the life of me I can't figure out to reverse the reference so I get green to blue references as well.
Regarding the second point. Right now a tooltip with relevant information appears near the moused-over point, but I would like to have a similar tooltip appear next to the corresponding point from the alternate year of data, so that direct comparisons across years are easier. I am quite new to adding HTML tooltips so I'm not clear on how to do this and suspect it may require a new method for adding tooltips. Can any help to steer me in the correct direction for how to have a tooltip appear near the moused-over element and a corresponding linked element?
1) Remember that ids are unique and you're creating multiple circles with the same id, use a class instead
circles.attr("class", function(d) { return d.state })
2) You're creating a single tooltip, if you want to show one for each pair of states create multiple tooltips
Assuming that you make these changes you can easily create multiple tooltips for each pair of states
circles.on('mouseover', function (d) {
// selection for 2 states
var states = d3.selectAll('circle.' + d.state)
// code to style those nodes goes here ...
// tooltips for the states
var tooltips = d3.select('svg').selectAll('text.tooltip')
.data(states.data())
// initial styling of the tooltips goes here...
tooltips
.enter()
.append('text')
.attr('class', 'tooltip')
// update
tooltips
.html(function (d) {
// text of the tooltip
return 'something'
})
// positioning, it requires some margin fixes I guess
.attr('x', function (d) { return xScale(d.child_pov) })
.attr('y', function (d) { return yScale(d.non_math_prof) })
})
Finally remove the tooltips created on mouseover when the mouseout event is triggered
circles.on('mouseout', function (d) {
d3.select('svg').selectAll('text.tooltip').remove()
})
You cannot have multiple elements with the same id. Use a class .circleHawaii instead of an id #circleHawaii.

missing segments in d3 when putting sunburst on top of pie

(first posted on google group but no response so assuming I should be posting this here).
Am trying to lay a sunburst (coloured arcs) on top of a pie (yellow and white segments).
Here is a js fiddle that shows the problem, the initial green segments are missing:
http://jsfiddle.net/qyCkB/1/:
and a js fiddle without the pie where all the segments are shown correctly:
http://jsfiddle.net/X3sRy/1/
I have checked the nodes variable after it has been created on this line:
var nodes = partition.nodes({'values': data});
and the values appear to be the same in both examples.
On checking the DOM, it is just not drawing the first few segments of the sunburst.
Should this work or is it not possible to put two different layouts on top of each other?
Is there a better approach to achieving the same thing?
Your second-data join is colliding with the first. Your first data-join is on "g.arc", so you should be adding G elements with the class "arc" (not "clock_arc"). Your second data-join is on "path", which is inadvertently selecting the path elements you added previously. Since your second data-join matches the previously-added elements, you're not entering all of the expected elements for the pie.
You need to disambiguate the sunburst path elements from the pie path elements. One way you could do this is to select by class rather than element type, so the second data-join becomes ".pie" rather than "path". Something like this:
var gClock = svg.selectAll(".clock")
.data(clockData)
.enter().append("g")
.attr("class", "clock");
var pathClock = gClock.append("path");
var pathPie = svg.selectAll(".pie")
.data(pieData)
.enter().append("path")
.attr("class", "pie");
I'd also recommend reading these tutorials, if you haven't already: Thinking with Joins, Nested Selections, Object Constancy.

Categories

Resources