Example #1
0
    def __init__(self):

        self.prev = v.Btn(_metadata={'increm': -1},
                          x_small=True,
                          class_='ml-2 mr-2',
                          color=sc.secondary,
                          children=[
                              v.Icon(children=['mdi-chevron-left']),
                              cm.dynamic_select.prev
                          ])

        self.next = v.Btn(_metadata={'increm': 1},
                          x_small=True,
                          class_='ml-2 mr-2',
                          color=sc.secondary,
                          children=[
                              cm.dynamic_select.next,
                              v.Icon(children=['mdi-chevron-right'])
                          ])

        self.select = v.Select(dense=True,
                               label=cm.dynamic_select.label,
                               v_model=None)

        super().__init__(v_model=None,
                         align_center=True,
                         row=True,
                         class_='ma-1',
                         children=[self.prev, self.select, self.next])

        # js behaviour
        jslink((self, 'v_model'), (self.select, 'v_model'))
        self.prev.on_event('click', self._on_click)
        self.next.on_event('click', self._on_click)
Example #2
0
    def __init__(self, table, **kwargs):
        self.table = table

        update = v.Btn(children=['update'], color='success')
        close = v.Btn(children=['close'], color='error')

        self.form_1d = FormProperties_1D()
        self.form_2d = FormProperties_2D()

        self.form = v.CardText(children=self.form_1d.widget)

        self.dialog = v.Dialog(
            width='500',
            v_model=False,
            children=[
                v.Card(children=[
                    v.CardTitle(class_='headline gray lighten-2',
                                primary_title=True,
                                children=['Plot properties']), self.form,
                    v.CardActions(children=[v.Spacer(), update, close])
                ]),
            ])

        def close_btn(widget, event, data):
            self.dialog.v_model = False

        update.on_event('click', self.update_btn)
        close.on_event('click', close_btn)

        super().__init__(**kwargs)
Example #3
0
    def _initialize_widgets(self):
        """
        Initialize all widgets to display them
        """

        self.btn = v.Btn(
            color="blue",
            elevation=4,
            style_="width:150px;margin:auto;",
            outlined=True,
            children=[v.Icon(children=["get_app"]), "Save"],
        )

        self.reset = v.Btn(
            color="red",
            elevation=4,
            style_="width:150px;margin:auto;",
            outlined=True,
            children=["Reset"],
        )

        def resetwidgets(widget, event, data):

            clear_output(wait=True)
            self.display()

        self.btn.on_event("click", self.save)

        self.reset.on_event("click", resetwidgets)

        self.title_and_files = TitleAndFiles()
        self.driver = Driver()
        self.model = Model("model")
Example #4
0
    def __init__(self):
        with out:
            yes = v.Btn(children=['yes'],
                        class_='ma-2',
                        style_='width: 100px',
                        color='success')
            no = v.Btn(children=['no'],
                       class_='ma-2',
                       style_='width: 100px',
                       color='error')
            self.width = '500'
            self.v_model = False
            self.text = v.CardTitle(children=[])
            self.children = [
                v.Card(children=[
                    self.text,
                    v.CardActions(children=[v.Spacer(), yes, no])
                ]),
            ]

            self.path = None
            self.replace = True

            yes.on_event('click', self.yes_click)
            no.on_event('click', self.no_click)

            super().__init__()
    def __init__(self, label='', **kwargs):

        self.class_ = 'd-flex align-center mb-2'
        self.disabled = True
        self.row = True
        self.label = label

        super().__init__(**kwargs)

        self.w_prev = v.Btn(_metadata={'name': 'previous'},
                            x_small=True,
                            children=[
                                v.Icon(left=True,
                                       children=['mdi-chevron-left']), 'prev'
                            ])

        self.w_next = v.Btn(
            _metadata={'name': 'next'},
            x_small=True,
            children=[v.Icon(children=['mdi-chevron-right']), 'nxt'])

        self.w_list = v.Select(class_='ma-2',
                               label=self.label,
                               items=self.items,
                               v_model='')

        self.children = [self.w_prev, self.w_list, self.w_next]

        link((self.w_list, 'items'), (self, 'items'))
        link((self.w_list, 'v_model'), (self, 'v_model'))
        self.w_prev.on_event('click', self.prev_next_event)
        self.w_next.on_event('click', self.prev_next_event)
