Removing single elements of svg in d3.js - d3.js

I have the following code in d3.js
var svg = d3.select(".Canvas").append("svg").attr(
"width", width + margin.left + margin.right).attr("height",
height + margin.top + margin.bottom).append("g").attr(
"transform",
"translate(" + margin.left + "," + margin.top + ")");
svg.append("g").attr("class", "x axis").attr("transform",
"translate(0," + height + ")").call(xAxis);
svg.append("g").attr("class", "y axis").call(yAxisMajor).append("text")
.attr("transform", "rotate(-90)").attr("y", 6).attr("dy",
".71em").style("text-anchor", "end");
I tried the following to remove only the y-axis, not the whole svg:
d3.select(".Canvas").selectAll("svg").selectAll("g").select(".y axis").remove();
Why is the code not working?

Here is a little demo with a couple of simple ways to do it (see my comments in the fiddle).
d3.select("svg > g > #the_one_circle")
.transition().duration(1000)
.attr("r",1)
.remove();
Note how the svg and g elements are still there after removing the circle.

Because when you set class attribute as y axis , you actually set two classes. So in order to select and match both class names you need to call select with .y.axis. So that the result should be:
d3.select(".canvas").selectAll("svg").selectAll("g").select(".y.axis").remove();
at least worked for me, demo.

Related

D3 alignment of gridline for x and y axis

I am currently facing problem in setting grid line for a graph.
Problem
i) x grid line is not aligned to the x-axis
ii)y grid line is not appearing.
The code and output are in the
Plunker
Anyone can guide me on this? thanks in advance.
i) x grid line is not aligned to the x-axis
Reason:
You are doing like this
.attr("transform", "translate(0," + height + ")")
It should have been like this:
.attr("transform", "translate("+margin.left + "," + (height+ margin.top) + ")")
So you missed the margin left and margin top given to the graph, please add them as shown above.
ii)y grid line is not appearing.
Reason:
svg.append("g")
.attr("class", "grid")
.call(ygridlines <--- this is a function
.tickSize(-width)
.tickFormat("")
)
it should have been
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate("+margin.left + "," + (margin.top) + ")")
.call(ygridlines()
.tickSize(-width)
.tickFormat("")
)
Also you missed the transform for the y axis.
Working code here

Add brush on top of d3 barchart

I am trying to add a brush on top of a barchart in d3. Currently I am using barchart for my example:
https://bl.ocks.org/mbostock/1134768
This is the example of the brush that I want to implement: http://bl.ocks.org/mbostock/34f08d5e11952a80609169b7917d4172
I can only find examples where the bush is below the chart and not on the main chart itself. Can anyone explain to me how to put the brush on top of the barchart or point me in the direction of an example that I could follow?
In the Brush & Zoom example you are referring to, there are following lines:
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
...
svg.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(zoom);
These are specifying positions of the chart area, brush area and zoom area. You can just tweak margin and margin2 values which are specified at the beginning of the script, or explicitly set up a different transformation here.
You need to have margin.top > margin2.top, and tweak bottom margins too.

How can I split an ordinal axis in d3?

The following is my draw axis code:
var seasons = ["summer", "winter", "fall", "spring"];
var margin = {top:80, right:30, bottom:30, left:30},
width = 1200 - margin.right - margin.left,
height = 800 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.domain(seasons)
.rangeRoundBands([0, width], 0.9);
xAxis = d3.svg.axis()
.scale(x)
.tickSize(4, 6)
.tickPadding(6)
.orient("bottom");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
</script>
However, the tickPadding function does now introduce a space between the ordinal axis categories.
More specifically, I want that each of the summer, winter, fall and spring parts of the axis are separate from each other, sort of like dashed line. How can I get this?
I don't know of any way built into the d3 axis to accomplish this, but you can remove the path it draws and replace it with a dashed line, like so:
// Draw the axis, as you currently are
var axisElem = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Remove the line
axisElem.selectAll("path.domain").remove();
// Figure out how big each dash should be
var gapFraction = 0.1; // The portion of the line that should be a gap
var total = x(seasons[1]) - x(seasons[0]);
var dash = total * (1 - gapFraction);
var gap = total * gapFraction;
// Draw the dashed line
axisElem.append("line")
.classed("domain", true)
.attr("x1", x(seasons[0]) - dash / 2 + gap / 2)
.attr("x2", x(seasons[seasons.length - 1]) + dash / 2 - gap / 2)
.attr("y1", 0)
.attr("y2", 0)
.attr("stroke", "black")
.attr("stroke-dasharray", dash + "," + gap);

Updating line graph

I'm looking for the best way to update my line graph. The incoming data is not 'new', it's just switching between many different data sets. My issue is that .append('path') simply isn't working, and I'm not sure why. It may have to do with my grouping: I like to put margins around my graphs so axis and labels aren't clipped. To do this, my HTML looks like the following...
<svg w, h id='svg-container'>
<g translate(w - margin, h - margin) id='chart-container'>
<g id='x-axis'>
<g id='y-axis'>
In my code I would like to select chart-container and append a <path d='...' id='line'>. Later, when updating the graph, I would hope to be able to simply select('chart-container').select('path') and update that selection.
Initial setup of the chart:
var svgContainer = d3.select(element[0]).append('svg')
.attr({
width: width + margin.left + margin.right,
height: height + margin.top + margin.bottom
})
.classed('svg-container', true);
var chartContainer = svgContainer.append('g')
.classed('chart-container', true)
.attr('transform', "translate(" + margin.left + "," + margin.top + ")");
chartContainer.append('path')
.data(activeData)
.attr('d', lineFunc)
.attr('stroke', 'blue')
.attr('stroke-width',
.attr('fill', 'none');
Update the chart later on:
svgContainer = d3.select('#line-container').select('.svg-container')
.attr({
width: width + margin.left + margin.right,
height: height + margin.top + margin.bottom
});
chartContainer = svgContainer.select('.chart-container')
.attr('transform', "translate(" + margin.left + "," + margin.top + ")");
chartContainer.select('path')
.data(activeData)
.attr('d', lineFunc)
.attr('stroke', 'blue')
.attr('stroke-width',
.attr('fill', 'none');
Unfortunately this doesn't work, and I'm not sure why. The initial chartContainer.append('path') seem to be working (sometimes), and the chartContainer.select('path') doesn't actually return the correct item (othertimes). Might d3 be traversing my axis groups and returning one of their paths? Am I going about this the wrong way?
You don't show us your complete code, but from your description it sounds as if you may be selecting the wrong path. One way around this is to assign a special class to the path you want and select accordingly.
chartContainer.append("path")
.attr("class", "chart");
chartContainer.select("path.chart");
The other problem is that you can't really use .data() to update the data bound to the DOM element like you're using it. Use .datum() instead.
chartContainer.select('path')
.datum(activeData);

font size is not working in my d3.js code

i am writing d3.js for generating many charts and graphs.. but when there is no data i am just appending svg a text and writting "no data to display" and assigning some attributes like x y dy etc.. similarly font-size but except font size every thing is working .
why? here is my code
var svg = d3.select(selector).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
if (!data.IssueTrendsDAO.issueTrendList) {
svg.append("text")
.attr("font-size","34px")
.attr("y", 79)
.attr("x", 40)
.attr("dy", ".47em")
.style("text-anchor", "start")
.style("fill", "#004669")
.style("font-weight", "bold")
.text("No data to display");
}
I think you'll find it works if you assign font-size as a style rather than as an attribute.
.style("font-size", "34px")
(better yet, assign an id or class attribute and set all your styles in CSS)

Resources