quantopian / qgrid

An interactive grid for sorting, filtering, and editing DataFrames in Jupyter notebooks
Apache License 2.0
3.03k stars 425 forks source link

GridOption: Fit column size to data - Up to a max size #119

Open JohnOmernik opened 7 years ago

JohnOmernik commented 7 years ago

One option to consider would be a "Fit column size to data size" - with a max width for this option... this would allow us to utilize our available real estate on screen in an easy way, and make it so we don't have horizontal scroll bars that go on for 2.4 miles on some data.

TimShawver commented 6 years ago

Hmm yea it's kind of a tough problem because it requires looking at the contents of every cell of the DataFrame to determine exactly how wide the column should be. I suppose maybe I could come up with a strategy for estimating the required width of each column though...I'll have to think about that and do some research.

In case it's helpful you can set the default width for all columns in a grid via the grid_options kwarg on the show_grid method: http://qgrid.readthedocs.io/en/latest/#qgrid.show_grid

qgrid.show_grid(df, grid_options={'forceFitColumns': False, 'defaultColumnWidth': 200})
ipcoder commented 6 years ago

May be as a simple alternative to provide an access to .width attribute of the column? Then at least user can set it according to its own needs/logic.

Now all the columns are of same width and for some tables that means wide data columns requires manual resizing each time the table is displayed.

TimShawver commented 6 years ago

Yea good point, there's a PR open which adds column-specific options, so maybe I can add it as a column-specific option you can set when you construct the grid.

TimShawver commented 5 years ago

The ability to set the width on specific columns has been added in version 1.1.0. For example if you want to make all column 200px, except for column B which should be 400px, you could do the following:

col_options = {
    'width': 200,
}
col_defs = {
    'B': {
        'width': 400,
    }
}

qgrid_widget = qgrid.show_grid(df_types,
                               column_options=col_options,
                               column_definitions=col_defs,
                               show_toolbar=True)
qgrid_widget
fomightez commented 5 years ago

Tip: if you have a lot of columns and you want the solution posted by TimShawver July 11, 2018 to work, you need to also include grid_options={'forceFitColumns': False}. Otherwise, the settings in column_options and column_definitions will get ignored and your columns will be all squashed next to one another.

col_options = {
    'width': 200,
}
col_defs = {
    'B': {
        'width': 400,
    }
}

qgrid_widget = qgrid.show_grid(df_types,
                               column_options=col_options,
                               column_definitions=col_defs,
                               grid_options={'forceFitColumns': False},
                               show_toolbar=True)

(Placing this here because this page currently comes up near top if searching qgrid column width.)

aakashsantuka commented 5 years ago

show_grid() got an unexpected keyword argument 'column_options'

I am getting this error

fomightez commented 5 years ago

show_grid() got an unexpected keyword argument 'column_options'

I am getting this error

Which version were you trying @aakashsantuka ? I just tried in the one available when you click launch binder from here and didn't see that. I believe there is running at least 1.1.0. because it mentions it at the top. (Hopefully, even 1.1.1.) The information here specifically describes column_options parameter for version 1.1.0; I don't know if it predates it.

dpdoughe commented 4 years ago

Might be nice if width could be specified in the relative units of the current font (em, ex etc). That would allow the fitting to be scalable based on length of longest string in column for example.

E.g.

 col_defs = {
    'B': {
        'width': '40em',
    }
}
dpdoughe commented 4 years ago

FYI, in current version specifying a string for width e.g. 'width': '400', leads to invisible cells and other strange behavior. Perhaps string for width should raise exception if not supported?

JohnOmernik commented 4 years ago

So I am back to using Qgrid, and was giving some thought to this. @TimShawver posted that "Hmm yea it's kind of a tough problem because it requires looking at the contents of every cell of the DataFrame to determine exactly how wide the column should be. I suppose maybe I could come up with a strategy for estimating the required width of each column though...I'll have to think about that and do some research."

It is a tough problem, but maybe we don't have to solve it... what I mean is this:

What if we had a feature that when enabled (it's disabled by default), took the initial load of a dataframe (i.e. only what is rendered, because as I understand it, the whole data frame isn't held in the dom, Qgrid dynamic loads it) So, we take this initial load and do the "look at every content of every cell/row combination" thing. This wouldn't have to be the whole data frame, but it would give a good guestimate on sizes. First of all, we do "up to a max" like my initial post said. so if the column for Row 2 was 1000 pixels, and we said our max column size was 750, it would only go to 750. It would set the columns based on that. We could have a min size too. This would give a "best effort at acceptable cost" solution.

Three options:

I know some would say "but then the columns could be wrong as new data gets sent in that ma be bigger than the initial data" Yep, it could be. But how is that different then when we have have fixed column sizes? The data IS wrong at this point. The nice thing about this approach is frankly the small columns. Those that have always have too much white space. Those will be made smaller so that the whitespace is not wasted without any clicks by the user.

In addition, the number of columns to be tested could be programatic. If the user wants to wait for all the data frame to be checked, that could be an option too, but the point of this post is we don't need a perfect solution. We need a performant solution that is better than what we have, not a performant solution that is perfect.

Thoughts?

dpdoughe commented 4 years ago

Seems related. Maybe the CSS for the table width needs to be unset in QGrid for this to work though. https://stackoverflow.com/questions/33475457/how-to-make-table-td-tr-auto-width-based-on-text-length