How can i bring gridlines to the front? - d3.js

In d3 graphs, how can i bring gridlines to the front or back of the bars. Which parameter is responsible for the same?
Sample working fiddle
The code for ticks is:-
var yAxisGrid = yAxis.ticks(numberOfTicks)
.tickSize(w, 0)
.tickFormat("")
.orient("right");

There is nothing similar to the z index (http://www.w3schools.com/cssref/pr_pos_z-index.asp) in SVG.
So, your question:
Which parameter is responsible for the same?
Has the answer: none.
That being said, this is the rule: who's painted later remains on top (just like a real painter using ink in a canvas).
So, just move the code for the circles to be before the code for the gridline.
//create the circles
svg.selectAll("circle")
.data(dataset)
.enter()
.append("circle")
/)...
//draw axes here
svg.append("g")
.attr("class", "axis") //assign "axis" class
.attr("transform", "translate(0," + (h - padding) + ")")
.call(xAxis);
//...
This is your updated fiddle (I made the circles larger): http://jsfiddle.net/e4L7sn37/

Related

How to include additional lines between x-axis values using d3.js?

I created x axis with the values ​​and the labels and applied a style in grid lines. The code is below:
let xScale = d3.scalePoint().domain(axisXValues).range([0, width]);
let xAxisGenerator = axisXLabels.length > 0
? d3.axisBottom(xScale).ticks(axisXValues.length).tickFormat((d,i) => axisXLabels[i])
: d3.axisBottom(xScale).ticks(axisXValues.length);
chart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxisGenerator.tickSize(-height));
I would like to include more ticks between (green) the values ​​and apply a different style as in the example below:
Does anyone have an idea?
Thanks!
I would add a new linear scale with the same range and domain in the original point scale. (Keeping the original point scale and its rendered axis, of course)
Then calculate the values in between and plot the axis using axisBottom.tickValues()
Color of the tick line can be changed by accessing .tick line and applying the stroke attribute.
Do note that this would only work if the point scale's domain is equally spaced, i.e. linear.
Adding the following code to yours should work. Attaching a working codepen too.
const xScaleInBetween = d3.scaleLinear()
.range(xScale.range())
.domain(d3.extent(axisXValues));
let xTicks = xScale.domain();
let xTicksInBetween = Array.from({length: xTicks.length - 1},
(_, j) => ((xTicks[j] + xTicks[j+1]) /2));
chart.append("g")
.attr("class", "x-axis-between")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xScaleInBetween)
.tickValues(xTicksInBetween)
.tickSize(-height))
.call(g => g.selectAll('.tick line').attr('stroke', 'green'))
.call(g => g.selectAll('.tick text').remove())

How can i show the labels on the x axis when there is data overlap in d3js?

I am having a function that draws a stacked barchart . However the x axis labels overlap and make it unreadable . How can i fix this issue ?
I would be happy if i can show fewer number of ticks and labels if there are too many data.
You can access the project at https://angular-tqfk8f.stackblitz.io/
code can be accessed at
https://stackblitz.com/edit/angular-tqfk8f
really appreciate any help.
I don't think it would be nice to display all the values in smaller svg. You need to take a decision here. I can suggest you two ways:
You can create scrollable svg and display
Either don't display x axis values as you are showing on legend.
But if you still want to display you can create a custom logic of yourself like below:
You can use tickValues hook on x axis, and select which values you want to display. In my case i want to show 5 ticks.
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.transition()
.duration(1000)
.call(d3.axisBottom(x).tickValues(x.domain().filter((d, i) => {
const value = Math.floor(data.length/5)
return i % value === 0;})))
.selectAll("text")
.style("text-anchor", "middle")
.attr("dx", "3em")
.attr("dy", "1em")
.attr("transform", "rotate(30)");
Please find working code at - https://stackblitz.com/edit/angular-yry3au

D3 spacing between arcs

