My aim is to have a multi-line chart with a brush, and the vertical gridlines follow the changing ticks. I'm almost where I want to be but there's still a few thorns in my side. Please see my jsFiddle:
http://jsfiddle.net/U4CGz/3/
Right now I can get it so that either
x-axis ticks change properly, lines disappear, gridlines don't behave, y-axis disappears
or
x-axis ticks do not change, lines work properly, grid lines do not change
You can switch between these two behaviors at the bottom of my code:
function brushed() {
x_main.domain(brush.empty() ? x_mini.domain() : brush.extent());
// alternate between these two
main.selectAll('path').attr('d', line);
// main.selectAll('path').attr('d', function(d) { return line(d.values); });
main.select('.x.axis').call(xAxis);
update_vgrid(x_main);
}
Has anybody else dealt with these things before? Thank you
Related
With assistance, I've uncovered the way to change elements in a radial dendrogram.
The lines below perform that function.
However, I'm trying to guess at what I need to bold text with the same mouse over. Can someone tell me what I'm missing?
// responsible for changing the style and type of the nodes when mousing over them
d3.selectAll('g.node').attr("id", function(d,i){ return "node"+i});
d3.selectAll('path.link').attr("id", function(d,i){ return "link"+i}); //my guess is on the line
below
d3.selectAll('text').attr("id", function(d,i){ return "text"+i});
// still trying to figure out how to make the text bold on mouse over
d3.selectAll('g.node').each(function(d, i) {
d3.select('#node'+i).on("mouseover", function() {
d3.select('#link'+(i-1))
.attr('style','stroke-width: 4px','style','font-weight: bold'); // my 2nd guess is on the next
line
d3.select('text').attr("font-weight",function(d,i) {return i*800+800;});
}).on("mouseout", function() {
d3.select('#link'+(i-1)).attr('style', 'stroke-width: 1.5px','stroke-opacity: 0.4','stroke:
#555');
});
});
In order to set font-weight - which is a CSS property -, .style should be used instead of .attr:
d3.select('#link'+(i-1))
.style('font-weight','bold');
Useful reference: modifying elements with d3-selection.
(I'm still figuring how best to use this platform)
But my answer was to create a CSS class called, .node text:hover, then increase the font weight within that class.
In Mike Bostock's cubism demo (http://bost.ocks.org/mike/cubism/intro/demo-stocks.html), there is a cursor which displays the values of all horizon charts on display. Furthermore, the cursor text shows the time axis point in time. As the cursor text obscures an axis label, the label fades.
I am working on a similar display with d3.js (but not cubism). I have all working except that fade portion. I have searched through the CSS in the developer's window, searched the source code (as best I could), but I don't understand what manner of magic is being used to accomplish this feat. I've even looked through SO "axis label transition" questions, but I have failed to connect the dots on xaxis label transitions.
How does that fade in/out when obscured by text happen?
UPDATE:
I think I located the event script area where this happens - its just a little over my head at the moment - can anyone help me decipher what this event listener is doing? Specifically, in the second g.selectAll in the else clause below - what data (d) is being used here? What is causing this event to fire?
This is the coolest part of the display (outside of the horizon charts), I would love to figure this out ...
context.on("focus.axis-" + id, function(i) {
if (tick) {
if (i == null) {
tick.style("display", "none");
g.selectAll("text").style("fill-opacity", null);
} else {
tick.style("display", null).attr("x", i).text(format(scale.invert(i)));
var dx = tick.node().getComputedTextLength() + 6;
g.selectAll("text").style("fill-opacity", function(d) { return Math.abs(scale(d) - i) < dx ? 0 : 1; });
}
}
});
I used this as reference to accomplish the same effect.
I'm not sure what the context variable is or how the id's are set or what the tick flag references but what I did was simply update the opacity of the ticks according to their proximity to the mouse. With this, the vertical tick fades as well as the label text.
svg.selectAll('.x.axis .tick').style('opacity', function (d) {
return Math.min(1, (Math.round(Math.abs(d3.mouse(svg.node())[0] - x(d))) - 10) / 15.0);
});
This way, the opacity is set to 0 if it's within 10 pixels, and fades from 1-0 between 10 and 25. Above 25, the opacity would be set to an increasingly large number, so I clamp it to 1.0 using the Math.min function.
My labels are slightly rotated, so I also added an offset not shown inside the formula above (a +3 after [0]) just to make it look a bit nicer. A year late to answer your only question, but hey it's a nice effect.
same answer as Kevin Branigan's post, but using the d3 scale to calculate the opacity value.
var tickFadeScale = d3.scale.linear().domain([10,15]).range([0,1]).clamp(true);
svg.selectAll('.x.axis .tick').style('opacity', function (d) {
return tickFadeScale(Math.abs(d3.mouse(svg.node())[0] - x(d)));
}
I have a pie chart and I'm trying to transition the rotation of my labels. For some reason, when I add transition, the text is removed. I've created a fiddle of my problem:
http://jsfiddle.net/samselikoff/k69We/
The chart renders but without labels. On line 110, uncomment out the setTimeout function. After a second, the transition will work correctly.
Why does the transition without the setTimeout blow away the label values?
The erring pair of lines in the code are line 65:
piece.append("g").attr("class", "label").append("text").style("opacity", 0);
And line 93:
g.selectAll(".label")
.data(function(d) {return d;})
.transition()
.duration(500)
// ...
.select('text')
// ...
.style("opacity", 1)
You cancel this transition on text on line 114 by starting a new transition:
g.selectAll(".label")
.select("text")
.transition()
.duration(500)
// ... (opacity is not changed here)
Hence, the opacity of the text stays zero. You can inspect the DOM to see that indeed the text elements exist (i.e. not blowen away) but just with opacity zero. This is a behavioural change between D3v2.7 and D3v3.
Now there are number of ways of correcting this depending on what was the behaviour you originally wanted. One of the ways is this: http://jsfiddle.net/zvPB6/ which straightens the labels in-sync with the other transitions.
If you wanted a .delay(500) for the straightening, then you'll probably have to listen to the end event and start a new transition in order to not delay the whole transition on all texts.
I am using D3.js to draw an axis with ticks. I would like to hide only the last tick on the y-axis.
Maybe a picture will make it clearer. This is what my axis looks like at the moment - I'd like to hide the "21" and its associated tick.
Here is my current code:
var yAxisScale = d3.svg.axis().orient("left");
yAxisScale.scale(y_position);
yAxisScale.ticks(20).tickFormat(function(d) { return d+1; });
var yAxis = vis.selectAll("g.y.axis").data([1]);
Is there a way I can hide only the last tick, regardless of how many ticks there are on the y-axis?
I tried adding this line, but it doesn't work, even though the selectAll expression appears to return the right element.
d3.select(d3.selectAll("g.y.axis g")[0].pop()).style('opacity', 1e-6);
The opacity is still set to 1.
you should to take a look at axis.tickSize(). it allows you to set the size of the major, minor, and end ticks.
also see here for similar question:
Remove end-ticks from D3.js axis
I am a novice while working on d3.js.
I wanted to know how can we Animate some data (eg. Change colors) with respect to time.
eg. Let's say, in Monitoring app, I am projecting cluster data over US Map. Projection is done by drawing a circle and filling it by RED, GREEN or YELLOW color depending on it's status.
When we start monitoring, ideally all circles will be filled with "GREEN" color and then over time color can change to "YELLOW" or "RED" depending on how cluster is behaving.
So if I need to play these color changes over time in some time window, how can it be done ?
If you can point me to any of the similar examples , that will help too ?
Thanks
Take a look at http://mbostock.github.com/d3/tutorial/bar-2.html. Basically you'll need a redraw function that you'll call whenever you want to update your chart. (Note: there is nothing special about the name of this function, you can call it whatever you want.)
You can use setInterval to create a basic timer, this is the rate that your chart will be updated.
setInterval(function() {
redraw(); // call the function you created to update the chart
}, 1500);
Then you define redraw to update the chart data. This is a redraw function for a bar chart, but yours would be similar. You would just be adjusting the color based on the data instead of the y position and height.
function redraw() {
// Update…
chart.selectAll("rect")
.data(data)
.transition()
.duration(1000)
.attr("y", function(d) { return h - y(d.value) - .5; })
.attr("height", function(d) { return y(d.value); });
}
Note that this is a simplified version, I recommend reading the page that I linked above for a more complete example.