I'm coding a dimple based bubble chart, which for some z-values removes a bubble and draws a big red X instead, which is an svg path created by line interpolation like this:
var points = [{"x":x-edgeSize,"y":y+edgeSize},
{"x":x,"y":y},
{"x":x+edgeSize,"y":y-edgeSize},
{"x":x,"y":y},
{"x":x-edgeSize,"y":y-edgeSize},
{"x":x,"y":y},
{"x":x+edgeSize,"y":y+edgeSize},
{"x":x,"y":y}];
var lineFunction = d3.svg.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; })
.interpolate("linear");
var path = graphSelection.append("path").attr("d",lineFunction(points))
.attr("stroke",color)
.attr("stroke-width",lineWidth);
Now, I want it to be responsive and I followed dimple's example for responsive charts:
Dimple - Responsive sizing and now all the sizes and bounds are by % and I'm calling draw on resize:
this.chart.draw(this.delay,true);
The problem is that the red Xs don't move by themselves, obviously.
So I tried to move it independently on resize, but I don't know the right coordinates until the transition ends - which makes it a 2 step transition.
Will adding the X-path to series.shapes help? will it move along with the other bubbles?
Is there a standard way of doing this?
Thanks
Related
I am creating a leaflet map with popup d3 barplots that are tied to specific geographic points. I am using this code to create the leaflet popups (but with my own data): http://bl.ocks.org/Andrew-Reid/11602fac1ea66c2a6d7f78067b2deddb
I want to be able to add a fixed horizontal line (which will represent a threshold in that data), something like this. I added a fixed line to the code (after this other post):
var lineEnd = 90;
var line = svg.append("line")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", function(){ return y(lineEnd)})
.attr("y2", function(){ return y(lineEnd)})
.attr("stroke-width", 2)
.attr("stroke", "black");
But in the output on my leaflet map, the line seems to appear at arbitrary points on the graphs. Does anyone have any ideas of what I might need to change in the original code to be able to add this horizontal line?
One thing I noticed is that you add your line to the svg directly
But the bars are added to a group element that is translated
var g = svg.append("g")
.attr("transform","translate("+[margin.left,margin.top]+")");
What if you add the line to that group element instead, does it appear in the right place?
I've completed a bar graph codepen showing US GDP (the popular one from FCC).
https://codepen.io/le-hu/pen/Baoywgd
The problem i can't eradicate is such - the graph does not start at bottom padding 50units above svg bottom, but instead spans to the border and even goes below svg border i believe. I've tried changing every setting. My bet is something's wrong with the yScale domain, or range property.
const yScale = d3.scaleLinear()
.domain([0,
d3.max(data.data, d => d[1])])
.range([height - padding, padding]);
Code seams to be ignoring the height - padding part in range setting. (or my understanding of it)
I'd like the graph to start on the line the x axis we have, the one showing dates in years 1950+.
Just like in the original:
https://codepen.io/freeCodeCamp/pen/GrZVaM
thank you for any insight!
Mehdi's solution worked like a charm - thank you very much for your time!
In SVG, the vertical coordinates go from top to bottom(reference).
This makes the reasoning about the y coordinate and height of a vertical bar in a bar chart less straightforward.
The tutorial Let's make a bar chart, part 4 explains how to perform this.
the y position of the rectangle has correctly been set tothe one of the value d[1]:
.attr("y", (d, i) => yScale(d[1]))
The height of the rectangle is incorrect, though. It should be the distance between origin (value 0) and position of the value d[1]. As shown below:
.attr("height", (d, i) => yScale(0)- yScale(d[1]))
I am new to d3v4 and working on a chart where i need to show little rectangle on certain date matching to its title on yaxis. The problem i am facing is rectangles in the chart area not drawing equal to the yaxis point labels, i have tried changing the y value by hardcoding, it works fine but the point is the number of data object will change in real time like it could be any number of objects in an array. Here is the plunker
To draw the graph dynamically with limited data objects i've created few buttons on top of chart so that rectangles in the chart can draw equal to y-axis labels.
Any help is much appreciated.
You are using a band scale: that being the case, you should not change the y position, which should be just...
.attr('y', function(d) {
return yScale(d.title);
})
.. and you should not hardcode the height: use the bandwidth() instead:
.attr('height', yScale.bandwidth())
The issue now is setting the paddingInner and paddingOuter of the scale until you have the desired result. For instance:
var yScale = d3.scaleBand().domain(data.map(function(d) {
return d.title
}))
.range([height - 20, 0])
.paddingInner(0.75)
.paddingOuter(.2);
Here is the plunker with those changes: https://plnkr.co/edit/ZxGCeDGYwDGzUCYiSztQ?p=preview
However, if you still want (for whatever reason) hardcode the height or the width of the rectangles, use a point scale instead, and move the y position by half the height.
Hello I am trying to create an area chart with d3 and am trying to match d3's generated coordinates with a d3.symbolCircle.
This is what I have:
https://codepen.io/anon/pen/bozoQa
You will notice that in the current state the dots do not match the generated lines.
The reason for that is because of line 133.
const area = d3.area()
.x((d, i) => xScale(data.xAxis.categories[i]))
.y0(viewModel.height)
.y1((d) => yScale(d))
.curve(d3.curveBasis)
This creates the area as curved instead of a straight line. If I remove that the dots would match and it would work but I need this chart to have curved lines.
Taking this into consideration how can I set the dots in the correct position no matter what type of curve I will be setting on the area chart?
You should use another interpolation function, for example, curveCardinal. Look at this demo page, when you can choose interpolation function for your case (click on names of functions appears/disappears the corresponding line).
Look at my fork of your pen with curveCardinal - https://codepen.io/levvsha/pen/YrBEzN?editors=1010
const area = d3.area()
.x((d, i) => xScale(data.xAxis.categories[i]))
.y0(viewModel.height)
.y1((d) => yScale(d))
.curve(d3.curveCardinal);
Description: I have a multiple line chart with controls to filter which lines show, so lines are entering and exiting.
Desired effect: I want to transition the line to be exactly where the x-axis is (flattening it to a horizontal line the width of the x axis) before it disappears.
What I'm trying:
var moveBottomLeft = `M0,${this.height - margin.bottom}`;
var lineBottomRight = `L${this.width - margin.right},${this.height-margin.bottom}`;
path.exit().transition().duration(DURATION).attr('d', moveBottomLeft+lineBottomRight).remove();
What happens:
All of the line disappears besides the first section.
That small section of line expands to the width of the x axis, and translates down to where it is.
Instead, I would like the whole line to transform (not just that first section). How can I achieve this?
Figured it out: use d3.svg.line(), but set y to just return the height of the chart. (my code looks different, but I think this would be close)
path.exit().transition().attr('d', function() {
return d3.svg.line()
.x(function(d){return d})
.y(function(d){return chartHeight})(lineData)
})
.remove()