Example #6
0
    def __init__(self, vizapp, data=None, filename=None):

        self._vizapp = vizapp

        self.mostable = None
        self.mostable_dir = None
        self.data = data
        self.html = None
        self.current_cutout = None

        # Create control bar with drop down bar (OverflowBtn), back button, and next button

        self._back_button = v.Btn(children=["Back"], color="info")
        self._next_button = v.Btn(children=["Next"], color="info")

        self._back_button.on_event("click", self._on_back)
        self._next_button.on_event("click", self._on_next)

        self._control_bar = v.Layout(row=True, wrap=True, children=[self._back_button, self._next_button])

        self._current_slit = v.OverflowBtn(label="Slit", v_model=None,  items=[], width=10)
        self._current_slit.observe(self._on_change_current_slit, names=['v_model'])

        # Add to menu bar
        self._menu_bar = v.Layout(row=True, wrap=True, children=[
                                    v.Flex(xs6=True, class_='px-2', children=[self._current_slit]),
                                    v.Flex(xs6=True, class_='px-2', children=[self._control_bar])

        ])

        # Create table and mos_widget

        # the table viewer must be built with the data already in. This allows the
        # column headers to be properly set (it's an ipysheet API constraint). For
        # now, the code only works when data is not None.
        self._table = MOSVizTable(session=self._vizapp.glue_app.session, data=data)
        self._mos_widget = MOSVizWidget(session=self._vizapp.glue_app.session)

        # Combine into main

        self._main_box = v.Layout(row=True, wrap=True, children=[
            self._menu_bar, self._table.show(), self._mos_widget
        ])

        if data:
            self.add_data(data)

        # not sure on how this works. Probably depends on what we
        # want the user interface to look at the notebook level.
        # It's not being exercised yet.
        if filename:
            self._vizapp.glue_app.load_data(filename)
Example #7
0
    def __init__(self, table, schema, *args, default=None, **kwargs):
        """
        
        Dialog to modify/create new elements from the ClassTable data table
        
        Args: 
            table (ClassTable, v.DataTable): Table linked with dialog
            schema (dict {'title':'type'}): Schema for table showing headers and type of data
            default (dict): Dictionary with default valules
        """

        self.table = table
        self.default = default
        self.title = "New element" if not self.default else "Modify element"
        self.schema = schema
        self.v_model = True
        self.max_width = 500
        self.overlay_opcity = 0.7

        # Action buttons
        self.save = v.Btn(children=['Save'])
        save_tool = sw.Tooltip(self.save, 'Create new element')

        self.cancel = v.Btn(children=['Cancel'])
        cancel_tool = sw.Tooltip(self.cancel, 'Ignore changes')

        self.modify = v.Btn(children=['Modify'])
        modify_tool = sw.Tooltip(self.modify, 'Update row')

        save = [save_tool, cancel_tool]
        modify = [modify_tool, cancel_tool]

        actions = v.CardActions(children=save if not default else modify)

        super().__init__(*args, **kwargs)

        self.children=[
            v.Card(
                class_='pa-4',
                children=[
                    v.CardTitle(children=[self.title])] + \
                    self._get_widgets() + \
                    [actions]
            )
        ]

        # Create events

        self.save.on_event('click', self._save)
        self.modify.on_event('click', self._modify)
        self.cancel.on_event('click', self._cancel)
