I have this code:
y.domain([-arr2, arr2]).nice();
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("x", 150)
.attr("y", -10)
.attr("dy", ".71em")
.style("text-anchor", "end")
.attr("font-family", "sans-serif")
.attr("font-size", "34px")
.text("log(Lev)");
This is the graph with Y axis created by this code:
As you can see, Y axis have a negative portion (0 <--> -25) bellow X axis,
i whould like to change negative Y axis domain to be positive.
So i get something like:
You can use:
yAxis = Math.abs(yAxis);
You want to use a custom render for the axis labels. You can do it with yAxis.tickFormat(function(v){ return String(Math.abs(v)); }) (github.com/mbostock/d3/wiki/SVG-Axes#wiki-tickFormat) – Prusse 10 mins ago
Related
Is there a way to justify the text in the X axis to the left? I've tried with .attr("text-anchor", "middle") .attr("text-anchor", "end") .attr("text-anchor", "start") but nothing works, I also tried with css but nothing works.
this is how my X axis looks like
and this is the part of the code that ads the x labels
// Add X axis
var x = d3.scaleBand()
.domain(groups)
.range([0, width])
.padding([0.5]);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll("text")
.attr("text-anchor", "middle")
.attr("font-size", "55px")
.attr("y", "-7")
.attr("x", "-45")
.attr("transform", "rotate(-90)");
I don't know if I understood your question properly but it seems you want the x axis text closest to the axis itself am I right?
If that's the question I think your problem is related to the text-anchor atribute.
I would sugest writing .style instead of .attr so the code would look something like this:
.style("text-anchor", "end")
I'll provide this link for you to read so you can understand a bit more how to fix the axis problem and I hope it helps.
If it doesn't work, please let me know.
I want to append x-axis text label and rotate the x axis labels.
Both works individually but I cant figure out how to use them both together.Can someone please help.
g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll("text") // either this
.style("text-anchor", "end")
.attr("dx", "-.8em")
.attr("dy", ".1em")
.attr("transform", "rotate(-65)")
.append("text")// or this
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.style("font-weight", "bold")
.style("fill", "black")
.text(tooltipTxt);
I'm confused about how to save a D3 selection for later use. In the code below, I have a "global" variable for my axes, to which I save them when they are first created. Later, I'm able to use this variable for certain things (here, setting some text) but not others (here, updating the scale), which only work if I explicitly (re)select the axes.
Is there perhaps something about JavaScript variable scoping or lifetime that I don't understand? Any assistance is appreciated!
The relevant code, much condensed from the full context:
// Top level of page
var gxaxis, gyaxis;
var updatePlot = function (view, first) {
d3.csv("data.csv", function (error, data) {
data.forEach(function (d) {
...
});
var x, y;
x = d3.scale.linear().range(...);
y = d3.scale.linear().range(...);
x.domain(d3.extent(data, function (d) {...})).nice();
y.domain(d3.extent(data, function (d) {...})).nice();
var xAxis = d3.svg.axis().scale(x).orient("bottom");
var yAxis = d3.svg.axis().scale(y).orient("left");
// The variable 'first' is true on page load, so this code the if clause will be executed before any executions of the else clause
if (first) {
gxaxis = svg.append("g").attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end");
gyaxis = svg.append("g").attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end");
} else {
// Why is it necessary to explicitly select; why can't I use my gxaxis variable (as I do below for the text)?
svg.select(".x.axis")
.transition().duration(0).ease("in")
.call(xAxis);
// Using gyaxis.transition()... has NO EFFECT
svg.select(".y.axis")
.transition().duration(0).ease("in")
.call(yAxis);
}
var xLabel = ...;
var yLabel = ...;
// This use of gxaxis works.
gxaxis.text(xLabel);
gyaxis.text(yLabel);
});
};
// Set up handlers for switching among views
d3.selectAll(".view-select").on("click", function () {
d3.event.preventDefault();
updatePlot(this.id, false);
});
updatePlot('a', true);
This code:
gxaxis = svg.append("g").attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end");
Creates this DOM:
<svg>
<...>
<g class="x axis">
<g class="tick">
<line ...>
<text ...>
</g>
</g>
</...>
</svg>
And saves the text to the selection, because it was appended last.
If you want the axis, save the axis to the selection before you edit the text.
gxaxis = svg.append("g").attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
gxaxis.selectAll("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end");
I'm trying to draw an x-axis label for one of my d3 graphs, and I'm having a lot of trouble positioning it below the axis itself. Here is my current code:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", (width / 2))
.style("text-anchor", "middle")
.text("Users ordered by contribution");
And here is a screenshot of the problem. Is there a quick fix?
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", (width / 2))
.attr("y", height) //set your y attribute here
.style("text-anchor", "middle")
.text("Users ordered by contribution");
You can set your y position attribute for your svg text as per above
I'm trying to make a scatter plot with two sets of data from two tsv files. However, each one shares the x-axis with single scale. There are two y-axis each with their own scale. The graph I have right now will help visually.
Problem is, the 2nd data set (in orange) only plots partially as seen as a smudge at about 15,000 on the a-axis. it should really be a much larger line. Also, when I run this, sometimes the 2nd data set renders and the first does now. Not sure why this is happening..
Here are the two (likely) relevant blocks of code:
//1st data set
d3.tsv("datatest4.tsv", function(error, tsv1) {
tsv1.forEach(function(d) {
d.altit = +d.altit;
d.tmp = +d.tmp;
});
x.domain(d3.extent(tsv1, function(d) { return d.altit; })).nice();
y.domain(d3.extent(tsv1, function(d) { return d.tmp; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.style("text-anchor", "end")
.text("Altitude (m)");
svg.append("g")
.attr("class", "y axis axis1")
.call(yAxis)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end");
svg.selectAll(".dot")
.data(tsv1)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 1)
.attr("cx", function(d) { return x(d.altit); })
.attr("cy", function(d) { return y(d.tmp); })
.style("fill","steelblue");
});
and
//2nd data set
d3.tsv("datatest2.tsv", function(error, tsv2) {
tsv2.forEach(function(dd) {
dd.alti = +dd.alti;
dd.pressure = +dd.pressure;
});
x2.domain(d3.extent(tsv2, function(dd) { return dd.alti; })).nice();
y2.domain(d3.extent(tsv2, function(dd) { return dd.pressure; })).nice();
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis2)
.attr("x", width)
.attr("y", -6)
.text("Altitude (m)");
svg.append("g")
.attr("class", "y axis axis2")
.call(yAxis2)
.append("text")
.attr("class", "label")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end");
svg.selectAll(".dot")
.data(tsv2)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 1)
.attr("cx", function(dd) { return x2(dd.alti); })
.attr("cy", function(dd) { return y2(dd.pressure); })
.style("fill","orange");
});
The problem is that you're using the same selector, svg.selectAll(".dot"), for each dataset .data(tsv1) and .data(tsv2).
D3 thinks that the 2nd set is supposed to replace the first. You can fix it by assigning a unique class to each type of dot.
svg.selectAll(".blue.dot")// Select specifically blue dots
.data(tsv1)
.enter().append("circle")
.attr("class", "blue dot")// Assign two classes
...
svg.selectAll(".orange.dot")
.data(tsv2)
.enter().append("circle")
.attr("class", "orange dot")
...