UNPKG

webwriter-chart

Version:

ww-chart is an interactive data visualization widget for the WebWriter tool that implements various charts and diagrams for static and exploratory data visualization.

226 lines (220 loc) 9.78 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { html } from "lit"; import { customElement } from "lit/decorators.js"; import { csvToDataset, randomColor, randomNumber, randomString, readFileInput, } from "../../functions"; import style from "./DatasetInput.style"; import SlIconButton from "@shoelace-style/shoelace/dist/components/icon-button/icon-button.js"; import SlInput from "@shoelace-style/shoelace/dist/components/input/input.js"; import SlColorPicker from "@shoelace-style/shoelace/dist/components/color-picker/color-picker.js"; import IconTrash from "bootstrap-icons/icons/trash.svg"; import IconPlusCircle from "bootstrap-icons/icons/plus-circle.svg"; import { SharedTestStateMixin } from "../../state"; import { FileUploadButton } from "../FileUploadButton"; import { LitElementWw } from "@webwriter/lit"; let DatasetInput = class DatasetInput extends SharedTestStateMixin(LitElementWw) { addDataset() { this.sharedState.chart.datasets.sets.push({ name: randomString(), color: randomColor(), colors: this.sharedState.chart.datasets.sets[0].colors, data: Array(this.sharedState.chart.datasets.sets[0].data.length) .fill("") .map(() => randomNumber()), }); } addColumn() { this.sharedState.chart.datasets.labels.push(randomString()); this.sharedState.chart.datasets.sets = this.sharedState.chart.datasets.sets.map((dataset) => { dataset.data.push(randomNumber()); dataset.colors.push(randomColor()); return dataset; }); } deleteColumn(i) { this.sharedState.chart.datasets.labels.splice(i, 1); this.sharedState.chart.datasets.sets = this.sharedState.chart.datasets.sets.map((dataset) => { dataset.data.splice(i, 1); dataset.colors.splice(i, 1); return dataset; }); } deleteDataset(i) { this.sharedState.chart.datasets.sets.splice(i, 1); } render() { if (this.sharedState.chart.datasets.sets.length === 0) return html `<sl-button @click=${this.addDataset}>Add Dataset</sl-button>`; return html `<div class="table-wrapper"> <div class="table-scroll-container"> <div class="table-layout-container"> <table> <thead> <tr> <th>Labels</th> ${this.sharedState.chart.datasets.labels.map((label, i) => html `<th> <div style="display: flex; flex-direction: row; align-items: center" > <div class="input-wrapper"> <sl-input ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.changeData)} type="text" class="input" value="${label}" @sl-input=${(e) => (this.sharedState.chart.datasets.labels[i] = e.target.value)} ></sl-input> </div> ${!this.sharedState.printable ? html `<sl-icon-button ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.addRemoveData)} src=${IconTrash} label="Settings" @click=${() => this.deleteColumn(i)} ></sl-icon-button>` : html ``} </div> </th>`)} </tr> </thead> <tbody> ${this.sharedState.chart.datasets.sets.map((dataset, i) => html ` <tr> <td> <div style="display: flex; flex-direction: row; align-items: center" > ${!this.sharedState.printable ? html ` <sl-icon-button ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.addRemoveData)} src=${IconTrash} label="Settings" @click=${() => this.deleteDataset(i)} ></sl-icon-button>` : html ``} <div class="input-wrapper"> <sl-input ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.changeData)} id="input" type="text" class="input" value="${dataset.name}" @sl-input=${(e) => (this.sharedState.chart.datasets.sets[i].name = e.target.value)} ></sl-input> </div> ${!this.sharedState.printable ? html ` <sl-color-picker ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.changeData)} value="${this.sharedState.chart.datasets.sets[i] .color}" @sl-input=${(e) => (this.sharedState.chart.datasets.sets[i].color = e.target.value)} ></sl-color-picker> ` : html ``} </div> </td> ${dataset.data.map((value, j) => html `<td> <div style="display: flex; flex-direction: row; align-items: center" > <div class="input-wrapper"> <sl-input ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.changeData)} id="input-${i}-${j}" type="number" class="input" value="${value}" @sl-input=${(e) => (this.sharedState.chart.datasets.sets[i].data[j] = Number(e.target.value))} ></sl-input> </div> ${!this.sharedState.printable ? html `<sl-color-picker ?disabled=${!(this.sharedState.editable || this.sharedState.teacherOptions.changeData)} value="${this.sharedState.chart.datasets.sets[i].colors[j]}" @sl-input=${(e) => (this.sharedState.chart.datasets.sets[i].colors[j] = e.target.value)} ></sl-color-picker>` : html ``} </div> </td>`)} </tr> `)} </tbody> </table> ${this.sharedState.editable || (this.sharedState.teacherOptions.addRemoveData && !this.sharedState.printable) ? html ` <sl-icon-button @click=${this.addColumn} src=${IconPlusCircle} label="Add Column" ></sl-icon-button> <sl-icon-button @click=${this.addDataset} src=${IconPlusCircle} label="Add Dataset" ></sl-icon-button> <br /> <wwci-file-upload-button @wwcifileinput=${async (e) => { const fileContent = await readFileInput(e.detail.value); const { datasets, title } = csvToDataset(fileContent); this.sharedState.chart.datasets = datasets; if (title) this.dispatchTitleUpdateEvent(title); }} ></wwci-file-upload-button> ` : html ``} </div> </div> </div>`; } dispatchUpdateEvent() { this.dispatchEvent(new CustomEvent("wwci-change", { detail: { value: this.sharedState.chart.datasets, }, bubbles: false, composed: true, })); } dispatchTitleUpdateEvent(title) { this.dispatchEvent(new CustomEvent("wwci-title-change", { detail: { value: title, }, bubbles: false, composed: true, })); } static styles = style; static get scopedElements() { return { "sl-icon-button": SlIconButton, "sl-input": SlInput, "sl-color-picker": SlColorPicker, "wwci-file-upload-button": FileUploadButton, }; } }; DatasetInput = __decorate([ customElement("wwci-dataset-input") ], DatasetInput); export { DatasetInput };