plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.86k stars 1.85k forks source link

Make layout height & width understand viewport and percentage sizes #106

Closed caalberts closed 5 years ago

caalberts commented 8 years ago

Hi, how can I set the width of the svg chart according to viewport width? I tried using width: '80vw' in layout, but plotly doesn't seem to parse the vw units. Appreciate any help!

      const layout = {
        hovermode: 'closest',
        autosize: true,
        // width: 1000,
        // height: 600,
        margin: {
          l: 50,
          r: 20,
          b: 50,
          t: 50,
          pad: 10
        },
        yaxis: {
          rangemode: 'tozero'
        }
      }
etpinard commented 8 years ago

plotly.js only understands fixed height and width at the moment.

This tutorial https://plot.ly/javascript/responsive-fluid-layout/ shows you how to make responsive/fluid plotly.js graphs.

Personally, I really like the idea of making height and width understand viewports and width percentage.

Changing the issue title to reflect a feature request.

amirmog commented 8 years ago

Any progress on this? Any ideas as how to make the graph take up 100% of the height and width of its parent container?

ps. I have already see this: https://plot.ly/javascript/responsive-fluid-layout/

Thank you.

etpinard commented 8 years ago

@amirmog we hope to merge numerous auto-size improvements in https://github.com/plotly/plotly.js/pull/635 before the next release.

It won't resolve the height-in-percentage proposal, but it will make it easier for community contributor to add this feature.

fresheneesz commented 7 years ago

Here's a function that can convert any valid absolute or relative css length to pixels:

// gets the pixel length of a value defined in a real absolute or relative measurement (eg mm)
function lengthToPixels(length, metric) {
    if(lengthToPixels.cache === undefined) lengthToPixels.cache = {}//{px:1}
    var conversion = lengthToPixels.cache[metric]
    if(conversion === undefined) {
        var tester = document.createElement('div')
        tester.style.width = 1+metric
        tester.style.visibility = 'hidden'
        tester.style.display = 'absolute'
        document.body.appendChild(tester)
        conversion = lengthToPixels.cache[metric] = tester.offsetWidth
        document.body.removeChild(tester)
    }

    return conversion*length
}
nzjrs commented 7 years ago

also broken for me. any pointers how to make graphs be 100% of their parent container?

antoinerg commented 6 years ago

@chriddyp Can you elaborate on the use case for this feature?

Currently, without specifying a width or a height, it seems like figures are 100% of their parent container. Therefore, one can control the graph size in CSS using any unit of measurements (pixel, viewport and percentage sizes). See for example https://codepen.io/antoinerg/full/NLboJw

It is my understanding that viewport and percentage sizes only make sense in the context of a page. In my opinion, this presentation logic should be CSS' business so I am not sure plotly.js should deal with those explicitly. Is there a use case I am not seeing or can we close this issue?

pdfabbro commented 5 years ago

It appears that you can change the height on resize, but not the width as the width is always dependent on the height you set. You should be able to set a minWidth and a scroll bar because the charts are completely illegible on mobile.

antoinerg commented 5 years ago

Hello @pdfabbro and thank you for commenting on this issue!

It appears that you can change the height on resize, but not the width as the width is always dependent on the height you set.

I'm not sure I understand what you mean by this. It seems to me that the width does change on resizing as shown in this codepen https://codepen.io/antoinerg/full/NLboJw. Can you elaborate or better yet send me a Codepen highlighting the issue?

You should be able to set a minWidth and a scroll bar because the charts are completely illegible on mobile.

At the moment, this can be accomplished using CSS as shown in this codepen https://codepen.io/antoinerg/pen/JaZEOQ. Please let us know whether this solution makes sense and is doable in your context.

Thank you again :)

pdfabbro commented 5 years ago

Hi Antoine,

Thanks very much for the quick response! Yes, for me the width does change, but I can't actually set it to a specific value whereas I can set the height to a specific value. If I don't set the height, then it goes back to its default of 450px. What I'd like to be able to do is set the height AND width to specific values, but right now it seems to only take in my height and then adjust the width accordingly.

As for the minWidth and scroll, I am doing something very similar to what you have, but it isn't working. I am calculating width, height, and minWidth in a resize function similar to the eponym's code from here: https://community.plot.ly/t/plot-sizing-problems/1620/13

I'll have to take a closer look at yours and see what's different than mine. Thanks again.

pdfabbro commented 5 years ago

