I am trying to adapt the animated grouped bar chart example from
https://bl.ocks.org/aholachek/fb0c1cd7ea9707bc8ff55a82402c54b1
for my own purposes. One modification that I am stuck at right now is that my data will have a variable number of groups and the xAxes and blocks have to resize accordingly.
I have already added the resizing of the domains with
x0.domain(data[Object.keys(data)[0]].map(obj =>obj.name))
x1.domain(valueKeys).rangeRound([0, x0.bandwidth()])
in the update function, but this does not seem to be enough. While the width of the bars is resized correctly, the x values are not spaced out evenly and instead get pushed into the far right corner of the graph when adding more elements after the initial creation for example.
For now I only care about the grouped version, not the stacked one.
I would appeciate any pointers
Problem could be solved by clearing out the barContainer before the update. This of course prevents transitions on the already existing bars, but that is good enough for me
Related
I'm showing percentage values inside my chart columns but some of the labels overlap when the values are very small and are hard to read. I tried adjusting the font size but it's not helping. How can I show these labels without any overlap? Screenshot below.
I'm afraid there's very little that can be done as the library doesn't have any strategies to automatically avoid overlap outside of hiding the labels if there's not enough room by default with the default false setting for showAllValueLabels.
You can try tweaking the graph objects' labelOffset property to shift the text up to see if that helps, but that's all you can do on the label side of things.
Alternatively, instead of using labels, just rely on the chart balloons that appear when hovering over the column. You can also enable the chartCursor, which shows all balloons within a category/date instead of just one of the balloons and they won't overlap. You can adjust the cursor's visibility and appearance as well.
I want to draw a D3 pie chart. Initially the arc segments will be hidden, then I want to animate them sequantially one by one to make them visible in response to keyboard/mouse events from the application flow.
The application flow is a linear: E.g. part 1, animate first arc segment to make it visible. Part 2, animate second segment to make it visible. Part 3, etc. until the pie is completely visible.
I'm interested in using the Swiper project - http://www.idangero.us/swiper/api/#.VqemYVOLQmI - so moving to each slide would trigger an event that would make an arc visible (i.e. onSlideChangeEnd would show each sequential arc)
One approach I could take would be to draw the pie segment as initially invisible, then use a style transition to make it visible:
d3.selectAll(“.segment1”).transition().duration(500).style("fill", "#7FB9E6”);
This could make each sequential arc visible in response to each event.
However that’s not quite the look I’m going for - I want the animation on the fill of the arc to appear like it’s moving from left to right, e.g. in this kind of "sweep" animation: http://jsfiddle.net/thmain/xL48ru9k/1/
Is this kind of animation possible to use if I’m not updating data using D3 (i.e. the chart is already created, I just want the arcs to appear sequentially in response to an event).
I'm new to animation / tweening so help is appreciated. Thanks.
One idea is to initialize the chart with all the values initially set to zero. Then, as your user swipes through your content, just update each element as needed with each items' respective data value.
I think (I haven't tried it) that it would create a 'bumping' effect, where each time a user swipes (or whatever the function call is) the chart's slices would 'add' a slice and resize the visible slices' portion of the data shown (if that makes sense).
The easiest way is probably to leverage the d3.svg.arc shape directly (a pie chart is merely a "helper" for creating many of these). If you know what the total of the data is, you can calculate the angle of each arc individually, and show/hide/animate them at will.
Is there a way to create a horizontal bar chart (or modify the row chat)?
The row chart does almost what I want, however I want the y axis to be a continuous variable and it seems the row chart defines the y axis in terms of discrete/ordinal variables.
I was also thinking about rotating the svg with d3. (Rotating the whole div worked, however the brush effect did not rotate too).
I was thinking:
dc.renderAll();
d3.select("body").select("#barChart3").select("svg").attr("transform", function(d) { return "rotate(90)"});
however that erased the whole chart rather than rotating it.
Any suggestions?
Update:
I am having some success with rotating the svg (the brush works), however the graph is being cut off and I can't figure out why...
The two charts are completely different codebases and have different features. The Y axis of a row chart does not even use a scale, so you are quite right that it can't be made continuous in its present form.
It is an eventual goal to merge them, but for now I think rotating is your best bet.
As for the clipping problem you're having, look for the clip-path attribute on the generated SVG. It would need to be rotated as well, but for a quick fix you can probably remove it.
I need to find out where to draw my y axis dependent of a date
My data looks like the following in .csv format:
startYYYYMM, endYYYYMM, ProjectName
201301, 201303, Proj1
201302, 201412, Proj2
201304, 201311, Proj3
I've done the chart as laying bar chart
Where to start my bars on the x axis is dependent on the start and is no problem. It's the y that is the problem.
I wonder If there is any built in "optimization" in d3 that I can use. I release that I can loop through my data to decide "the grouping" of my data.
And a pic of how I would like it to look like:
https://www.dropbox.com/s/5xs0jfxb33ipn60/temp.jpg
/Thank's
If I understand correctly, the difference between what you want and a standard Gantt chart is that the Gantt chart puts every project on its own line, but you want to compact the display so that long-finished projects don't continue to take up a row of blank space.
To get that "optimized function based on date" that figures out where on the Y-domain you can fit a project to keep the display compact, you're going to need to keep track of which projects are active at a given time, and loop through them to find out where you have room on your display for a new project.
Here's an algorithm you could implement. The results won't always be perfect (sometimes a small rectangle will end up taking up room in a space where a larger rectangle could have been positioned) but it should be much more compact than a standard Gantt chart.
Sort your projects by start date and work through them in that order, assigning y-positions to each.
As you work through your project list, keep a secondary array of "active" projects -- ones that have been started but not finished at the time you are looking. These will always be projects that you have already positioned on the graph, since you're positioning projects in order of start time.
For each project in your main array:
go through the active-project array (if it's not empty) and remove any projects that finished before the project you are plotting started (if you want padding between rectangles, require a certain minimum time to have passed in between);
sort the active-project array by the y-position you have already assigned to each project-rectangle;
scan through the active-project array, checking the y-position and height of each rectangle, to see if you have room to place the rectangle for your current project;
if you can't fit it in-between any of the currently active projects, set it's position to be above the last active project, and check whether the new position+height of this rectangle exceeds your previous maximum height;
either way, store the calculated y position (which will be in the same units as the variable you are using for rectangle height) in the project's data-object.
Now that you've set this project's position, add it to the active-project array and move on to the next project in your main array.
Once you have determined a relative y-position for each rectangle, set your y-scale domain according to the maximum height you used and draw the axis and rectangles.
You can look at this answer for some inspiration, although that example is more complicated than what you need.
I am writing an app that uses Highcharts, and in one instance I want to have a "slider" at the bottom of the chart that extends up vertically over the chart. Moving the slider will update other parts of the page based on where the user moves the slider on the chart.
The problem is that when drawing anything on top of the Highchart (image or a div) the performance becomes absolutely unacceptable. The slider simply cannot keep up with the mouse movements See a jsfiddle here. Note - this only happens when working with a large number of data points (which is absolutely unavoidable in my case).
Is there anything that I can do, short of not drawing on top of the chart?
I suspect the slowness is because the browser has to redraw the chart (either the whole thing or parts of it) as the div slides over it. With a large data set to redraw the chart from, this becomes annoyingly slow.
There are solutions, but not all of them are always acceptable:
You can try reducing the number of points in your data set by sampling it at a lower rate.
You can try windowing, so that the viewer only shows a range within the entire set. For example, if you have 10,000 data points your window can slide along the data set, showing only 1,500 points at a time as opposed to all 10,000 points.
Move to a different technology such as Flash or Silverlight.
Like I said, though, not all of these or even any of them will work for you.
I noticed that when you drag the slider over the graph it still highlights the datapoints. You probably should set pointer-events:none on that part of your chart while dragging the slider, that will allow browsers to not check pointer-events in that subtree (which if you have a lot of datapoints can be somewhat expensive, especially if you update these elements on hover).