-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce support for chart resizing #544
Comments
I recently started using Here's a jsfiddle showing the technique. Resize the results pane to see it in action. There's a slight flicker when the page first loads before the Looking at the source code for dc.js, I don't think it would be very difficult to add a If the awkwardness of the large axes/legend are not your thing, you could always stick with your current technique, with a couple of tweaks to improve performance, like using the dc.events.trigger(..) function to ensure that the calls to |
Or another approach would be to detect a
Right now I have a function that I pass to the width:
Then on window.resize() I .redrawAll(). But passing in a percentage to width would be much cleaner and intuitive. |
@jefffriesen I don't think just providing Instead, I think the best way to keep it intuitive is by translating the behavior of I've forked the master branch and started making the changes I've described above to add support for the technique I mentioned above. It essentially leaves the height-width of the chart in place, meaning that it doesn't break any of the existing charts which rely on them for computing internal rendering coordinates, and instead simply changes attributes on the generated SVG element. |
@axiomabsolute, note we also have the (fairly new) behavior of fitting to the parent div if width or height is set to null, which seems to be similar to what you're proposing with https://github.com/dc-js/dc.js/blob/master/web/docs/api-latest.md#heightvalue The parent div can in turn be sized at a percentage of its parent, so I don't think anything needs to be built in for percentages. I poked around to see if there are resize events on elements. It seems there is only a browser-level resize event, and then some hacks involving overflow detection which I'd be wary of including. Not sure how to address that part. |
I think the bar width resize problem @wssbck mentions is the same as #572 / #533. Generally people seem to recommend throttling events using something like dc.trigger because yes, it is rather resource-intensive to redraw elements as fast as the mouse can resize the window. |
@gordonwoodhull Thanks, I hadn't noticed that feature was added! Combining that with adding the viewBox attribute to the parent SVG in the Maybe use the viewBox for the live resize portion then fire off a true redraw only when the resize event is "complete" (i.e. the user hast let go of the mouse button)? This would give a kind of live preview of the chart with a relatively low performance cost, but would still do a true redraw at the end to ensure that elements that SHOULDN'T be scaled (like the axis markers and text labels) aren't distorted. You could even toss in the dc.trigger functionality so that if the user pauses for long enough while resizing it would trigger a full redraw. |
Related (not an answer, just cultivating the question): |
I made the parent responsive width (and set the chart width to null), then I'm using a resize event to rerender (with trigger delays), but while it works sometimes (and the svg element gets correctly sized all the time), the internal elements (like |
I'm currently using the height(null) and width(null) to get responsive rectangular charts but I can't find any documentation on how to get round pie charts to have dynamic radius. radius(null) doesn't seem to work. Any plans on getting the same functionality for radius? |
@alexhultman, could you open a separate issue for this? It looks like it is supposed to work: https://github.com/dc-js/dc.js/blob/master/src/pie-chart.js#L85
Please include the error you're getting, if any. |
Thanks for the quick reply. It actually seems to work. However, it doesn't redraw on resize like the other charts we have. I have to reload the page to get it to redraw. Could be our fault though. Anyhow - could you please update the docs about radius(null)? Thanks. |
Ok, I changed the description of I am not sure, but I think if that if any charts redraw on resize, or even automatically rescale when redrawn and their div has changed size, it is accidental. That's what this ticket is about. I have not investigated this, however. It would be nice to support and PRs are always welcome! |
I have the same behaviour like neverfox. When resizing the window I set a new height and width to the charts and use dc.renderAll(). The svg gets the new dimensions but the g-element inside the svg does not resize. Linecharts however resize correctly. RowCharts not. When I destroy all charts and render them from scratch the new width/height is set correctly. At the end I render everything from scratch. It would not be the best solution but how often does the user resize the viewport? I think only developers do this that often to test the ui. |
This isn't perfect, but I pasted a quick gist on how I've been doing this for many months now, and it is working without issue. We use a ton of row, bar, pie, and line charts, and it is all working with bootstrap at all the various breakpoints. This is angular specific (sorry), but you could extract the main logic out of it. The solution is essentially to debounce on window's This isn't the best way to build an angular directive either (shared scope with controller), but I figured I'd just post it if someone finds it useful. I don't attempt to resize the height, as we don't really want that with our charts. If you really want to resize the height and width, I'd use the svg viewport to scale it. |
Thanks. I will give it a try but svg-viewport is not a solution for me. I tested it and it looks awful when everything is scaling including the axis. |
Support for resizing coordinate grid charts is in 2.0.0 beta 15. You still need to drive it from some event you subscribe to (like Also moving this goal to 2.0 because it seems these changes can be made without breaking the API. I'm also adding a new examples directory, mostly for testing these: We can continue to add charts there as they gain compatibility. |
Adding (imperfect) support for pie chart resizing while I'm at it. |
for #544 plus artifacts for last few commits
@amergin reports:
|
Each chart just has to be tested, since a lot of attributes are only applied when the elements are created. It's pretty easy to fix the charts with the right testing framework, and that's the main contribution today. If anyone wants to port more test cases from the examples directory to the resizing directory, that would help. |
Not sure if you are aware of this, but the x axis resize problem still exists in |
Thanks for the report, @amergin. I was not aware of this. This issue won't be closed until every chart is certifiably fixed, so it may go past 2.0. |
@dsushmasagar, sorry but the issue tracker is for reporting bugs and making enhancement requests, not for general support questions. Please ask on Stack Overflow with the dc.js tag, or on the user group, and we will be glad to help you there. I know what you're asking is related to this issue, but it doesn't require any changes to dc.js and it's not going to help this issue along. |
@gordonwoodhull I have made a lot of progress on responsive charts in my fork. There have been some big changes and some things don't quite work fully yet. http://ruhley.github.io/dc.js/examples/label-wrap.html The main responsive changes are:
There are heaps of other changes done as well. See them in the changelog. |
That's great, @ruhley! I hope we are not making conflicting changes. I guess I have mostly been focusing on making non-breaking changes for 2.0, sometimes successfully, sometimes not. If you think the interface needs to be broken in order to fix the functionality, those would be great to consider for 2.1. (I'm following a weaker form of semantic versioning where the point releases can change the interface but not the point releases, because the interface has such a huge surface area.) |
My work has recently started getting heavily involved in charts and has authorised me to spend a fair bit of time fixing up dc.js whenever it is needed. The label wrapping and fitting them in properly was the major issue they wanted fixed. #943 was my original pull request for Paired Row Charts. I have kept my fork up to date and have resolved conflicts myself (don't want to miss out on any fixes you put in!) |
That's awesome. There is definitely plenty to be fixed. Let's try to get some of your fixes integrated back into dc-js, although it looks like it may be difficult since you have been changing interfaces and not writing tests. I wish I could put more time into this - at least my other projects are also open source vis. |
Things have been changing quite a lot on my fork recently, so I was going to wait for it to slow down a bit before updating all the tests. Also my main testing page has been http://ruhley.github.io/dc.js/examples/label-wrap.html, so only the charts on that page have been converted over. I have yet to fix up bubble, choropleth, scatter plot, heat map and box plot. Hopefully I can get a solid block of time at work to get all of that done... |
P.S. Also see the new awesome tooltips at http://ruhley.github.io/dc.js/examples/label-wrap.html. Have a look at the pie or row chart to see the border changing colour! |
@ruhley tooltip looks really cool..(y) |
Cool tooltips! It's really useful to have the code around, whether or not you have time to integrate it yourself. We can pull in stuff on demand. |
+1 |
Hi, I'm trying to mix width(0) and rescale() and, for what I understand, it does not mix, because width(0) is generated once. The workaround I found is to add:
|
@gordonwoodhull I'm trying to make it generic and so far works ok:
What about wrapping that into a new dc.responsive(true) ? |
@tttp, interesting idea! My impression has been that each application has its own way of dealing with responsiveness, but maybe it would be good to just decided on one supported way of doing this. A couple of notes on your code above:
That's weird that some charts would not have a root node. Any pattern there? |
@gordonwoodhull, well, if you'd want to have your own responsiveness, you'd just responsive (false) and do it your own way... but agree, we should offer "the dc way responsiveness" that works 90% out of the box.
(brainstorm mode): one feature that would make it better is to be able to adjust the ticks, eg if you are at >1000px, you'd put xAxis().ticks(10), if you are in a smaller window, you'd ticks(3) Not sure if it can work on the on("renderlet") or if it needs a on("resize") event, will try to make more of my viz responsive, see how it goes |
I suppose we'd have to add Different people have different requirements about what should be responsive - there are applications where the height should be responsive too. I think the height could be read from the container as well. Changing ticks would have to be before any drawing is done, so either the existing |
So you'd have to add a new signature on the height
My experience with responsive design is based on bootstrap, where the height is usually "whatever it needs to be to display the content once the width is set. For now, fixed height works fine for me, but some stuff (eg. pie chart, heatmaps or choropleth) might benefit being able to adjust the height to keep the ratio constant indeed. and assuming responsive() is part of dc, it could access _charMap, isn't it? This being said, .chartGroups sounds handy anyway... I do not know how to test the resize event, is this something that is already covered on your resize examples or does it need to be done by hand? X+ |
I'm not sure I understand you about the height signature. I just meant, set the height to It might make sense to just add an option to Unfortunately it can't access I'd test this by removing the |
@tttp, obviously a partial solution will be useful to a lot of people. If you made any progress with this, please go ahead and file a PR. I'm just noting all the stuff that would have to go into a general-purpose library solution before it could be merged. (Or if the above snippet is as far as you got, that's already helpful. 😺) |
My prefered solution for responsive sizing is to set a viewBox on the chart svg element and remove the width and height attributes. Then by applying a responsive percentage based width to the chart using css the whole chart resizes and maintains aspect ratio without need for any resize listeners or js resizing. My one remaining problem is that then clicking on the chart triggered a redraw and messes things up. Is it possible to turn disable js resizing and setting of the width and height attributes altogether? |
Hi @atomless, personally I don't like viewBox approach because the fonts get stretched, but I agree we should support that. It sounds like you basically want to fix the width and height but not have them reflected in the SVG tag attributes, is that correct? Could you try commenting out the |
Thanks @gordonwoodhull - I'll give that a try. I do not see any stretching of the fonts with the viewBox method. Everything is just beautifully responsive. I can literally resize the window down tiny or go full screen and chart and text resize perfectly in proportion. |
@gordonwoodhull yes commenting out var makeResponsiveChart = function(chart_el_id, w, h) {
$(chart_el_id + ' > svg').removeAttr('height').removeAttr('width').attr('viewBox', '0 0 ' + w + ' ' + h);
}; Where w, and h describe the desired aspect ratio of the chart. Using css the svg element is then set to 100% of it's containing div so it resizes automatically with the browser window. I see no font stretching. Would be excellent to have support for responsive charts sized with css internally without having to apply these hacks. |
That's great - I'm glad it works for you. I'm referring to the text sizing along with the chart - I prefer to have the text a certain size (defined in CSS) and then when the chart is larger the text takes up less room. But I agree we should also support the If you're willing to put these changes under a flag (say |
Great. Thanks @gordonwoodhull, I'll make a fork and submit a PR. |
responsiveResize option #1312 |
I have hit an issue when trying to use DC charts in a responsive layout. Since charts do not automatically redraw to accommodate the new size of their HTML container, I am forcing them to do so by calling dc.renderAll() on every window resize event. This is however not a good solution because it uses a lot of resources and some charts do not render properly during resizing anyway. For example, bars in row charts seem to "forget" that the HTML container has shrinked horizontally and still render like it has not.
The text was updated successfully, but these errors were encountered: