unique_bubble_graph.yaml aktualisiert
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
unique_bubble_graph:
|
||||
name: Unique Bubble Multi History Background Graph
|
||||
version: 2.8.6
|
||||
version: 2.8.7
|
||||
creator: Torsten
|
||||
supported:
|
||||
- button
|
||||
@@ -120,6 +120,26 @@ unique_bubble_graph:
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bubble-history-point-markers {
|
||||
position: absolute !important;
|
||||
inset: 0 !important;
|
||||
z-index: 8 !important;
|
||||
display: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bubble-history-point-marker {
|
||||
position: absolute !important;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
box-shadow:
|
||||
0 0 0 2px rgba(20, 20, 20, 0.55),
|
||||
0 0 8px rgba(255, 255, 255, 0.65);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.bubble-button-card-container,
|
||||
.bubble-button-card,
|
||||
.bubble-name-container,
|
||||
@@ -175,6 +195,9 @@ unique_bubble_graph:
|
||||
|
||||
const extendToNow = cfg.extend_to_now !== false;
|
||||
const extendThresholdMinutes = Number(cfg.extend_threshold_minutes ?? 2);
|
||||
const tooltipIndicator = ["points", "line", "both", "none"].includes(cfg.tooltip_indicator)
|
||||
? cfg.tooltip_indicator
|
||||
: "points";
|
||||
|
||||
const sameScale = cfg.same_scale === true;
|
||||
const numberOrNull = (value) => {
|
||||
@@ -360,6 +383,7 @@ unique_bubble_graph:
|
||||
let bg = host.querySelector(".bubble-history-background");
|
||||
let tooltip = host.querySelector(".bubble-history-tooltip");
|
||||
let marker = host.querySelector(".bubble-history-marker");
|
||||
let pointLayer = host.querySelector(".bubble-history-point-markers");
|
||||
let loader = host.querySelector(".bubble-history-loader");
|
||||
|
||||
if (!bg) {
|
||||
@@ -381,6 +405,12 @@ unique_bubble_graph:
|
||||
host.appendChild(marker);
|
||||
}
|
||||
|
||||
if (!pointLayer) {
|
||||
pointLayer = document.createElement("div");
|
||||
pointLayer.className = "bubble-history-point-markers";
|
||||
host.appendChild(pointLayer);
|
||||
}
|
||||
|
||||
if (!loader) {
|
||||
loader = document.createElement("div");
|
||||
loader.className = "bubble-history-loader";
|
||||
@@ -537,7 +567,10 @@ unique_bubble_graph:
|
||||
|
||||
host.__bubbleHistoryTooltip = tooltip;
|
||||
host.__bubbleHistoryMarker = marker;
|
||||
host.__bubbleHistoryPointLayer = pointLayer;
|
||||
host.__bubbleHistoryTooltipTop = tooltipTop;
|
||||
host.__bubbleHistoryTooltipIndicator = tooltipIndicator;
|
||||
host.__bubbleHistoryPaddingY = paddingY;
|
||||
|
||||
if (host.__bubbleHistoryTooltipAttached) return;
|
||||
|
||||
@@ -551,8 +584,9 @@ unique_bubble_graph:
|
||||
|
||||
const tooltipElement = host.__bubbleHistoryTooltip;
|
||||
const markerElement = host.__bubbleHistoryMarker;
|
||||
const pointLayerElement = host.__bubbleHistoryPointLayer;
|
||||
|
||||
if (!tooltipElement || !markerElement) return;
|
||||
if (!tooltipElement || !markerElement || !pointLayerElement) return;
|
||||
|
||||
const rect = host.getBoundingClientRect();
|
||||
const xRatio = Math.min(1, Math.max(0, (event.clientX - rect.left) / rect.width));
|
||||
@@ -568,11 +602,15 @@ unique_bubble_graph:
|
||||
: Math.max(...usableSeries.map((series) => series.points[series.points.length - 1].t));
|
||||
|
||||
const targetTime = globalMinTime + xRatio * (globalMaxTime - globalMinTime);
|
||||
const timeRange = globalMaxTime - globalMinTime || 1;
|
||||
const indicatorMode = host.__bubbleHistoryTooltipIndicator || "points";
|
||||
|
||||
const rows = usableSeries.map((series) => {
|
||||
const nearest = findNearestPoint(series.points, targetTime);
|
||||
if (!nearest) return "";
|
||||
const nearestBySeries = usableSeries.map((series) => ({
|
||||
series,
|
||||
nearest: findNearestPoint(series.points, targetTime)
|
||||
})).filter((entry) => entry.nearest);
|
||||
|
||||
const rows = nearestBySeries.map(({ series, nearest }) => {
|
||||
return `
|
||||
<div class="bubble-history-tooltip-row">
|
||||
<span class="bubble-history-tooltip-dot" style="background:${series.color};"></span>
|
||||
@@ -581,31 +619,68 @@ unique_bubble_graph:
|
||||
`;
|
||||
}).join("");
|
||||
|
||||
const firstNearest = findNearestPoint(usableSeries[0].points, targetTime);
|
||||
const firstNearest = nearestBySeries[0]?.nearest;
|
||||
const tooltipTime = firstNearest ? firstNearest.t : targetTime;
|
||||
|
||||
const x = ((targetTime - globalMinTime) / (globalMaxTime - globalMinTime || 1)) * rect.width;
|
||||
const x = ((targetTime - globalMinTime) / timeRange) * rect.width;
|
||||
const safeX = Math.min(rect.width - 60, Math.max(60, x));
|
||||
|
||||
const pointMarkers = nearestBySeries.map(({ series, nearest }) => {
|
||||
const minValue = Number.isFinite(series.__minValue) ? series.__minValue : 0;
|
||||
const maxValue = Number.isFinite(series.__maxValue) ? series.__maxValue : 1;
|
||||
const valueRange = maxValue - minValue || 1;
|
||||
const pointX = ((nearest.t - globalMinTime) / timeRange) * rect.width;
|
||||
const pointYView =
|
||||
100 -
|
||||
host.__bubbleHistoryPaddingY -
|
||||
((nearest.v - minValue) / valueRange) *
|
||||
(100 - host.__bubbleHistoryPaddingY * 2);
|
||||
const pointY = (pointYView / 100) * rect.height;
|
||||
|
||||
return `
|
||||
<span
|
||||
class="bubble-history-point-marker"
|
||||
style="left:${pointX}px;top:${pointY}px;background:${series.color};"
|
||||
></span>
|
||||
`;
|
||||
}).join("");
|
||||
|
||||
tooltipElement.innerHTML = `
|
||||
${rows}
|
||||
<div style="opacity:0.75;margin-top:3px;">${formatTime(tooltipTime)}</div>
|
||||
`;
|
||||
|
||||
tooltipElement.style.display = "block";
|
||||
markerElement.style.display = "block";
|
||||
|
||||
tooltipElement.style.left = `${safeX}px`;
|
||||
tooltipElement.style.top = `${host.__bubbleHistoryTooltipTop}px`;
|
||||
|
||||
if (indicatorMode === "line" || indicatorMode === "both") {
|
||||
markerElement.style.display = "block";
|
||||
markerElement.style.left = `${x}px`;
|
||||
} else {
|
||||
markerElement.style.display = "none";
|
||||
}
|
||||
|
||||
if (indicatorMode === "points" || indicatorMode === "both") {
|
||||
pointLayerElement.innerHTML = pointMarkers;
|
||||
pointLayerElement.style.display = "block";
|
||||
} else {
|
||||
pointLayerElement.innerHTML = "";
|
||||
pointLayerElement.style.display = "none";
|
||||
}
|
||||
};
|
||||
|
||||
host.onmouseleave = () => {
|
||||
const tooltipElement = host.__bubbleHistoryTooltip;
|
||||
const markerElement = host.__bubbleHistoryMarker;
|
||||
const pointLayerElement = host.__bubbleHistoryPointLayer;
|
||||
|
||||
if (tooltipElement) tooltipElement.style.display = "none";
|
||||
if (markerElement) markerElement.style.display = "none";
|
||||
if (pointLayerElement) {
|
||||
pointLayerElement.style.display = "none";
|
||||
pointLayerElement.innerHTML = "";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -645,25 +720,39 @@ unique_bubble_graph:
|
||||
const globalMaxTime = Math.max(...usableSeries.map((series) => series.points[series.points.length - 1].t));
|
||||
const sameScaleRange = sameScale ? getSameScaleRange(usableSeries) : null;
|
||||
|
||||
const buildPath = (series) => {
|
||||
let minValue;
|
||||
let maxValue;
|
||||
|
||||
const getValueRange = (series) => {
|
||||
if (sameScaleRange) {
|
||||
minValue = sameScaleRange.minValue;
|
||||
maxValue = sameScaleRange.maxValue;
|
||||
} else {
|
||||
return {
|
||||
minValue: sameScaleRange.minValue,
|
||||
maxValue: sameScaleRange.maxValue
|
||||
};
|
||||
}
|
||||
|
||||
const rawMinValue = Math.min(...series.points.map((point) => point.v));
|
||||
const rawMaxValue = Math.max(...series.points.map((point) => point.v));
|
||||
|
||||
const rawRange = rawMaxValue - rawMinValue;
|
||||
const safeRange = rawRange || Math.max(Math.abs(rawMaxValue), 1);
|
||||
const valuePadding = safeRange * (valuePaddingPercent / 100);
|
||||
|
||||
minValue = rawMinValue - valuePadding;
|
||||
maxValue = rawMaxValue + valuePadding;
|
||||
}
|
||||
return {
|
||||
minValue: rawMinValue - valuePadding,
|
||||
maxValue: rawMaxValue + valuePadding
|
||||
};
|
||||
};
|
||||
|
||||
const renderSeries = usableSeries.map((series) => {
|
||||
const range = getValueRange(series);
|
||||
|
||||
return {
|
||||
...series,
|
||||
__minValue: range.minValue,
|
||||
__maxValue: range.maxValue
|
||||
};
|
||||
});
|
||||
|
||||
const buildPath = (series) => {
|
||||
const minValue = series.__minValue;
|
||||
const maxValue = series.__maxValue;
|
||||
const timeRange = globalMaxTime - globalMinTime || 1;
|
||||
const valueRange = maxValue - minValue || 1;
|
||||
|
||||
@@ -685,7 +774,7 @@ unique_bubble_graph:
|
||||
.join(" ");
|
||||
};
|
||||
|
||||
const paths = usableSeries.map((series, index) => {
|
||||
const paths = renderSeries.map((series, index) => {
|
||||
const linePath = buildPath(series);
|
||||
const areaPath = `${linePath} L ${width} ${height} L 0 ${height} Z`;
|
||||
|
||||
@@ -714,7 +803,7 @@ unique_bubble_graph:
|
||||
</svg>
|
||||
`;
|
||||
|
||||
host.__bubbleHistorySeries = usableSeries;
|
||||
host.__bubbleHistorySeries = renderSeries;
|
||||
host.__bubbleHistoryMinTime = globalMinTime;
|
||||
host.__bubbleHistoryMaxTime = globalMaxTime;
|
||||
attachTooltipOnce();
|
||||
@@ -1197,6 +1286,19 @@ unique_bubble_graph:
|
||||
label: Tooltip anzeigen
|
||||
selector:
|
||||
boolean: null
|
||||
- name: tooltip_indicator
|
||||
label: Tooltip Markierung
|
||||
selector:
|
||||
select:
|
||||
options:
|
||||
- label: Punkte auf dem Graphen
|
||||
value: points
|
||||
- label: Vertikale Linie
|
||||
value: line
|
||||
- label: Punkte und Linie
|
||||
value: both
|
||||
- label: Keine Markierung
|
||||
value: none
|
||||
- name: tooltip_top
|
||||
label: Tooltip Position oben
|
||||
selector:
|
||||
|
||||
Reference in New Issue
Block a user