How to get x coordinate for each of the bar in recharts? - recharts

In this example graph, I am trying to implement a vertical reference line on hover for each of the bars, but based on the Xaxis with id=1 and type number, so that it corresponds to the ticks of the Xaxis with id=0 and type category. Further I want to have several grouped bars per each page (e.g. 5 bars on Page A, 5 bars on Page B, etc.), thus I can't rely on tick value on categorical Xaxis and need to know x coordinate of each bar to implement reference line.
In the example code, you can see that my reference line is displayed inaccurately, even though I am using x value from the onMouseMove event.
How can I get the accurate X coordinate for the middle point of each of the bar in recharts, so that I can display my reference line accurately?

Related

Alignment and Colors of Data Point Outliers of Box Plot

Is it possible to align the data points and outliers of box plot in one straight line like in center of box plot?
Additionally, can I color the data points?
The current and the desired screen shot are attached with it.
You can use
.dataWidthPortion(0)
to not spread the points out at all. Documentation.
General advice on changing the color or style of anything, if there is no accessor for it:
Look for the chart in the chart selectors wiki, or if it's not there, inspect the item you want to change in the developer tools and find out what SVG tag and CSS class the item has. In this case, it's circle.data
Add a pretransition handler which selects the items you want, and changes them:
var cc = d3.scaleOrdinal().range(d3.schemeDark2);
bp02.on('pretransition', chart => {
chart.selectAll('circle.data').attr('fill', function(d) {
const boxDatum = d3.select(this.parentNode).datum();
return cc(boxDatum.value[d]);
})
});
In this case, we're creating an ordinal scale to map the available data to the colors in a color scheme.
The interesting question is here is what data to bind to the color of the dots, and how to get that data.
A box plot's data consists of an array of key/value pairs where each value is a Y value. When the box plot draws it will bind each circle.dot element to the index of the data in the array.
So we need to get the array that is bound to the box. Luckily d3.select(this.parentNode).datum() will give us the key/value pair for the box.
For this example, we are encoding the color based on the Y value, which we get by looking inside boxDatum.value. You don't specify how you want the dots colored but this shows the data that is available.

After effects: how to make a text follow top of animated bar in bar chart

I want to animate a horizontal bar chart. The bars (squares) start at zero and grow within two easy-ease keyframes from 0 to a specific value. This value is displayed in a text layer. I have set up a slider which goes from zero to the specific value and controls both the text layer (value) and the size of the bar (width of square).
Problem: I want the value to follow the top of the bar chart as in here:
https://www.instagram.com/p/B7_5SOQFrW6/?utm_source=ig_web_copy_link
I tried to set easy-ease keyframes for the text layer too and adjust the values in the diagram editor. Result was too shaky and not nice to look at. Is there a solution with expressions?
source text of text layer for first Bar (1):
Math.round(thisComp.layer("controler").effect("1")("slider"))
source for square (first bar):
temp = thisComp.layer("controler").effect("1")("slider");
he_ = thisComp.layer("controler").effect("height")("slider");
[temp,wi_]
info: width is a slider with which I control the height of the bars.
Check this sample project, with both vertical and horizontal bars: https://url.io/ae_barchart
You can use sourceRectAtTime (like in the sample project), or calculate the position of the top side of your bar, knowing it's height and bottom Y coordinate and then translate it into Composition space from the bar layer`s space, so you can apply it to your Text Layer position.
If you check the position property of "bar_horizontal_text" / "bar_vertical_text" layers you'll see what I mean.
The rest of the setup is extra... just "fooling around". :-)

Is it possible to change the x scale of a rowchart to sqrt?

I want to change the scale of the x axis of a row chart because some values are close to 0 but others are over 100000. I have tried this:
chart.x([d3.scaleSqrt().domain([0, 75000]).clamp(true)])
but it doesn't work.
However, this same method does work with a barchart. Any suggestions of how I can solve this?
EDIT: What I meant by 'it doesn't work' is that it shows the rowchart but the x axis is what comes by default, so there is no rescaling of the axis.
First off, you've got an extra set of brackets - that should be
chart.x(d3.scaleSqrt().domain([0, 75000]).clamp(true))
Since you don't say what didn't work, I will guess that you got a "squished" chart.
Here is what I got when I first tried this:
Unlike other dc.js charts, the row chart will not set the range of the X scale when the scale is passed in by the user.
For other charts, dc.js will initialize the range based on the "effective width" - the width of the chart minus the left and right margins.
We can do the same:
chart.x(d3.scaleSqrt()
.domain([0, 75000])
.range([0,chart.effectiveWidth()])
.clamp(true)])
My example now looks like

Chart-like object (but not a gantt or stacked bar chart) in d3 -- where to start?

I have a chart I've created in excel that I'd like to replicate in d3, but I'm not sure where I should begin.
It's intended to show which character is speaking at which moment during a play, and so it visually looks similar to a gantt chart or stacked bar chart but it isn't working off of time the way a gantt chart would. Am I right in thinking that it'd be a bar chart or series of bar charts? Could I build it up by a series of 1 pixel wide bars, so that each pixel would equal a line in the play?
I'd provide code but I tried to modify the standard stacked bar chart and all I've really been able to do is either make the whole thing blank or modify the canvas dimensions. So I'd appreciate some suggestions to get me started.
it seems to me that the only (and big!) trouble you'll have here is creating the JSON. Once you have the JSON, it will be a piece of cake! Here is what I thought:
Create a very big JSON that is just 1 big array of hundreds of objects. Each object would be like this:
{"character": "John Doe", "place": "tavern", "duration": 5}
Then, you'll append the narrow rectangles using an ordinal scale for the places ("place") on y axis, setting the x position according to the cumulative duration of previous speeches and setting the width using the duration of each speech, and using CSS you can color the bars according to the character (using character for setting the class).
For this, you would use D3 only for the scales, avoiding the typical selection().data().enter().append() pattern and appending each rectangle in a for loop. Let me explain. Suppose you put your JSON in a variable named data. Then, you do:
for (var i = 0; i < data.length; i++){
var speech = data[i]
//rest of the code
}
This allow you, for each loop, to know the y position of the bar using speech.place, the name of the character using speech.character, for the colors, and the duration of the line using speech.duration. For calculating the x position, you declare a var duration; outside the loop and, inside it, you write:
duration += speech.duration;
In this approach, once you would use the cumulative duration for x position, the objects in the array must to be in the exact chronological order of the play.
PS: D3 is so nice that you can create an additional value named "line", for each object, with the actual line spoken by the character, and when the user hover over the rectangle he/she will see the text of the speech!

D3.js: Mouse over between grid lines

I am creating a line chart with grid lines. Here's the similar example: http://bl.ocks.org/hunzy/11110940
I need to change the background of vertical space between X(2) to X(4), X(8) to X(10) and X(12) to X(14) on mouse hover. But I am not able to understand how to use D3 to reference those spaces between the grid lines.
There is nothing there to click on/hover over. The normal axis/grid creates lines, not rectangles. You would need to change the default behave of the axis objects to create "invisible, but clickable" rectangles in order to be able to attach a mouse event to those spaces.
I don't know if this is the recommended approach but it seems like it could work. After the axis has been created:
something
.attr('class','xaxis')
.call(xAxis)
You could select the ticks with something like this:
d3.select(svg).select('.xaxis g.tick').each(function(){
// this.transform will be "translate(X,Y)"
})
In the function you can query the existing properties of the g elements and extract the transform attribute which will contain the X and Y offset for the "tick". This can be used to determine one dimension of your rectangle objects. The other dimension is determined by the size of the other axis or something like that.

Resources