I am pretty new to D3 chart and I created my first donut chart using D3, but I was wondering if there is anyway I can put some padding/spacing between each arc.
I know I could reduce each arc's start and end angles, for example,
arc 1: from 90degree to 120degree
arc 2: from 120degree to 150degree
reduce the angles above like
arc 1: from 92degree to 118degree
arc 2: from 122 degree to 148degree
and so on..
but I am curious if there is any easier way to put some spacing.
Here's my code and you can see the full code in JSfiddle.
var vis = d3.select(elementSelector);
var arc = d3.svg.arc()
.innerRadius(svgInnerRadius)
.outerRadius(svgOuterRadius)
.startAngle(function(d){return anglePercentage(d[0]);})
.endAngle(function(d){return anglePercentage(d[1]);});
...
http://jsfiddle.net/24FaQ/
Thank you so much in advance.
This is actually what you're looking for:
http://bl.ocks.org/mbostock/f098d146315be4d1db52
var pie = d3.layout.pie()
.padAngle(.02);
If you're drawing on top of a solid background (white or otherwise), you can add stroke to achieve this effect without modifying the angles.
Here's a modified fiddle.
vis.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("d", arc)
.style("fill", function(d){return color(d[2]);})
.attr('stroke', '#fff') // <-- THIS
.attr('stroke-width', '6') // <-- THIS
.attr("transform", "translate(" + svgWidth / 2 + ", " + svgHeight / 2 + ")");
This applies the stroke to all the edges, including the curved ones. If you need to avoid that, the you have to instead draw and position lines with white strokes at the start/end of each slice.

simple multi line chart with D3

http://jsfiddle.net/ytvka/4/
I know this one has been asked before but I've not been able to use those examples to figure out what I'm doing wrong.
I want to create a simple 6 point, 3 series chart with data that looks like:
data = [
{"key":"D78","date":"2013-09-23T17:26:21.258Z","value":1.25},
{"key":"D78","date":"2013-09-23T17:28:21.258Z","value":2.25},
{"key":"R71","date":"2013-09-23T17:26:21.258Z","value":2.45},
{"key":"R71","date":"2013-09-23T17:28:21.258Z","value":2.85},
{"key":"X44","date":"2013-09-23T17:26:21.258Z","value":3.87},
{"key":"X44","date":"2013-09-23T17:28:21.258Z","value":3.87}
]
Nothing exciting there. What I'd ideally like to do is make a 3-series line chart out of this data.
svg = d3.select(selector).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom).append("g")
x = d3.time.scale().range([ 0, width ])
y = d3.scale.linear().range([ height, 0 ])
format = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ")
valueLine = d3.svg.line().interpolate("basis")
.x((d) ->
console.log format.parse(d.date)
x(format.parse(d.date))
)
.y((d) ->
console.log d.value
y d.value
)
svg.append("path").attr("class", "line")
.attr "d", valueLine(u.where(data, key: "X44"))
Which generates SVG: <path class="line" d="M137998238125800,-287L137998250125800,-287"></path>
This code just pulls out one of the series using lodash. Problem is: nothing on the screen. It runs through and grabs the value but there's no lines. I'm finding that existing examples are either complex and not well explained (http://bl.ocks.org/mbostock/3884955) or missing key parts (http://www.d3noob.org/2013/01/adding-more-than-one-line-to-graph-in.html).
What's wrong with my code?
How can I add in the other series (R71, D78)?
Is there a good tutorial of this out there that has complete code and walks through all the steps?
Your first point is at (137998238125800,-287) pixel coordinate, which is far away from the visible screen area. You don't use the selectAll/enter pattern which is at the core of D3. So you should start with this fundamental tutorial, then probably the code example you mention will make more sense:
var city = svg.selectAll(".city")
.data(cities)
.enter().append("g")
.attr("class", "city");
city.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { return color(d.name); });

d3 axis tick alignment

I have a d3 bar chart with, and the axis tick marks are centered below the bars (as I would expect). In this case, I would actually like to left align the axis ticks and have the ticks under the left edge of the bar. Is that possible?
EDIT: Javascript for constructing the axis
// note width is just the width of the chart
var xScale = d3.scale.ordinal().rangeRoundBands([0,width], .1);
var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
here is an example of left aligning the ticks.
http://bl.ocks.org/mbostock/6186172
the idea is that after you create the ticks you collect them and aligne them:
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll("text")
.attr("y", 6)
.attr("x", 6)
.style("text-anchor", "start");
Why not just create a new scale?
var padding = .1;
var axisScale = d3.scale.linear()
.domain([0, n])
.range([0 + padding, WIDTH + padding]);
Where n is the number of bars in your histogram.
I think that this should be adjusted when you add the axis to your graph.
Try (assuming your graph is called svg):
var bandSize = xScale.rangeBand();
svg.append("svg:g")
.attr("transform", "translate(-" + bandSize + "," + h + ")")
.call(xAxis)
.selectAll("text")
.style("text-anchor", "start")
.attr("transform", "translate(" + bandSize + ", 0)");
In my experiments, this shifts the ticks to the start of each band, and retains the text centered under each band.

Resources