Example #8
0
    def __init__(self, title='SEPAL module', **kwargs):

        self.toggle_button = v.Btn(icon=True,
                                   children=[
                                       v.Icon(class_="white--text",
                                              children=['mdi-dots-vertical'])
                                   ])

        super().__init__(
            color=sepal_main,
            class_="white--text",
            dense=True,
            app=True,
            children=[self.toggle_button,
                      v.ToolbarTitle(children=[title])],
            **kwargs)

        def setTitle(self, title):
            """set the title in the appbar"""

            self.children = [
                self.toolBarButton,
                v.ToolbarTitle(children=[title])
            ]

            return self
Example #9
0
 def create_link_button(self, target, text, icon):
     return v.Btn(
         class_="mx-2",
         href=target,
         target="_blank",
         children=[v.Icon(children=[icon]), text],
     )
Example #10
0
def provider_buttons(providers):
    """ Generates a collection of provider buttons for a backend.

    Parameters:
        providers (list): A list of providers.

    Returns:
        VBox: An ipywidgets VBox instance.
    """
    vbox_buttons = []
    for pro in providers:
        button = wid.Box(children=[
            vue.Btn(color='#f5f5f5',
                    small=True,
                    children=[pro],
                    style_="font-family: Arial, sans-serif; font-size:10px;")
        ],
                         layout=wid.Layout(margin="0px 0px 2px 0px",
                                           width='350px'))

        button.children[0].on_event('click', _copy_text)
        vbox_buttons.append(button)

    return wid.VBox(children=vbox_buttons,
                    layout=wid.Layout(width='350px', max_width='350px'))
Example #11
0
def AppBar(title='SEPAL module'):
    """
    create an appBar widget with the provided title using the sepal color framework
    
    Returns: 
        app (v.AppBar) : The created appbar
        toolbarButton (v.Btn) : The button to display the side drawer
    """

    toolBarButton = v.Btn(
        icon = True, 
        children=[
            v.Icon(class_="white--text", children=['mdi-dots-vertical'])
        ]
    )
    
    appBar = v.AppBar(
        color=sepal_main,
        class_="white--text",
        dense=True,
        app = True,
        children = [
            toolBarButton, 
            v.ToolbarTitle(children=[title]),
        ]
    )
    
    return (appBar, toolBarButton)
Example #12
0
def provider_buttons(providers: List[str]) -> wid.VBox:
    """Generate a collection of provider buttons for a backend.

    When one of these buttons is clicked, the code to get the particular
    provider is copied to the clipboard.

    Args:
        providers: A list of provider names.

    Returns:
        A widget with provider buttons.
    """
    vbox_buttons = []
    for pro in providers:
        button = wid.Box(children=[vue.Btn(color='#f5f5f5', small=True,
                                           children=[pro],
                                           style_="font-family: Arial,"
                                                  "sans-serif; font-size:10px;")],
                         layout=wid.Layout(margin="0px 0px 2px 0px",
                                           width='350px'))

        button.children[0].on_event('click', _copy_text)
        vbox_buttons.append(button)

    return wid.VBox(children=vbox_buttons,
                    layout=wid.Layout(width='350px',
                                      max_width='350px'))
Example #13
0
    def __init__(self):

        title = v.CardTitle(children=[cm.quintile.clip.title])
        self.link = v.TextField(
            class_="ma-5",
            v_model=None,
            outlined=True,
            label=cm.quintile.clip.lbl,
            hint=cm.quintile.clip.hint,
            persistent_hint=True,
            readonly=True,
            append_icon="mdi-clipboard-outline",
        )

        self.done = v.Btn(color="primary",
                          outlined=True,
                          children=[cm.quintile.clip.done])

        self.card = v.Card(
            children=[title, self.link,
                      v.CardActions(children=[self.done])])

        super().__init__(value=False,
                         persistent=True,
                         max_width="600px",
                         children=[self.card])

        # js links
        self.done.on_event("click", self._done_click)
