Hi excuse the newbie nature of this question (and code snippet).
I want to set the extent of a brush. I firstly, I better make sure that my definition of "extent" is correct.
It seems that in most brush examples (such as this: http://bl.ocks.org/mbostock/6232620 ) when the user is initially presented with the brush -- a region is not selected.
I would like to set an initial region...so that the user can already see a selection.
I figure that this selected region is called the "extent".
I have defined my brush as follows:
var the_brush = d3.brushX().extent([[0, 0], [width, height]]).handleSize(50).on("brush", brushed);
And then attach it to an svg element using the following:
svg.append("g").attr("class", "brush").call(the_brush);
The height and width are initially defined as 50 and 880 respectively.
I then figure that I should be able to experiment in Chrome console to redefine the extent such that a shaded area is displayed.
I use this command (in the Chrome console):
the_brush.extent([200, 0], [500, 50])
But a function is returned.
Mmmm I am obviously missing something quite fundamentially here...by what..?
I hope it is clear from my question...my actual objective. That is when the user first opens the page that (s)he is presented with a brush widget that already has a portion selected.
There is a hacky (but working) copy of the code here
My question is similar to a previous question here
But I do not think that the previous solution is applicaton to D3 version 4.
Thanks.
Related
I've got a behavior with d3.zoom whose solution I'm sure is to be found in something I'm obviously missing, but I can't seem to make sense of it. I've reviewed and reviewed examples, and seem to be following them precisely, but something is causing this particular function to not behave.
The following, rather than zoom to focusElement as intended, flips between zooming away from it, and then back to it. The values of -focusBBox['x'], for example, flip between the following two values on subsequent executions. 2500 is svgWidth/2
-208.586669921875
2500
function focusObject(focusElement) {
var focus = document.getElementById(focusElement);
var focusBBox = focus.getBoundingClientRect();
gridGroup.transition().duration(750).call(zoom.transform,d3.zoomIdentity.translate(-svgWidth / 2, -svgHeight / 2).translate(-focusBBox['x'], -focusBBox['y']));
}
Can someone just please take a moment to give a kind virtual slap to point out what it is that I'm missing?
Aha! From a previous incarnation of this particular endeavor, I was using a fixed-position SVG to capture mouse events and applying my transformations to a child SVG. The fact that getBbox() returns local coordinates and getBoundingClientRect() returns coordinates from the outer SVG coord system thus mucked things up.
I've included the revised snippet below. Note that focusBBox2 uses getBBox rather than getBoundingClientRect(), and that grid is the parent SVG as distinct from gridGroup in the original post.
function focusObject(focusElement) {
var focus = document.getElementById(focusElement);
var focusBBox2 = focus.getBBox();
grid.transition()
.duration(750)
.call(zoom.transform,d3.zoomIdentity.translate(focusBBox2.x, focusBBox2.y));
}
I am building a version of this parallel coordinate view in d3.js v4.
https://bl.ocks.org/syntagmatic/05a5b0897a48890133beb59c815bd953
In my example I have a predefined selection (in the form of a [min,max] array that I would like to set programatically as a brush in one or more of the axes, after the plot has loaded. But I cannot seem to find a way to do it. Most examples I found on setting a brush from code are using d3 v3 and use setting extent but that does not work anymore in v4 it seems.
can someone give me some tips and a simple example hot to do this in this case (so with multiple axes and brushes active) ?
thanks
Select your brush group and call brush.move, then also pass an array with the start and end coordinates. Your brush move event will then take care of the rest.
d3.select(".brush").call(brush.move, [[startX, endX], [startY, endY]]);
Could some one please suggest how to do column-drilldown with D3 JS library,
below example is from Hightchart,
http://www.highcharts.com/demo/column-drilldown
A complete code example for this problem is probably quite extensive, so I'll mostly keep to how you would approach it and assume you know enough of D3 to turn the concept into code.
Lets assume you have the functionality for drawing a general bar chart.
Part of that functionality would priobably be things like
Setting up your svg element and containers
Setting up your scales (one for x and one for y)
Adding axes based on the scales you have created
Adding your bars to the svg container
4.1 Make sure you have your data set available as an array
4.2 Create an enter selection for the available data and append rectelements
4.3 Update attributes like x, y for all your available bar nodes
4.4 Remove any nodes on your exit selection
Voila you have a simple bar chart. Nothing new in that and you can have a look at the code details here -> https://bl.ocks.org/mbostock/3885304
Now in order to do the drill down:
In order to avoid lots of code repetition it probably makes sense to separate the above steps into functions. So for example a setup function that just creates your svg and containers as well as your scales.
Important about the setup function is that you do not need to rerun it on drill through.
Second you will want an update function. This contains steps 3+, which you will need to rerun in order to update your charts on drill through.
One addition here would be adding functionality for updating your scale domain in the beginning (as your data changes on drill through and you want to reflect that in your scales).
Now that you have those two functions all you really need to do is:
Add a click handler to your axis labels or your bars (click on bars might be easier for now). You cans use d3's .on() function for that.
In that event you will want to subset your data by the value of the clicked bar (or get a new data set for the bar value depending on how your data is structured) and then run the update function we created above with the new data.
It could look something like this:
d3.selectAll('.bar-nodes')
.on('click', function(d) {
var updatedData = updateData(d);
updateChart(updatedData);
});
If anything is unclear some more specific questions would be good.
Hope that helps.
I am trying to modify Bullet Charts example of dimple.js with each bullet chart being in a child-svg of the parent-svg. Purpose of having individual svg for each bullet chart is to make their management (show/hide/remove) easier. Also, this makes the recursive definition of a chart complete - That is, a chart is contained by an svg.
The fiddle for the modified version is here....
As you can see, from 2nd chart onwards, on mouse hover, tool tips go out of place!!! Please note that, for child-svg, I've set the style overflow: visible without which tool-tips were not visible at all.
Want to know if I am missing anything in handling the attributes of child-svg elements or is it a bug in dimple.js. Also, please let me know if you know of any workaround.
Thanks.
One of the first questions I have is why do you want child svg elements? What are you trying to accomplish?
The only difference I see in your code and the example is the height / width swap at the top and the sub svg + bounds.
Keep in mind that the origin changes with each sub-svg. This might be why you are having trouble with the tool-tips. Maybe you have that worked into your add-bullet calls.
I think nagu has the right approach here if you really want separate svg elements.
I have a bar chart that is wider than the svg element but, with panning, you're able to drag left and right. The x-axis is time based (I use d3.time.scale()).
After building the chart, I'd like to be able to pan to a specific point on the x-axis. For example, the user may have already panned to a certain point and shut down their session - I'd like to put them back where they were when they return.
I've been looking at doing something like:
d3.selectAll('rect')
.attr('transform', 'translate(' + savedXaxisLocation + ',0)';
Is that the right idea? I'm assuming I also need to do that to the x axis itself?
As you can tell I'm feeling my way around this - I'd be happy to include any other code or screenshots if y'all feel it relevant.
In general, you would have a top-level g element that contains everything else and would translate that. This saves you from having to translate all the elements individually. When you do that, you may want to apply a clipPath to hide the elements that have been panned out of view.
This example should help you to get a better idea of what you can do and how.