I just noticed you have a property in a config object "responsive:true". I don't see that property in the reference: https://plot.ly/javascript/reference/ or the config reference: https://plot.ly/javascript/configuration-options/

pdfabbro commented 5 years ago

I think I see what I'm doing wrong in terms of the scrollbar issue which would mean I no longer care about explicitly setting both height and width (in terms of pixels), so this should resolve my issue. Thanks very much!

I'd still be curious why I can't explicitly set both height and width though, but perhaps I am setting that on the wrong div as I noticed eponym's code is setting the svg-container, whereas you are setting the width on the container that is passed to Plotly.plot.

pdfabbro commented 5 years ago

Yup, I was on the wrong div... sorry for the spam, looks like I was trying to combine eponym's answer and height and div property's incorrectly. I tried out your scroll solution and it works perfectly for me. Thank-you so much for taking the time to do that.

antoinerg commented 5 years ago

Glad I could help @pdfabbro !

The config option responsive: true is new in v1.41 and the doc will be updated accordingly very soon :)

chriddyp commented 5 years ago

~I believe that this issue can be closed now.~ From a Dash perspective, I think we're OK here for now.


For any future visitors, one issue that I've seen folks have with sizing is that the graph div doesn't inherit the parent's height.

So, this "doesn't work"

<div style="height: 60vh">
   <div id="plot"/>
</div>

but this will work:

<div style="height: 60vh">
   <div id="plot" style="height: inherit"/>
</div>

This particular use case came up in Dash (see https://community.plot.ly/t/cant-seem-to-change-default-height-on-graph/6742/28?u=chriddyp and the previous comment).

antoinerg commented 5 years ago

Thank you @chriddyp!

One can also style the div#plot directly:

<div id="plot" style="height: 50vh"/>

This feels more natural to me. Can we do that easily from Dash?

chriddyp commented 5 years ago

Yup, that works too! I originally mentioned that in the Dash forum (see https://community.plot.ly/t/cant-seem-to-change-default-height-on-graph/6742/14?u=chriddyp) but it seems like some folks were still getting tripped up by styling the containers for their graphs one further level up (the graph's parent).

etpinard commented 5 years ago

I think @antoinerg 's responsize: true addition effectively resolved this ticket.

Closing, but please comment if you think there's more to the story.

lujcheng commented 4 years ago

I have an issue where the map is overflowing out of the screen in a sort of carousel, every container div for the plot is width: 100%, however, the plot is defaulting to 100px so when it comes in it's 100px until I resize the screen. I've also done this https://plot.ly/javascript/responsive-fluid-layout/.

antoinerg commented 4 years ago

Hello @Renkinjutsu ! In order to help you with your issue, we would need a Codepen reproducing the issue. Thanks!

tdpetrou commented 4 years ago

This is still an issue. Height of figures is 450px unless you set it explicitly using px or vh/vw. Spent an extraordinarily long time banging my head against the wall on this one.

leo-smi commented 3 years ago

Can't change image height yet, just the width!

AjManoj commented 3 years ago

Setting Parent Height to 100% with layeout ={resposnive : true} resolved the problem

aiqc commented 2 years ago

now that I am using columns in Dash, I am struggling with responsive chart widths. chart areas keep getting stretched or pushed off the page. it feels like i need %s that will adjust w the containers dimensions. could probably wrap it in a div or something

JeremyBesson commented 1 year ago

@tdpetrou I was in the same situation until I found another maybe more "elegant" solution (Because responsive: true should be set by default... So I can't understand why set it to true should solve this) My solution: Set height 100% in dcc.graph AND height whatever you want in the dbc.row where the dcc.graph is inside

pocupine commented 11 months ago

I didn't use Dash but Plotly in Python Flask directly. When I wanted to insert the code into a HTML file I encountered this problem. I Found that when use plotDiv = pyo.plot(fig, include_plotlyjs=False, output_type='div', config= config) without specifying width and height in fig.update_layout,The default height and width in the variable plotDiv is "height:100%; width:100%;" I then used "plotDiv = plotDiv.replace("height:100%; width:100%;","height:100%; width:90%; margin:auto;")" to change the width percentage and centered the fig. Hopefully it is helpful for someone.

pocupine commented 11 months ago

One more thing is that this is actually using the plotly-build-in CSS but not the CSS we normally use. I did try to use a div container in the original HTML file and tried to set the style but failed. THIS MUST BE DONE IN THE plotly-build-in div container.