Example #14
0
    def __init__(self, states):
        """
        Create a list of state items and a plus button to add new states.

        Parameter
        =========

        states: list
            The list of default states defined by the test case.

        """
        self.states = states
        self.default_state = self.states[0]
        super().__init__(self.default_state)

        self.eval_stab = v.Btn(children=['Check stability'], color='primary')

        for s in states:
            self.item_list.children.append(self.create_item(s))

        self.item_list.notify_change({'name': 'children', 'type': 'change'})

        self.widget = v.Card(children=[
            v.CardTitle(children=['List of linear states', v.Spacer(), self.add_button]),
            v.CardText(children=[self.item_list]),
            v.CardActions(children=[v.Spacer(), self.eval_stab])
        ])
Example #15
0
    def __init__(self, model):
        self.model = model

        self.panels = v.ExpansionPanels(accordion=True, multiple=True, v_model=[])
        up = 'keyboard_arrow_up'
        down = 'keyboard_arrow_down'
        legend_icon = v.Icon(children=[down])
        self.legend_button = v.Btn(icon=True, children=[legend_icon])
        # Style to remove gray background in panels, and remove padding in panel contents
        panel_style = v.Html(tag='style', children=[(
            ".v-application--wrap{background-color: white!important}"
            ".v-expansion-panel-content__wrap{padding:0!important}"
            ".v-input__slot .v-label{color: black!important}"
        )])

        def a(): self.widgets = VBox([self.panels, panel_style], layout=Layout(padding='0px', border='1px solid black', width='400px'))
        def b(): self.accesses = Accesses(model, self.update_selection)
        def c(): self.stats = PlotStats(model)
        def d(): self.tags = Tags(model, self.update_selection, tag_type=TAG_TYPE_SPACETIME)
        def e(): self.threads = Tags(model, self.update_selection, tag_type=TAG_TYPE_THREAD)
        def m(): self.mearsurement = PlotMeasure(model)
        def f(): self.add_panel(LEGEND_MEM_ACCESS_TITLE, self.accesses.widgets)
        def g(): self.add_panel(LEGEND_TAGS_TITLE, self.tags.widgets)
        def h(): self.add_panel(LEGEND_THREADS_TITLE, self.threads.widgets)
        #def i(): self.add_panel(LEGEND_STATS_TITLE, self.stats.widgets)
        def n(): self.add_panel(LEGEND_MEASUREMENT_TITLE, self.mearsurement.widgets)

        self.progress_bar([
            a,
            b,
            c,
            d,
            e,
            m,
            f,
            g,
            h,
            #i,
            n
            ])

        # give accesses nformation about tags and threads for layers



        def update_legend_icon(_panels, _, selected):
            if len(selected) == len(self.panels.children):
                legend_icon.children = [up]
            elif selected == []:
                legend_icon.children = [down]
        self.panels.on_event('change', update_legend_icon)

        def update_panels(*args):
            if legend_icon.children[0] == up:
                legend_icon.children = [down]
                self.panels.v_model = []
            else:
                legend_icon.children = [up]
                self.panels.v_model = list(range(len(self.panels.children)))
        self.legend_button.on_event('click', update_panels)
Example #16
0
    def __init__(self, table, out_path, *args, **kwargs):
        """

        Dialog to save as .csv file the content of a ClassTable data table

        Args:
            table (ClassTable, v.DataTable): Table linked with dialog
            out_path (str): Folder path to store table content
        """
        self.max_width = 500
        self.v_model = False
        self.out_path = out_path

        super().__init__(*args, **kwargs)

        self.table = table

        self.w_file_name = v.TextField(label="Insert output file name",
                                       type="string",
                                       v_model="new_table.csv")

        # Action buttons
        self.save = v.Btn(children=["Save"])
        save = sw.Tooltip(self.save, "Save table")

        self.cancel = v.Btn(children=["Cancel"])
        cancel = sw.Tooltip(self.cancel, "Cancel")

        info = (sw.Alert().add_msg("The table will be stored in {}".format(
            str(out_path))).show())

        self.children = [
            v.Card(
                class_="pa-4",
                children=[
                    v.CardTitle(children=["Save table"]),
                    self.w_file_name,
                    info,
                    save,
                    cancel,
                ],
            )
        ]

        # Create events
        self.save.on_event("click", self._save)
        self.cancel.on_event("click", self._cancel)
