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.
383 lines (377 loc) • 16.5 kB
JavaScript
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, property, state } from "lit/decorators.js";
import {
//attribute,
//csvToDataset,
randomColor, randomNumber, randomString,
// readFileInput,
} from "../../functions";
import style from "./AdvancedInput.style";
import SlButton from "@shoelace-style/shoelace/dist/components/button/button.component.js";
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 SlPopup from "@shoelace-style/shoelace/dist/components/popup/popup.component.js";
import { SharedTestStateMixin } from "../../state";
import { FileUploadButton } from "../FileUploadButton";
import { LitElementWw } from "@webwriter/lit";
import { Select } from "../Select";
//TODO: Add the color for columns to distinguish number or string
let AdvancedInput = class AdvancedInput extends SharedTestStateMixin(LitElementWw) {
constructor() {
super(...arguments);
//TODO: Check if this is good
this.remeberedStringOrNumber = [];
this.addColumnPopupOpen = false;
}
addDataset() {
let dataset = [];
if (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length > 0) {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[0].data.forEach((element) => {
typeof element === "number"
? dataset.push(randomNumber())
: dataset.push(element);
});
}
else {
this.remeberedStringOrNumber.forEach((element) => {
typeof element === "number"
? dataset.push(randomNumber())
: dataset.push(element);
});
}
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.push({
id: this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length > 0
? this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced
.sets[this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced
.sets.length - 1].id + 1
: 1,
data: dataset,
});
}
addFirstDataset() {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.color =
randomColor();
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels.push(randomString());
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.push({
id: 1,
data: Array(1)
.fill("")
.map(() => randomNumber()),
});
this.sharedState.scatterplotAdvanced.selectedX = "none";
this.sharedState.scatterplotAdvanced.selectedY = "none";
}
addNumberColumn() {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels.push(randomString());
if (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length > 0) {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets =
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.map((dataset) => {
dataset.data.push(randomNumber());
return dataset;
});
}
}
addStringColumn() {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels.push(randomString());
if (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length > 0) {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets =
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.map((dataset) => {
dataset.data.push(randomString());
return dataset;
});
}
}
deleteColumn(i) {
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels.splice(i, 1);
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets =
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.map((dataset) => {
dataset.data.splice(i, 1);
return dataset;
});
this.list_labels = ["none"].concat(this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels);
this.disabled = this.list_labels.length === 0 ? true : false;
}
deleteDataset(i) {
if (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length === 1) {
this.remeberedStringOrNumber =
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[0].data;
}
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets.splice(i, 1);
}
// TODO: Fix disable when delete all columns
// TODO: fix name of wwci-select while editing x and y axis names?
render() {
this.list_labels = ["none"].concat(this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels);
this.disabled = this.list_labels.length === 0 ? true : false;
if (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets
.length === 0 &&
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels
.length === 0)
return html `<sl-button
class="add-dataset-button"
=${() => this.addFirstDataset()}
>Add Dataset</sl-button
> `;
return html `
<div class="wrapper">
<div class="container">
<p class="text">X-Axis</p>
<wwci-select
.value="${this.list_labels.includes(this.sharedState.scatterplotAdvanced.selectedX)
? this.sharedState.scatterplotAdvanced.selectedX
: this.list_labels[0]}"
?disabled=${this.disabled}
.selectOptions="${this.list_labels}"
-change="${(e) => {
this.sharedState.scatterplotAdvanced.selectedX = e.target.value;
}}"
>
</wwci-select>
</div>
<div class="container">
<p class="text">Y-Axis</p>
<wwci-select
.value="${this.list_labels.includes(this.sharedState.scatterplotAdvanced.selectedY)
? this.sharedState.scatterplotAdvanced.selectedY
: this.list_labels[0]}"
?disabled=${this.disabled}
.selectOptions="${this.list_labels}"
-change="${(e) => {
this.sharedState.scatterplotAdvanced.selectedY = e.target.value;
}}"
>
</wwci-select>
</div>
<div class="table-layout-container">
<table>
<thead>
<tr>
<th>
<div
style="display: flex; flex-direction: row; align-items: center"
>
<div class="input-wrapper">
<p>ID</p>
</div>
${!this.sharedState.printable
? html `
<sl-color-picker
?disabled=${!(this.sharedState.editable ||
this.sharedState.teacherOptions.changeData)}
value="${this.sharedState.scatterplotAdvanced
.scatterplotdatasetsAdvanced.color}"
-input=${(e) => (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.color =
e.target.value)}
></sl-color-picker>
`
: html ``}
</div>
</th>
${this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.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}"
-input=${(e) => {
const prevValue = this.sharedState.scatterplotAdvanced
.scatterplotdatasetsAdvanced.labels[i];
const newValue = e.target.value;
this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.labels[i] = newValue;
if (this.sharedState.scatterplotAdvanced
.selectedX === prevValue) {
this.sharedState.scatterplotAdvanced.selectedX =
newValue;
}
if (this.sharedState.scatterplotAdvanced
.selectedY === prevValue) {
this.sharedState.scatterplotAdvanced.selectedY =
newValue;
}
}}
></sl-input>
</div>
${!this.sharedState.printable
? html `<sl-icon-button
?disabled=${!(this.sharedState.editable ||
this.sharedState.teacherOptions.addRemoveData)}
name="trash"
label="Settings"
=${() => this.deleteColumn(i)}
></sl-icon-button>`
: html ``}
</div>
</th>`)}
</tr>
</thead>
<tbody>
${this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.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)}
name="trash"
label="Settings"
=${() => 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.id}"
-input=${(e) => (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[i].id = e.target.value)}
></sl-input>
</div>
</div>
</td>
${this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[i].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="text or number"
class="input"
value="${value}"
-input=${(e) => typeof this.sharedState.scatterplotAdvanced
.scatterplotdatasetsAdvanced.sets[i].data[j] === "number"
? (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[i].data[j] = Number(e.target.value))
: (this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced.sets[i].data[j] = String(e.target.value))}
></sl-input>
</div>
</div>
</td>`)}
</tr>
`)}
</tbody>
</table>
${this.sharedState.editable ||
(this.sharedState.teacherOptions.addRemoveData &&
!this.sharedState.printable)
? html `
<sl-popup
placement="right"
strategy="fixed"
.active=${this.addColumnPopupOpen}
>
<sl-icon-button
slot="anchor"
name="plus-circle"
label="Add Column"
=${(e) => {
this.addColumnPopupOpen = true;
e.target.focus();
}}
=${() => (this.addColumnPopupOpen = false)}
></sl-icon-button>
<div class="popup-content">
<sl-button
=${(e) => {
if (e.button !== 0)
return;
this.addStringColumn();
this.addColumnPopupOpen = false;
}}
>
Text dataset
</sl-button>
<sl-button
=${(e) => {
if (e.button !== 0)
return;
this.addNumberColumn();
this.addColumnPopupOpen = false;
}}
>
Numeric dataset
</sl-button>
</div>
</sl-popup>
<sl-icon-button
=${() => this.addDataset()}
name="plus-circle"
label="Add Dataset"
></sl-icon-button>
<br />
`
: html ``}
</div>
</div>
`;
}
dispatchUpdateEvent() {
this.dispatchEvent(new CustomEvent("wwci-change", {
detail: {
value: this.sharedState.scatterplotAdvanced.scatterplotdatasetsAdvanced,
},
bubbles: false,
composed: true,
}));
}
dispatchTitleUpdateEvent(title) {
this.dispatchEvent(new CustomEvent("wwci-title-change", {
detail: {
value: title,
},
bubbles: false,
composed: true,
}));
}
static get scopedElements() {
return {
"sl-icon-button": SlIconButton,
"sl-input": SlInput,
"sl-color-picker": SlColorPicker,
"wwci-file-upload-button": FileUploadButton,
"wwci-select": Select,
"sl-button": SlButton,
"sl-popup": SlPopup,
};
}
};
AdvancedInput.styles = style;
__decorate([
property({ type: Array })
], AdvancedInput.prototype, "list_labels", void 0);
__decorate([
property({ type: Boolean })
], AdvancedInput.prototype, "disabled", void 0);
__decorate([
property({ type: Array })
], AdvancedInput.prototype, "remeberedStringOrNumber", void 0);
__decorate([
state()
], AdvancedInput.prototype, "addColumnPopupOpen", void 0);
AdvancedInput = __decorate([
customElement("wwci-advanced-input")
], AdvancedInput);
export { AdvancedInput };