d3 axis orientation: center - d3.js

in D3, how can I put an axis in the middle, or center, of a graph? The documentation says "only top/bottom/left/right".
I know the dimensions of my graph, let's say it is 400px by 400px. In Protovis I used
vis.add(pv.Rule).bottom(200)
placing an axis 200px up from the bottom. How can I do this in D3?

You can transform the axes whichever way you want. The orientation only refers to which side the ticks and numbers are placed on.
See e.g. http://alignedleft.com/tutorials/d3/axes/
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
where you just need to change the parameter to the transform to get whatever you want.

Related

DC chart heatmap columns text rotation doesn't work [duplicate]

I am new to d3 and svg coding and am looking for a way to rotate text on the xAxis of a chart. My problem is that typically the xAxis titles are longer than the bars in the bar chart are wide. So I'm looking to rotate the text to run vertically (rather than horizontally) beneath the xAxis.
I've tried adding the transform attribute:
.attr("transform", "rotate(180)")
But when I do that, the text disappears altogether. I've tried increasing the height of the svg canvas, but still was unable to view the text.
Any thoughts on what I'm doing wrong would be great. Do I need to also adjust the x and y positions? And, if so, by how much (hard to troubleshoot when I can see it in Firebug).
If you set a transform of rotate(180), it rotates the element relative to the origin, not relative to the text anchor. So, if your text elements also have an x and y attribute set to position them, it’s quite likely that you’ve rotated the text off-screen. For example, if you tried,
<text x="200" y="100" transform="rotate(180)">Hello!</text>
the text anchor would be at ⟨-200,100⟩. If you want the text anchor to stay at ⟨200,100⟩, then you can use the transform to position the text before rotating it, thereby changing the origin.
<text transform="translate(200,100)rotate(180)">Hello!</text>
Another option is to use the optional cx and cy arguments to SVG’s rotate transform, so that you can specify the origin of rotation. This ends up being a bit redundant, but for completeness, it looks like this:
<text x="200" y="100" transform="rotate(180,200,100)">Hello World!</text>
Shamelessly plucked from elsewhere, all credit to author.
margin included only to show the bottom margin should be increased.
var margin = {top: 30, right: 40, bottom: 50, left: 50},
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".15em")
.attr("transform", "rotate(-65)");
One problem with this rotating D3 axis labels is that you have to re-apply this logic each time you render the axis. This is because you do not have access to the enter-update-exit selections that the axis uses to render the ticks and labels.
d3fc is a component library that has a decorate pattern allowing you to gain access to the underling data join used by components.
It has a drop-in replacement for the D3 axis, where axis label rotation is performed as follows:
var axis = fc.axisBottom()
.scale(scaleBand)
.decorate(function(s) {
s.enter()
.select('text')
.style('text-anchor', 'start')
.attr('transform', 'rotate(45 -10 10)');
});
Notice that the rotation is only applied on the enter selection.
You can see some other possible uses for this pattern on the axis documentation page.

Separately controlling positioning of y-axis line and y-axis labels

I am creating a bar chart using d3. The bar chart accepts negative values. The chart I am creating is based on this chart here, and mostly have similar setup.
The change I like to make is shift the text labels of the y-axis to the absolute left of the chart, but keep the y-axis line at its original spot.
From the above link, the following are the lines of code to render the y-axis (they are at the bottom of the page, almost the last thing of the code)
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + x(0) + ",0)")
.call(yAxis);
Now, if I adjust the above translate line to the following
.attr("transform", "translate(0,0)")
then BOTH the axis line AND the labels will be left aligned. I would like to keep the axis line at its position but move all the labels to the left.
How can I do that?
PS. A solution I thought about is to create second y-axis. The first y-axis is hidden with the labels shown, and is displayed to the left. The second y-axis is shown, but the labels are hidden, and is at the center. However, I do not like this solution, I do not think it is very clean.
Thanks.
Just increase the tick padding:
.tickPadding(width/2 - margin.left);

How can I add axis labels to a sankey diagram in d3?

I want to add axis on a sankey diagram. The code for the chart can be found in the following links: https://github.com/irbp005/d3SankeyAndLineInteraction
The visual representation of the char is as follows:
Ans I want to add labels like:
Basically in both sides of the y axis. Any ideas on how can I achieve this?
This should be fairly straightforward. Add a g element for each side and apply a translation transform to position it in the x axis and then use something along the lines of this:
selection.append("text")
.attr("class", "axis-label")
.attr("transform", "rotate(-90)")
.attr("y", -50)
.attr("x", -height/2)
.attr("fill", "#000")
.style("text-anchor", "middle")
.text("Y Label");
Look through the 1st example in Chapter 1 here that explains the addition of X and Y labels to the plot axes:
https://leanpub.com/d3-t-and-t-v4/read

How to align and resize chart in viewBox

I am trying to make a treemap responsive, however, the chart simply drifts off to the left, and to the bottom. As if there is something affecting x0 and y0. The chart does not respond to resizing, however I think this may have something to do with the width and heights... possibly affecting the position of the chart also. Or, is this simply a CSS issue? Very confused with this one. I imagine I am missing something obvious...
Plnkr: https://plnkr.co/edit/U7Zsbjy0zubnMwo1SHg8?p=preview
var svg = d3.select("#graph")
.append("svg")
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.attr('style', 'border:solid 2px blue')
.attr('style', 'padding0px')
.call(responsivefy)
At line 156 you are doing
var newNode = node.enter()
.append("g")
.attr("class", "node");
.attr("transform", "translate("+[fullWidth/2, fullHeight/2]+")")
The last line of that code block is why everything ends up bottom right, you are translating every group to start from the middle of the chart (instead of top left). If you remove it the chart looks ok. Here's your chart with that edited : https://plnkr.co/edit/RUhlH4rwopNKf4iDiUge?p=preview
As for making it responsive, you already set the viewbox attribute on the SVG to make it responsive. You don't need that extra function responsivefy on top of it. You seem like you used this answer for the responsive classes : https://stackoverflow.com/a/25978286/11487 but the order of the nodes in your markup was not quite there.
One thing that's important to note : when you use preserveAspectRatio with "xMinYMin meet" to get a responsive graph, you cannot use width and height instructions.
With that fixed up :
https://plnkr.co/edit/KADSH9GSX1E3lnpmhzjV?p=preview

How to create Stacked Line Chart D3, Multiple Y Axis and common X Axis

I am triying to create a line chart which will have multiple y axis but a common x axis using d3, can somebod provide me the example how to create it with D3 library. It should be something like as shown below
Quite simply: Just draw 2 charts but only append one x-axis, here's a fiddle to get you started: http://jsfiddle.net/henbox/fg18eru3/1/
In this example, I've assumed that the two different datasets have different y-domains but the same x-domain. If that's not the case, you should just get the max and min from the combined x-domains of both sets.
If you start by defining 2 g elements that will contain the two charts, and transforming the bottom chart down so they don't overlap:
var topchart = svg.append("g").attr("class", "topchart");
var bottomchart = svg.append("g").attr("class", "bottomchart")
.attr("transform", "translate(0," + height/2 + ")");
... then append the path and y-axis to the appropriate g, but only add the x-axis to the bottom chart:
bottomchart.append("g")
.attr("class", "axis x-axis")
.attr("transform", "translate(0," + (height/2 - padding) + ")")
.call(xAxis);

Resources