Example #17
0
def DownloadBtn(text, path="#"):
    btn = v.Btn(class_='ma-2',
                xs5=True,
                color='success',
                href=utils.create_download_link(path),
                children=[v.Icon(left=True, children=['mdi-download']), text])

    return btn
Example #18
0
    def __init__(self, table, **kwargs):
        self.table = table

        update = v.Btn(children=['update'])
        close = v.Btn(children=['close'])

        self.form = [
            IntField(label='linewidth', v_model=plot_config['linewidth']),
            v.Select(label='Line style',
                     items=[{
                         'text': v,
                         'value': k
                     } for k, v in Line2D.lineStyles.items()],
                     v_model=plot_config['linestyle']),
            v.Select(label='Marker',
                     items=[{
                         'text': v,
                         'value': k
                     } for k, v in Line2D.markers.items()],
                     v_model=plot_config['marker']),
            IntField(label='Marker size', v_model=plot_config['markersize']),
            FloatField(label='alpha', v_model=plot_config['alpha']),
            v.ColorPicker(v_model=plot_config['colors'][0]),
        ]

        self.dialog = v.Dialog(
            width='500',
            v_model=False,
            children=[
                v.Card(children=[
                    v.CardTitle(class_='headline gray lighten-2',
                                primary_title=True,
                                children=['Plot properties']),
                    v.CardText(children=self.form),
                    v.CardActions(children=[v.Spacer(), update, close])
                ]),
            ])

        def close_btn(widget, event, data):
            self.dialog.v_model = False

        update.on_event('click', self.update_btn)
        close.on_event('click', close_btn)
        super().__init__(**kwargs)
Example #19
0
    def __init__(self, *args, **kwargs):
        self.form = self.form_class(*args, **kwargs)

        update_btn = v.Btn(children=['update'], color='success')
        close_btn = v.Btn(children=['close'], color='error')

        self.update_dialog = v.Dialog(
            width='500',
            v_model=False,
            children=[
                v.Card(children=[
                    v.CardTitle(class_='headline gray lighten-2',
                                primary_title=True,
                                children=[self.update_text]),
                    v.CardText(children=[self.form]),
                    v.CardActions(children=[v.Spacer(), update_btn, close_btn])
                ]),
            ])

        update_btn.on_event('click', self.update_click)
        close_btn.on_event('click', self.close_click)

        self.content = v.CardText(children=[f'{self}'])

        self.btn = v.Btn(
            children=[v.Icon(children=['mdi-close'])],
            fab=True,
            color='error',
            dark=True,
            x_small=True,
        )

        super().__init__(children=[
            v.ListItemAction(children=[self.btn]),
            v.ListItemContent(children=[
                v.Card(
                    children=[self.content],
                    flat=True,
                    color='transparent',
                    light=True,
                ), self.update_dialog
            ]),
        ],
                         **kwargs)
Example #20
0
    def create_show_example(self) -> v.Btn:
        btn = v.Btn(class_="mx-2", children=["Show example"])

        def on_click(*_):
            self.heatmap_plot.children = [
                v.Img(src="examples/data/processed/png/liverpool.png"),
            ]

        btn.on_event("click", on_click)
        return btn
