Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 104 additions & 21 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class MiniGraphCard extends LitElement {
const queue = [];
this.config.entities.forEach((entity, index) => {
this.config.entities[index].index = index; // Required for filtered views
// entityState stands for "stateObj"
const entityState = hass && hass.states[entity.entity] || undefined;
if (entityState && this.entity[index] !== entityState) {
this.entity[index] = entityState;
Expand Down Expand Up @@ -212,7 +213,10 @@ class MiniGraphCard extends LitElement {
`;
}


/**
* Renders a header containing a name and an icon
* @returns HTML element
*/
renderHeader() {
const {
show, align_icon, align_header, font_size_header,
Expand All @@ -226,6 +230,10 @@ class MiniGraphCard extends LitElement {
: '';
}

/**
* Renders an icon
* @returns HTML element
*/
renderIcon() {
if (this.config.icon_image !== undefined) {
return html`
Expand All @@ -244,6 +252,10 @@ class MiniGraphCard extends LitElement {
` : '';
}

/**
* Renders a name
* @returns HTML element
*/
renderName() {
if (!this.config.show.name) return;
const name = this.tooltip.entity !== undefined
Expand All @@ -258,6 +270,10 @@ class MiniGraphCard extends LitElement {
`;
}

/**
* Renders states
* @returns HTML element
*/
renderStates() {
if (this.config.show.state)
return html`
Expand All @@ -284,35 +300,49 @@ class MiniGraphCard extends LitElement {
}
}

renderState(id) {
const isPrimary = id === 0; // rendering main state element?
if (isPrimary || this.config.entities[id].show_state) {
const state = this.getEntityState(id);
// use tooltip data for main state element, if tooltip is active
const { entity: tooltipEntity, value: tooltipValue } = this.tooltip;
const isTooltip = isPrimary && tooltipEntity !== undefined;
/**
* Renders a state/attrubute value (if "show_state: true")
* @returns HTML element
* @param {number} index Index of an entity in config.entities
*/
renderState(index) {
const isPrimary = index === 0; // rendering main entity state element?
if (isPrimary || this.config.entities[index].show_state) {
// get a state/attribute value
const state = this.getEntityState(index);
// use tooltip data for main entity state element, if tooltip is active
// "tooltip" - a selected point/bar
const { entity: tooltipEntityIndex, value: tooltipValue } = this.tooltip;
const isTooltip = isPrimary && tooltipEntityIndex !== undefined;
// either a state/attr for a selected point/bar - or a "native" state/attr
const value = isTooltip ? tooltipValue : state;
const entity = isTooltip ? tooltipEntity : id;
const entityConfig = this.config.entities[entity];
const entityIndex = isTooltip ? tooltipEntityIndex : index;
const entityConfig = this.config.entities[entityIndex];
return html`
<div
class="state ${!isPrimary && 'state--small'}"
@click=${e => this.handlePopup(e, this.entity[id])}
style=${entityConfig.state_adaptive_color ? `color: ${this.computeColor(value, entity)}` : ''}>
${entityConfig.show_indicator ? this.renderIndicator(value, entity) : ''}
@click=${e => this.handlePopup(e, this.entity[index])}
style=${entityConfig.state_adaptive_color ? `color: ${this.computeColor(value, entityIndex)}` : ''}
>
${entityConfig.show_indicator ? this.renderIndicator(value, entityIndex) : ''}
<span class="state__value ellipsis">
${this.computeState(value)}
</span>
<span class="state__uom ellipsis">
${this.computeUom(entity)}
${this.computeUom(entityIndex)}
</span>
${isPrimary && this.renderStateTime() || ''}
</div>
`;
}
}

/**
* Renders a "time interval" element for a selected point/bar
* @returns HTML element
*/
renderStateTime() {
// "tooltip" - a selected point/bar
if (this.tooltip.value === undefined) return;
return html`
<div class="state__time">
Expand Down Expand Up @@ -347,6 +377,11 @@ class MiniGraphCard extends LitElement {
</div>` : '';
}

/**
* Renders a legend entry for an entity
* @returns HTML element
* @param {number} index Index of an entity in config.entities
*/
computeLegend(index) {
let legend = this.computeName(index);
const state = this.getEntityState(index);
Expand All @@ -367,9 +402,13 @@ class MiniGraphCard extends LitElement {
return legend;
}

/**
* Renders a whole legend for all entities
* @returns HTML element
*/
renderLegend() {
// do not show a legend for only 1 entity or when a legend is globally disabled
if (this.visibleLegends.length <= 1 || !this.config.show.legend) return;

/* eslint-disable indent */
return html`
<div class="graph__legend">
Expand All @@ -390,6 +429,12 @@ class MiniGraphCard extends LitElement {
/* eslint-enable indent */
}

/**
* Renders an indicator for an entity
* @returns HTML element
* @param {string | number} state Value of a state/attribute
* @param {number} index Index of an entity in config.entities
*/
renderIndicator(state, index) {
return svg`
<svg width='10' height='10'>
Expand Down Expand Up @@ -599,6 +644,10 @@ class MiniGraphCard extends LitElement {
};
}

/**
* Renders primary Y-axis labels
* @returns HTML element
*/
renderLabels() {
if (!this.config.show.labels || this.primaryYaxisSeries.length === 0) return;
return html`
Expand All @@ -609,6 +658,10 @@ class MiniGraphCard extends LitElement {
`;
}

/**
* Renders secondary Y-axis labels
* @returns HTML element
*/
renderLabelsSecondary() {
if (!this.config.show.labels_secondary || this.secondaryYaxisSeries.length === 0) return;
return html`
Expand All @@ -619,6 +672,10 @@ class MiniGraphCard extends LitElement {
`;
}

/**
* Renders extrema & average info
* @returns HTML element
*/
renderInfo() {
return this.abs.length > 0 ? html`
<div class="info flex">
Expand Down Expand Up @@ -667,7 +724,14 @@ class MiniGraphCard extends LitElement {
return this.secondaryYaxisEntities.map(entity => this.Graph[entity.index]);
}

computeColor(inState, i) {
/**
* Returns a color for an entity
* accounting `color_thresholds`, global `line_color` & individual `color` settings
* @returns Color
* @param {string | number} inState Value of a state/attribute
* @param {number} index Index of an entity in config.entities
*/
computeColor(inState, index) {
const { color_thresholds, line_color } = this.config;
const state = Number(inState) || 0;

Expand All @@ -676,28 +740,42 @@ class MiniGraphCard extends LitElement {
const { color } = color_thresholds.find(ele => ele.value < state)
|| color_thresholds.slice(-1)[0];
intColor = color;
const index = color_thresholds.findIndex(ele => ele.value < state);
const c1 = color_thresholds[index];
const c2 = color_thresholds[index - 1];
const indexThreshold = color_thresholds.findIndex(ele => ele.value < state);
const c1 = color_thresholds[indexThreshold];
const c2 = color_thresholds[indexThreshold - 1];
if (c2) {
const factor = (c2.value - state) / (c2.value - c1.value);
intColor = interpolateRgb(c2.color, c1.color)(factor);
} else {
intColor = index
intColor = indexThreshold
? color_thresholds[color_thresholds.length - 1].color
: color_thresholds[0].color;
}
}

return this.config.entities[i].color || intColor || line_color[i] || line_color[0];
return this.config.entities[index].color
|| intColor
|| line_color[index] || line_color[0];
}

/**
* Returns a name of an entity accounting a `name` option
* @returns {string} Name of an entity
* @param {number} index Index of an entity in config.entities
*/
computeName(index) {
return this.config.entities[index].name
|| this.entity[index].attributes.friendly_name
|| this.entity[index].entity_id;
}

/**
* Returns an icon for an entity
* accounting an `icon` option, entity's native `icon` attribute,
* fallback to a standard MDI "temperature" icon
* @returns {string} mdi:icon
* @param {object} entity stateObj for an entity
*/
computeIcon(entity) {
return (
this.config.icon
Expand All @@ -707,6 +785,11 @@ class MiniGraphCard extends LitElement {
);
}

/**
* Returns a unit
* @returns {string} Unit
* @param {number} index Index of an entity in config.entities
*/
computeUom(index) {
return (
this.config.entities[index].unit !== undefined
Expand Down