redrawing axis in d3.js - javascript

I am implementing parallel coordinates chart dragging using d3.js
I draw my x-axis with the following code
var xAxis = d3.svg.axis().orient("bottom").scale(xScale);
svg.append("g").attr("class", "axis").attr("transform", "translate(" + 0 + " ," + Y_SCALE + ")").call(xAxis);
When I drag one of the x-axis, I can re-draw x-axis using the same code in the "on("dragend"...) event, but I don't know how to hide the previous one.
Can you please let me know how to hide the previous x-axis or do something more intelligent?

Related

d3js Star Chart - responsive legend

I am working on a d3.js chart - This current model creates a legend segment as a g element. I'd like to ensure the legend stacks below if there is not enough room in the container.
//desktop - ample space
//mobile - not enough space
I've cleaned up the legend part -- you able to clean up the code base and add some more comments here. One of the old features I had - is if there wasn't enough room in the chart the legend stacks underneath - like responsive design - I used to create 2 svg parts but apparently with d3 it should only be 1 svg - http://jsfiddle.net/h066yn5u/13/
see if the chart can be more dynamic with different sizes - I think I had to add a padding of 10 to the radius to give it a little gap between the edges.. maybe though its a case of adding a transform on the svg itself to add that padding
var arcchart = chart.append("g")
.attr("class", "starchart")
.attr("transform", "translate("+(r+10)+"," + h / 2 + ")");
var legend = chart.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + ((r + 10) * 2) + "," + (h / 4) + ")");
a version where it splits the chart into two svgs
http://jsfiddle.net/h066yn5u/14/
There are multiple ways to solve this issue.
Split into 2 svg containers: d3.js is not bound to just one svg container. You can split up the legend and the chart into 2 seperate svg containers and let the HTML handle the flow of the page
Use foreignObject: If you don't want to do that. You can try to use tag. Remember, that this is not supported by ie11 (and edge either afaik)
Calculate everything by hand: calculate the width of your legend (and including text), the width of the chart and get the available width for your whole container. If the whole container width is too small, push the legend below and of course adjust the svg height and width accordingly.

How can I implement 2 x axis in D3 version 4

I'm trying to implement two x axis (Major and minor axis) using D3.
I already have both of them been displayed, but my second axis is not displayng the domain properly.
Here's the code on codepen: http://codepen.io/wendelcosta/pen/QpzzgJ
g.append("g")
.attr("class", "axis axis--x2")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x2));
I need to display the days for the months as minor ticks in between the major ticks (Months), it should looks like the following image.
Click Here for Image Preview
You should use two time scales for the x axis.
In the "day" axis, you can set the axis generator using d3.timeDay:
call(d3.axisBottom(x2)
.ticks(d3.timeDay.every(6))
.tickFormat(d => d3.timeFormat("%d")(d)));
And in the "month" axis, you increase the tick size:
call(d3.axisBottom(x)
.tickSizeInner(20)
.tickFormat(d3.timeFormat("%b %y")));
Here is your updated codepen: http://codepen.io/anon/pen/bqOPRg?editors=0010
I'm printing just one on every 6 days, still the "day" axis is terribly crowded. Now it's up to you reducing the text size or reducing the number of ticks.
EDIT: Since OP asked in the comments to show only values present in the data array, here is another CodePen: http://codepen.io/anon/pen/qrvdWq?editors=0010

D3 adding interval on X axis

Trying to get intervals on the X axis. The X axis should display the 1st of every month(1st Jan, 1st Feb, etc). Also looking at how to zoom in the chart to show the days (1-31 Jan). So far i've got a brush only to work as i'm still new to creating bar charts in D3.
var brush = d3.svg.brush()
.x(x)
.on('brush', bListener);
var gBrush = svg.select('g.brush').call(brush);
gBrush.selectAll('rect')
.attr('height', height - margin.top - margin.bottom)
.style("opacity", 0.5)
.style("fill", ""grey");
Looking to create something like this but as a bar chart in D3, http://www.highcharts.com/demo/line-time-series.
Here's https://jsfiddle.net/noobiecode/wck4ur9d/4/
Any help would be appreciated.
Partial answer:
How to display the 1st of every month(1st Jan, 1st Feb, etc):
In your xAxis instead of this:
.ticks(d3.time.days, 1)
do this:
.ticks(d3.time.months)
working fiddle here
Regarding brushing i didn't see any examples, may be you need to write it on your own :(

Adding text to the center of a D3 Donut Graph

Fiddle
I am trying to insert basically a label to the center of a donut graph using D3. I was able to work with an existing code I found and manipulate it so all the slices of the graph mesh in the middle to appear like there is a label there, but I think it'd be a better idea just to figure out how to make it a more permanent home in the center. I am very new to JS and D3.
Any help is grealty appreciated.
Thank you
This is currently the code that is falsifying a label being in the center.
svg.selectAll("text").data(pie(data)).enter()
.append("text")
.attr("class","label1")
.attr("transform", function(d) {
var dist=radius-120;
var winkel=(d.startAngle+d.endAngle)/2;
var x=dist*Math.sin(winkel)-4;
var y=-dist*Math.cos(winkel)-4;
return "translate(" + x + "," + y + ")";
})
You can simplify your code quite a bit. Since you are already centering the pie chart:
var svg = d3.select("#svgContent").append("svg")
.attr("width",width)
.attr("height",height)
.append("g")
.attr("transform","translate("+width/2+","+height/2+")");
You can just add the text as follows:
svg.append("text")
.attr("text-anchor", "middle")
.text("$" + totalValue);
Note that since you are only adding one <text>, you don't need to bind any data to it, and can pass .text(...) a value directly instead of a function.

How to zoom in/out d3.time.scale without scaling other shapes bound to timeline

http://jsfiddle.net/HF57g/ is an example of a single event(blue rect) placed on the timeline. If i zoom into the timeline, rect's placement on the x axis changes in harmony with the ticks on axis. but at the same time, rect is scaled horizontally.
if i modify the following section of the code
svg.selectAll(".item").attr("transform", "translate(" + d3.event.translate[0]+", 0)scale(" + d3.event.scale+", 1)");
to
svg.selectAll(".item").attr("transform", "translate(" + d3.event.translate[0]+", 0)scale(1, 1)");
as in http://jsfiddle.net/HF57g/1/ to disable horizontal scaling, then the rect's position changes much more than the axis' during zoom in/out.
How can i zoom in/out time.scale without scaling other related shapes?
I ended up adding an update function to rearrange the rects' places depending on the new positions returned by scale(x).
function update_events(){
return svg.selectAll("rect.item")
.attr("x", function(d){return scale(d);})
}
Here's the final version: http://jsfiddle.net/HF57g/2/

Categories