Example #21
0
    def __init__(self,
                 extentions=['.txt'],
                 folder=os.path.expanduser('~'),
                 label='select file',
                 **kwargs):

        self.extentions = extentions
        self.folder = folder

        self.selected_file = v.TextField(label='file', v_model=self.file)

        self.file_list = v.List(
            dense=True,
            color='grey lighten-4',
            flat=True,
            children=[v.ListItemGroup(children=self.get_items(), v_model='')])

        self.file_menu = v.Menu(min_width=300,
                                children=[self.file_list],
                                close_on_content_click=False,
                                max_height='300px',
                                v_slots=[{
                                    'name':
                                    'activator',
                                    'variable':
                                    'x',
                                    'children':
                                    v.Btn(v_model=False,
                                          v_on='x.on',
                                          children=[label])
                                }])

        super().__init__(row=True,
                         class_='pa-5',
                         align_center=True,
                         children=[
                             v.Flex(xs12=True, children=[self.selected_file]),
                             v.Flex(xs12=True, children=[self.file_menu])
                         ],
                         **kwargs)

        link((self.selected_file, 'v_model'), (self, 'file'))

        def on_file_select(change):

            new_value = change['new']
            if new_value:
                if os.path.isdir(new_value):
                    self.folder = new_value
                    self.change_folder()

                elif os.path.isfile(new_value):
                    self.file = new_value

        self.file_list.children[0].observe(on_file_select, 'v_model')
Example #22
0
    def __init__(self, table, out_path, *args, **kwargs):
        """
        
        Dialog to save as .csv file the content of a ClassTable data table
        
        Args: 
            table (ClassTable, v.DataTable): Table linked with dialog
            out_path (str): Folder path to store table content
        """
        self.max_width = 500
        self.v_model = False
        self.out_path = out_path

        super().__init__(*args, **kwargs)

        self.table = table

        self.w_file_name = v.TextField(label='Insert output file name',
                                       type='string',
                                       v_model='new_table.csv')

        # Action buttons
        self.save = v.Btn(children=['Save'])
        save = sw.Tooltip(self.save, 'Save table')

        self.cancel = v.Btn(children=['Cancel'])
        cancel = sw.Tooltip(self.cancel, 'Cancel')

        info = sw.Alert().add_msg('The table will be stored in {}'.format(
            str(out_path))).show()

        self.children = [
            v.Card(class_='pa-4',
                   children=[
                       v.CardTitle(children=['Save table']), self.w_file_name,
                       info, save, cancel
                   ])
        ]

        # Create events
        self.save.on_event('click', self._save)
        self.cancel.on_event('click', self._cancel)
Example #23
0
 def add_tool(self, tool):
     self.tools[tool.tool_id] = tool
     icon = Image.from_file(icon_path(tool.icon, icon_format='svg'), width=ICON_WIDTH)
     button = v.Btn(v_on="tooltip.on", icon=True, children=[icon], value=tool.tool_id)
     annotated = v.Tooltip(
         bottom=True,
         v_slots=[{
             'name': 'activator',
             'variable': 'tooltip',
             'children': button}],
         children=[tool.tool_tip])
     self.children = list(self.children) + [annotated]
Example #24
0
def ProcessBtn(text="Launch process"):
    """
    create a process button filled with the provided text
    
    Returns: 
        btn (v.Btn) : the btn
    """
    btn = v.Btn(
        color='primary',
        children=[v.Icon(left=True, children=['mdi-map-marker-check']), text])

    return btn
Example #25
0
    def test_hide_component(self):

        # hide a normal v component
        widget = v.Btn()
        su.hide_component(widget)
        self.assertIn('d-none', widget.class_)

        # hide a sepalwidget
        widget = sw.Btn()
        su.hide_component(widget)
        self.assertFalse(widget.viz)

        return
def construct_nav(gui, page_change_func):
    page_buttons = []

    for page_name in gui.page_name_to_page.keys():

        btn = v.Btn(text=True, block=False, children=[page_name])

        btn.on_event("click", page_change_func)
        page_buttons += [btn]

    navigation = v.Container(_metadata={"mount_id": "content-nav"},
                             children=page_buttons)

    return navigation
