From 1f005d34caab68981456f5bb97303e04265fb850 Mon Sep 17 00:00:00 2001 From: Maxime Beauchemin Date: Tue, 13 Feb 2018 08:42:46 -0800 Subject: [PATCH] [dashboard] more granular grid layout Moving to a grid that is 4 times more granular. 48 columns. Shipping a db migration script which will upgrade the position metadata to reflect this change. Also adapting the examples to the new grid parameters. --- .../dashboard/components/GridLayout.jsx | 4 +- superset/data/__init__.py | 493 ++++++++++-------- .../versions/e866bd2d4976_smaller_grid.py | 73 +++ 3 files changed, 342 insertions(+), 228 deletions(-) create mode 100644 superset/migrations/versions/e866bd2d4976_smaller_grid.py diff --git a/superset/assets/javascripts/dashboard/components/GridLayout.jsx b/superset/assets/javascripts/dashboard/components/GridLayout.jsx index 68de7686cef5d..b204b41594ea3 100644 --- a/superset/assets/javascripts/dashboard/components/GridLayout.jsx +++ b/superset/assets/javascripts/dashboard/components/GridLayout.jsx @@ -176,8 +176,8 @@ class GridLayout extends React.Component { layouts={{ lg: this.props.dashboard.layout }} onResizeStop={this.onResizeStop} onDragStop={this.onDragStop} - cols={{ lg: 12, md: 12, sm: 10, xs: 8, xxs: 6 }} - rowHeight={100} + cols={{ lg: 48, md: 48, sm: 40, xs: 32, xxs: 24 }} + rowHeight={10} autoSize margin={[20, 20]} useCSSTransforms diff --git a/superset/data/__init__.py b/superset/data/__init__.py index e1d0b67558db2..c0a957ee1b032 100644 --- a/superset/data/__init__.py +++ b/superset/data/__init__.py @@ -362,76 +362,86 @@ def load_world_bank_health_n_pop(): dash = Dash() js = textwrap.dedent("""\ [ - { - "col": 1, - "row": 0, - "size_x": 2, - "size_y": 2, - "slice_id": "1231" - }, - { - "col": 1, - "row": 2, - "size_x": 2, - "size_y": 2, - "slice_id": "1232" - }, - { - "col": 10, - "row": 0, - "size_x": 3, - "size_y": 7, - "slice_id": "1233" - }, - { - "col": 1, - "row": 4, - "size_x": 6, - "size_y": 3, - "slice_id": "1234" - }, - { - "col": 3, - "row": 0, - "size_x": 7, - "size_y": 4, - "slice_id": "1235" - }, - { - "col": 5, - "row": 7, - "size_x": 8, - "size_y": 4, - "slice_id": "1236" - }, - { - "col": 7, - "row": 4, - "size_x": 3, - "size_y": 3, - "slice_id": "1237" - }, - { - "col": 1, - "row": 7, - "size_x": 4, - "size_y": 4, - "slice_id": "1238" - }, - { - "col": 9, - "row": 11, - "size_x": 4, - "size_y": 4, - "slice_id": "1239" - }, - { - "col": 1, - "row": 11, - "size_x": 8, - "size_y": 4, - "slice_id": "1240" - } + { + "slice_id": "567", + "size_x": 8, + "size_y": 8, + "v": 1, + "col": 1, + "row": 0 + }, + { + "slice_id": "568", + "size_x": 8, + "size_y": 8, + "v": 1, + "col": 1, + "row": 8 + }, + { + "slice_id": "569", + "size_x": 12, + "size_y": 28, + "v": 1, + "col": 37, + "row": 0 + }, + { + "slice_id": "570", + "size_x": 24, + "size_y": 12, + "v": 1, + "col": 1, + "row": 16 + }, + { + "slice_id": "571", + "size_x": 28, + "size_y": 16, + "v": 1, + "col": 9, + "row": 0 + }, + { + "slice_id": "572", + "size_x": 32, + "size_y": 16, + "v": 1, + "col": 17, + "row": 28 + }, + { + "slice_id": "573", + "size_x": 12, + "size_y": 12, + "v": 1, + "col": 25, + "row": 16 + }, + { + "slice_id": "574", + "size_x": 16, + "size_y": 16, + "v": 1, + "col": 1, + "row": 28 + }, + { + "slice_id": "575", + "size_x": 16, + "size_y": 16, + "v": 1, + "col": 33, + "row": 44 + }, + { + "slice_id": "576", + "size_x": 32, + "size_y": 16, + "v": 1, + "col": 1, + "row": 44 + } ] """) l = json.loads(js) @@ -738,70 +748,88 @@ def load_birth_names(): dash = Dash() js = textwrap.dedent("""\ [ - { - "col": 9, - "row": 6, - "size_x": 2, - "size_y": 4, - "slice_id": "1267" - }, - { - "col": 11, - "row": 6, - "size_x": 2, - "size_y": 4, - "slice_id": "1268" - }, - { - "col": 1, - "row": 0, - "size_x": 2, - "size_y": 2, - "slice_id": "1269" - }, - { - "col": 3, - "row": 0, - "size_x": 2, - "size_y": 2, - "slice_id": "1270" - }, - { - "col": 5, - "row": 3, - "size_x": 8, - "size_y": 3, - "slice_id": "1271" - }, - { - "col": 1, - "row": 6, - "size_x": 8, - "size_y": 4, - "slice_id": "1272" - }, - { - "col": 10, - "row": 0, - "size_x": 3, - "size_y": 3, - "slice_id": "1273" - }, - { - "col": 5, - "row": 0, - "size_x": 5, - "size_y": 3, - "slice_id": "1274" - }, - { - "col": 1, - "row": 2, - "size_x": 4, - "size_y": 4, - "slice_id": "1275" - } + { + "slice_id": "578", + "size_x": 8, + "size_y": 16, + "v": 1, + "col": 33, + "row": 24 + }, + { + "slice_id": "579", + "size_x": 8, + "size_y": 16, + "v": 1, + "col": 41, + "row": 24 + }, + { + "slice_id": "580", + "size_x": 8, + "size_y": 8, + "v": 1, + "col": 1, + "row": 0 + }, + { + "slice_id": "581", + "size_x": 8, + "size_y": 8, + "v": 1, + "col": 9, + "row": 0 + }, + { + "slice_id": "582", + "size_x": 32, + "size_y": 12, + "v": 1, + "col": 17, + "row": 12 + }, + { + "slice_id": "583", + "size_x": 32, + "size_y": 16, + "v": 1, + "col": 1, + "row": 24 + }, + { + "slice_id": "584", + "size_x": 12, + "size_y": 12, + "v": 1, + "col": 37, + "row": 0 + }, + { + "slice_id": "585", + "size_x": 20, + "size_y": 12, + "v": 1, + "col": 17, + "row": 0 + }, + { + "slice_id": "586", + "size_x": 16, + "size_y": 16, + "v": 1, + "col": 1, + "row": 8 + }, + { + "slice_id": "587", + "size_x": 16, + "size_y": 16, + "v": 1, + "col": 1, + "row": 48 + } ] + """) l = json.loads(js) for i, pos in enumerate(l): @@ -884,8 +912,8 @@ def load_unicode_test_data(): if not dash: dash = Dash() pos = { - "size_y": 4, - "size_x": 4, + "size_y": 16, + "size_x": 16, "col": 1, "row": 1, "slice_id": slc.id, @@ -1178,48 +1206,54 @@ def load_misc_dashboard(): dash = Dash() js = textwrap.dedent("""\ [ - { - "col": 1, - "row": 7, - "size_x": 6, - "size_y": 4, - "slice_id": "442" - }, - { - "col": 1, - "row": 2, - "size_x": 6, - "size_y": 5, - "slice_id": "443" - }, - { - "col": 7, - "row": 2, - "size_x": 6, - "size_y": 4, - "slice_id": "444" - }, - { - "col": 9, - "row": 0, - "size_x": 4, - "size_y": 2, - "slice_id": "455" - }, - { - "col": 7, - "row": 6, - "size_x": 6, - "size_y": 5, - "slice_id": "467" - }, - { - "col": 1, - "row": 0, - "size_x": 8, - "size_y": 2, - "slice_id": "475" - } + { + "slice_id": "564", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 1, + "row": 28 + }, + { + "slice_id": "565", + "size_x": 24, + "size_y": 20, + "v": 1, + "col": 1, + "row": 8 + }, + { + "slice_id": "566", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 25, + "row": 8 + }, + { + "slice_id": "577", + "size_x": 16, + "size_y": 8, + "v": 1, + "col": 33, + "row": 0 + }, + { + "slice_id": "590", + "size_x": 24, + "size_y": 20, + "v": 1, + "col": 25, + "row": 24 + }, + { + "slice_id": "591", + "size_x": 32, + "size_y": 8, + "v": 1, + "col": 1, + "row": 0 + } ] """) l = json.loads(js) @@ -1634,55 +1668,62 @@ def load_deck_dash(): dash = Dash() js = textwrap.dedent("""\ [ - { - "col": 1, - "row": 0, - "size_x": 6, - "size_y": 4, - "slice_id": "37" - }, - { - "col": 7, - "row": 0, - "size_x": 6, - "size_y": 4, - "slice_id": "38" - }, - { - "col": 7, - "row": 4, - "size_x": 6, - "size_y": 4, - "slice_id": "39" - }, - { - "col": 1, - "row": 4, - "size_x": 6, - "size_y": 4, - "slice_id": "40" - }, - { - "col": 1, - "row": 4, - "size_x": 6, - "size_y": 4, - "slice_id": "41" - }, - { - "col": 7, - "row": 4, - "size_x": 6, - "size_y": 4, - "slice_id": "42" - }, - { - "col": 1, - "row": 5, - "size_x": 6, - "size_y": 4, - "slice_id": "43" - } + { + "slice_id": "600", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 1, + "row": 0 + }, + { + "slice_id": "601", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 25, + "row": 0 + }, + { + "slice_id": "602", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 25, + "row": 16 + }, + { + "slice_id": "603", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 1, + "row": 16 + }, + { + "slice_id": "604", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 1, + "row": 16 + }, + { + "slice_id": "605", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 25, + "row": 16 + }, + { + "slice_id": "606", + "size_x": 24, + "size_y": 16, + "v": 1, + "col": 1, + "row": 20 + } ] """) l = json.loads(js) diff --git a/superset/migrations/versions/e866bd2d4976_smaller_grid.py b/superset/migrations/versions/e866bd2d4976_smaller_grid.py new file mode 100644 index 0000000000000..e99c703479344 --- /dev/null +++ b/superset/migrations/versions/e866bd2d4976_smaller_grid.py @@ -0,0 +1,73 @@ +"""smaller_grid +Revision ID: e866bd2d4976 +Revises: 21e88bc06c02 +Create Date: 2018-02-13 08:07:40.766277 +""" +import json + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.ext.declarative import declarative_base +from flask_appbuilder.models.mixins import AuditMixin + +from superset import db + +revision = 'e866bd2d4976' +down_revision = '21e88bc06c02' + +Base = declarative_base() +RATIO = 4 + +class Dashboard(Base): + """Declarative class to do query in upgrade""" + __tablename__ = 'dashboards' + id = sa.Column(sa.Integer, primary_key=True) + position_json = sa.Column(sa.Text) + dashboard_title = sa.Column(sa.String(500)) + + +def upgrade(): + bind = op.get_bind() + session = db.Session(bind=bind) + + dashboards = session.query(Dashboard).all() + for i, dashboard in enumerate(dashboards): + positions = json.loads(dashboard.position_json or '{}') + for pos in positions: + if pos.get('v', 0) == 0: + pos['size_x'] = pos['size_x'] * RATIO + pos['size_y'] = pos['size_y'] * RATIO + pos['col'] = ((pos['col'] - 1) * RATIO) + 1 + pos['row'] = pos['row'] * RATIO + pos['v'] = 1 + + dashboard.position_json = json.dumps(positions, indent=2) + session.merge(dashboard) + session.commit() + print('Upgraded ({}/{}): {}'.format( + i, len(dashboards), dashboard.dashboard_title)) + + session.close() + + +def downgrade(): + bind = op.get_bind() + session = db.Session(bind=bind) + + dashboards = session.query(Dashboard).all() + for i, dashboard in enumerate(dashboards): + positions = json.loads(dashboard.position_json or '{}') + for pos in positions: + if pos.get('v', 0) == 1: + pos['size_x'] = pos['size_x'] / 4 + pos['size_y'] = pos['size_y'] / 4 + pos['col'] = ((pos['col'] - 1) / 4) + 1 + pos['row'] = pos['row'] / 4 + pos['v'] = 0 + + dashboard.position_json = json.dumps(positions, indent=2) + session.merge(dashboard) + session.commit() + print('Downgraded ({}/{}): {}'.format( + i, len(dashboards), dashboard.dashboard_title)) + pass