return ['width', 'height', 'color', 'line-width', 'fill', 'value', 'time-period-from', 'time-period-to'];
class ZSparkline extends HTMLElement {
static ZBX_STYLE_CLASS = 'svg-sparkline';
static ZBX_STYLE_CLASS_LINE = 'svg-sparkline-line';
static ZBX_STYLE_CLASS_AREA = 'svg-sparkline-area';
static PADDING_VERTICAL = 2;
static DEFAULT_COLOR = '#42A5F5';
static DEFAULT_LINE_WIDTH = 1;
#xAccessor = value => value.x;
#yAccessor = value => value.y;
customElements.whenDefined('z-sparkline').then(() => {
if (this.#container !== undefined) {
this.#container = d3.select(this);
this.#width = parseFloat(this.#container.attr('width')) || this.offsetWidth;
this.#height = parseFloat(this.#container.attr('height')) || this.offsetHeight;
const color = this.#container.attr('color');
this.#color = isColorHex(color) ? color : ZSparkline.DEFAULT_COLOR;
const line_width = parseInt(this.#container.attr('line-width'));
this.#line_width = !isNaN(line_width) ? line_width : ZSparkline.DEFAULT_LINE_WIDTH;
const fill = parseInt(this.#container.attr('fill'));
this.#fill = !isNaN(fill) ? fill : ZSparkline.DEFAULT_FILL;
this.#points = ZSparkline.#parsePoints(this.#container.attr('value'));
from: parseInt(this.#container.attr('time-period-from')) || d3.min(this.#points, this.#xAccessor),
to: parseInt(this.#container.attr('time-period-to')) || d3.max(this.#points, this.#xAccessor)
this.#xScale = d3.scaleTime().domain(this.#getXScaleDomain()).range(this.#getXScaleRange());
this.#yScale = d3.scaleLinear().domain(this.#getYScaleDomain()).range(this.#getYScaleRange());
this.#areaGenerator = d3.area()
.x(d => this.#xScale(this.#xAccessor(d)))
.y1(d => this.#yScale(this.#yAccessor(d)))
.defined(d => !isNaN(this.#yAccessor(d)));