Example #27
0
    def test_show_component(self):

        # show a normal v component
        widget = v.Btn()
        su.hide_component(widget)
        su.show_component(widget)
        self.assertNotIn('d-none', widget.class_)

        # show a sepalwidget
        widget = sw.Btn()
        su.hide_component(widget)
        su.show_component(widget)
        self.assertTrue(widget.viz)

        return
Example #28
0
    def __init__(self, statement, choices):

        # get number of choices
        self.num_choices = len(choices)
        self.choices = choices

        # Shuffle answers
        self.indices = [i for i in range(self.num_choices)]
        random.shuffle(self.indices)
        self.correct = self.indices.index(0)

        # Define CSS properties to make text larger
        display(HTML("<style>.large_font { font-size: 100% }</style>"))
        display(HTML("<style>.xlarge_font { font-size: 120% }</style>"))

        # store the statement in a widget
        self.statement = w.HTMLMath(value=statement)

        # enlarge text
        self.statement.add_class("xlarge_font")

        # Create labels for each answer choice
        answers = [
            w.Label(value=self.choices[self.indices[i]])
            for i in range(self.num_choices)
        ]

        # Enlarge text for labels
        for a in answers:
            a.add_class("large_font")

        # Create radio buttons with answers as labels (slots)
        self.choice_buttons = v.RadioGroup(v_model=None,
                                           children=[
                                               v.Radio(v_slots=[{
                                                   'name': 'label',
                                                   'children': [a]
                                               }]) for a in answers
                                           ])

        # Create a submit button
        self.check_button = v.Btn(color='primary', children=['Check Answer'])

        # If button is clicked, check the currently selected answer
        self.check_button.on_event("click", self.on_click_submit)

        # Create a feedback area
        self.feedback = w.Output()
Example #29
0
    def __init__(self, title='SEPAL module', **kwargs):

        self.toggle_button = v.Btn(icon=True,
                                   children=[
                                       v.Icon(class_="white--text",
                                              children=['mdi-dots-vertical'])
                                   ])

        self.title = v.ToolbarTitle(children=[title])

        super().__init__(color=sepal_main,
                         class_="white--text",
                         dense=True,
                         app=True,
                         children=[self.toggle_button, self.title],
                         **kwargs)
Example #30
0
    def __init__(self, model):
        self.model = model

        self.panels = v.ExpansionPanels(accordion=True,
                                        multiple=True,
                                        v_model=[])
        up = 'keyboard_arrow_up'
        down = 'keyboard_arrow_down'
        legend_icon = v.Icon(children=[down])
        self.legend_button = v.Btn(icon=True, children=[legend_icon])
        # Style to remove gray background in panels, and remove padding in panel contents
        panel_style = v.Html(
            tag='style',
            children=[
                ".v-application--wrap{background-color: white!important} .v-expansion-panel-content__wrap{padding:0!important}"
            ])
        self.widgets = VBox([self.panels, panel_style],
                            layout=Layout(padding='0px',
                                          border='1px solid black',
                                          width='400px'))
        self.accesses = Accesses(model, self.update_selection)
        self.stats = PlotStats(model)
        self.tags = Tags(model, self.update_selection)
        self.add_panel(LEGEND_MEM_ACCESS_TITLE, self.accesses.widgets)
        self.add_panel(LEGEND_TAGS_TITLE, self.tags.widgets)
        self.add_panel(LEGEND_STATS_TITLE, self.stats.widgets)

        def update_legend_icon(_panels, _, selected):
            if len(selected) == len(self.panels.children):
                legend_icon.children = [up]
            elif selected == []:
                legend_icon.children = [down]

        self.panels.on_event('change', update_legend_icon)

        def update_panels(*args):
            if legend_icon.children[0] == up:
                legend_icon.children = [down]
                self.panels.v_model = []
            else:
                legend_icon.children = [up]
                self.panels.v_model = list(range(len(self.panels.children)))

        self.legend_button.on_event('click', update_panels)