我正在尝试使用LitElement构建图表。图表从用户那里获取数据属性,并显示此数据(图表图)。它还从数据中获取系列名称,以便显示带有每个系列复选框的图例,可用于在统计图中显示或隐藏该系列的数据。
下面是一个非常简单的示例,其中图表图只是包含数据点(3、5、4、7)的div,图例只是复选框。预期的行为是,当选择/取消选择复选框,在图表绘图对应的数据(数据的div)被示出/隐藏。例如,最初两个复选框都默认选中,并且两个系列的数据都正确显示。但是,如果取消选择第一个复选框,则我希望“ series1”的数据被隐藏,因此仅显示5和7。
这是复选框行为,我无法正常工作。当我选择或取消选择一个复选框时,我登录了this.series
,它似乎已正确更新,反映了选中了哪个复选框,但是图表(数据div)未更新。
import { LitElement, css, html } from "lit-element";
import { render } from "lit-html";
class TestElement extends LitElement {
static get properties() {
return {
data: { type: Array },
series: { type: Array },
};
}
constructor() {
super();
this.data = [];
this.series = [];
}
checkboxChange(e) {
const inputs = Array.from(this.shadowRoot.querySelectorAll("input")).map(n => n.checked);
this.series = this.series.map((s, i) => ({ ...s, checked: inputs[i] }));
console.log("this.series", this.series);
}
render() {
this.series = Object.keys(this.data[0]).map(key => ({ key, checked: true }));
const data = this.data.map(d => this.series.map(s => (s.checked ? html`<div>${d[s.key]}</div>` : "")));
const series = this.series.map(
s => html`<input type="checkbox" ?checked=${s.checked} @change=${this.checkboxChange} />`
);
return html`${data}${series}`;
}
}
customElements.define("test-element", TestElement);
render(
html`<test-element
.data=${[
{ series1: "3", series2: "5" },
{ series1: "4", series2: "7" },
]}
></test-element>`,
window.document.body
);
答案 0 :(得分:1)
尝试以下操作:
import { LitElement, html } from 'lit-element';
class TestElement extends LitElement {
static get properties() {
return {
data: { attribute: false, accessors: false },
series: { attribute: false, accessors: false },
checked: { attribute: false, accessors: false },
};
}
constructor() {
super();
this.data = [];
this.series = new Map();
this.checked = new Map();
}
get data() {
return this.__data || [];
}
set data(v) {
const oldValue = this.__data;
this.__data = Array.isArray(v) ? v : [];
this.series = new Map();
for (const row of this.data) {
for (const [series, value] of Object.entries(row)) {
this.series.set(series, [...this.series.get(series) || [], value])
}
}
for (const series of this.series.keys()) {
this.checked.set(series, this.checked.get(series) ?? true);
}
this.requestUpdate('data', oldValue);
this.requestUpdate('series', null);
this.requestUpdate('checked', null);
}
checkboxChange(e) {
this.checked.set(e.target.dataset.series, e.target.checked);
this.requestUpdate('checked', null);
}
render() {
return [
[...this.series.entries()].map(([series, values]) => values.map(value => html`
<div ?hidden="${!this.checked.get(series)}">${value}</div>
`)),
[...this.checked.entries()].map(([series, checked]) => html`
<input type="checkbox" ?checked=${checked} data-series="${series}" @change=${this.checkboxChange} />
`)
];
}
}
customElements.define("test-element", TestElement);
现场示例:https://webcomponents.dev/edit/FEbG9UA3nBMqtk9fwQrD/src/index.js
此解决方案提出了一些改进:
hidden
attr 隐藏未选中的系列attribute: false
而不是 type: Array
(假设您不需要从属性反序列化 data
。