From c04181ed687fbc702f76f2206bcb92959c186401 Mon Sep 17 00:00:00 2001 From: Michael Sweeney Date: Thu, 30 May 2024 12:00:37 -0400 Subject: [PATCH 1/2] plot-format --- .../resources/report.html.erb | 1676 +++++++++++------ 1 file changed, 1058 insertions(+), 618 deletions(-) diff --git a/lib/measures/detailed_hvac_viewer/resources/report.html.erb b/lib/measures/detailed_hvac_viewer/resources/report.html.erb index 9695214..794bea9 100644 --- a/lib/measures/detailed_hvac_viewer/resources/report.html.erb +++ b/lib/measures/detailed_hvac_viewer/resources/report.html.erb @@ -1,654 +1,1094 @@ - - -HVAC Detailed Viewer - - - - - - -
- - -
-
- -
- -
- - - - + + function mouseMove(e) { + let xdate = xScale.invert(d3.pointer(e)[0]); + + // hack to get closest index from 8760 hour. probably a much better way to do this. + + let [start, end] = xScale.domain(); + + let domain_fraction = + (xdate.getTime() - start.getTime()) / + (end.getTime() - start.getTime()); + + let selected_date = new Date( + startDate.getTime() + + (start.getTime() - startDate.getTime()) + + domain_fraction * (end.getTime() - start.getTime()) + ); + + let annual_fraction = + (selected_date.getTime() - startDate.getTime()) / + (endDate.getTime() - startDate.getTime()); + + let closest_idx = Math.round(annual_fraction * 8760); + + let closest_date = new Date( + startDate.getTime() + closest_idx * 3.6e6 + ); + + let pointarray = []; + + data_array.forEach((d, i) => { + pointarray.push(d.NodeValues[closest_idx]); + }); + + x_line + .style("opacity", 1) + .attr("x1", xScale(xdate)) + .attr("x2", xScale(xdate)); + + tooltip_div + .style( + "left", + 10 + event.pageX / window.innerWidth + event.pageX + "px" + ) + .style("top", 10 + event.pageY + "px") + .style("transition", "left 100ms, top 100ms") + .style("z-index", 999) + .style("opacity", 0.85).html(` +
+
+ ${d3.timeFormat("%B %d %H:%M")(closest_date)} +
+ ${pointarray + .map((d, i) => { + let node_name = data_array[i].nodeName; + let node_val = d; + + return ` +
+
+
${node_name}: ${node_val}
+
`; + }) + .join("")} +
`); + } + + hover_rect.on("mouseover", mouseOver); + hover_rect.on("mouseout", mouseOut); + hover_rect.on("mousemove", mouseMove); + + /* HANDLE ZOOM & BRUSH */ + + const clip_path = bindD3Element(defs, "clipPath", "clip-path").attr( + "id", + clipid + ); + + const clip_rect = bindD3Element(clip_path, "rect", "clip-rect") + .join("rect") + .attr("width", plotWidth) + .attr("height", plotHeight) + .attr("x", 0) + .attr("y", 0); + + const brush = d3 + .brushX() + .extent([ + [0, 0], + [plotWidth, contextHeight], + ]) + .on("brush end", brushed); + + const zoomFunc = d3 + .zoom() + .scaleExtent([1, Infinity]) + .translateExtent([ + [0, 0], + [plotWidth, plotHeight], + ]) + .extent([ + [0, 0], + [plotWidth, plotHeight], + ]) + .on("zoom", zoomed); + + let idleTimeout; + let idleDelay = 350; + + function idled() { + idleTimeout = null; + } + + function brushed(event) { + if (event.sourceEvent && event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom + var s = event.selection || contextXScale.range(); + + let xdomain = s.map(contextXScale.invert, contextXScale); + xScale.domain(xdomain); + + createLine(xdomain); + x_axis_g.call(d3.axisBottom(xScale)); + } + + function zoomed(event) { + if (event.sourceEvent && event.sourceEvent.type === "brush") return; // ignore zoom-by-brush + var t = event.transform; + let xdomain = t.rescaleX(contextXScale).domain(); + xScale.domain(xdomain); + createLine(xdomain); + x_axis_g.call(d3.axisBottom(xScale)); + context_plot_g + .select(".brush") + .call(brush.move, xScale.range().map(t.invertX, t)); + } + + context_plot_g + .selectAll(".brush") + .data([0]) + .join("g") + .attr("class", "brush") + .call(brush); + x_axis_g.call(d3.axisBottom(xScale)); + + hover_g.call(zoomFunc); + } + + /* END D3 MULTILINE PLOT */ + + function getRandomColor() { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; + } + // Call function to attach event listener when the DOM is fully loaded + document.addEventListener("DOMContentLoaded", selectLoopEvent); + + From 2c4e4b157da964bf5a7e2d4ad7a291c2040550a4 Mon Sep 17 00:00:00 2001 From: Michael Sweeney Date: Thu, 30 May 2024 12:46:10 -0400 Subject: [PATCH 2/2] line-format --- .vscode/settings.json | 5 + .../resources/report.html.erb | 104 +++++++++--------- 2 files changed, 60 insertions(+), 49 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..f235ed1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "*.html.erb": "html" + } +} \ No newline at end of file diff --git a/lib/measures/detailed_hvac_viewer/resources/report.html.erb b/lib/measures/detailed_hvac_viewer/resources/report.html.erb index 794bea9..263e97f 100644 --- a/lib/measures/detailed_hvac_viewer/resources/report.html.erb +++ b/lib/measures/detailed_hvac_viewer/resources/report.html.erb @@ -76,11 +76,10 @@