| /** |
| * @module modules/side-panel-sk |
| * @description <h2><code>side-panel-sk</code></h2> |
| * |
| * Element for showing the legend next to plot-google-chart-sk. |
| * The side panel comes with a left bar that will close or open the |
| * side panel. |
| * |
| * When there is only one trace in the dataframe, the legend will be empty. |
| * When the legend is empty, the side panel will have no content. |
| * It is recommended to hide this module if there is no content to show. |
| * |
| * This side panel can be adapted to also show the tooltip rather |
| * than have the tooltip hover over the data point. |
| */ |
| import { LitElement, html, css } from 'lit'; |
| import { customElement, property } from 'lit/decorators.js'; |
| import { classMap } from 'lit/directives/class-map.js'; |
| import { consume } from '@lit/context'; |
| |
| import { dataTableContext, DataTable } from '../dataframe/dataframe_context'; |
| import { legendFormatter, getLegend } from '../dataframe/traceset'; |
| import { defaultColors } from '../common/plot-builder'; |
| |
| import '@material/web/button/outlined-button.js'; |
| import '@material/web/iconbutton/icon-button.js'; |
| import '@material/web/icon/icon.js'; |
| |
| const chevronLeft = html`<svg |
| xmlns="http://www.w3.org/2000/svg" |
| viewBox="0 0 24 24" |
| fill="currentColor"> |
| <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" /> |
| </svg>`; |
| |
| const chevronRight = html`<svg |
| xmlns="http://www.w3.org/2000/svg" |
| viewBox="0 0 24 24" |
| fill="currentColor"> |
| <path d="M8.59 7.41L10 6l6 6-6 6-1.41-1.41L13.17 12z" /> |
| </svg>`; |
| |
| export interface SidePanelToggleEventDetails { |
| open: boolean; |
| } |
| |
| @customElement('side-panel-sk') |
| export class SidePanelSk extends LitElement { |
| static styles = css` |
| :host { |
| display: flex; |
| height: 100%; |
| border-radius: 8px; |
| overflow: scroll; /* legend entries can be very long */ |
| box-shadow: |
| 0px 2px 1px -1px rgba(0, 0, 0, 0.2), |
| 0px 1px 1px 0px rgba(0, 0, 0, 0.14), |
| 0px 1px 3px 0px rgba(0, 0, 0, 0.12); /* Elevation shadow */ |
| } |
| .show-hide-bar { |
| width: 20px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| } |
| .show-hide-bar:hover { |
| background-color: gray; |
| } |
| .info.closed { |
| display: none; |
| } |
| ul { |
| list-style: none; /* Remove default bullet points */ |
| padding-left: 5px; |
| font-size: 18px; |
| } |
| `; |
| |
| @property({ reflect: true, type: Boolean }) |
| opened = true; |
| |
| @consume({ context: dataTableContext, subscribe: true }) |
| @property({ attribute: false }) |
| private data?: DataTable; |
| |
| render() { |
| return html` |
| <div |
| class="show-hide-bar" |
| @click=${this.toggleSidePanel} |
| title=${this.opened ? 'Close panel' : 'Open panel'}> |
| <md-icon>${this.opened ? chevronRight : chevronLeft}</md-icon> |
| </div> |
| <div class="info ${classMap({ closed: !this.opened })}"> |
| <ul> |
| ${this.getLegend().map( |
| (item, index) => html` |
| <li style="color: ${defaultColors[index % defaultColors.length]}">${item}</li> |
| ` |
| )} |
| </ul> |
| </div> |
| `; |
| } |
| |
| private toggleSidePanel() { |
| this.opened = !this.opened; |
| this.dispatchEvent( |
| new CustomEvent<SidePanelToggleEventDetails>('side-panel-toggle', { |
| bubbles: true, |
| composed: true, |
| detail: { |
| open: this.opened, |
| }, |
| }) |
| ); |
| } |
| |
| private getLegend() { |
| if (this.data) { |
| const legend = legendFormatter(getLegend(this.data)); |
| return legend; |
| } |
| return []; |
| } |
| } |
| |
| declare global { |
| interface GlobalEventHandlersEventMap { |
| 'side-panel-toggle': CustomEvent<SidePanelToggleEventDetails>; |
| } |
| } |