Published
Edited
Feb 11, 2021
Fork of Google EEMs
1 fork
Insert cell
md`# UT EEM All Buildings`
Insert cell
xlsx = require('https://bundle.run/xlsx@0.14.1')
Insert cell
viewof binary = html`<input type=file>`
Insert cell
input = new Uint8Array(await Files.buffer(binary))
Insert cell
wb = xlsx.read(input, {type: 'array'})
Insert cell
excel = wb.Sheets["Baseline"];
Insert cell
data = xlsx.utils.sheet_to_json(excel);
Insert cell
height = 775
Insert cell
Insert cell
Insert cell
d3 = require("d3@^6.1")
Insert cell
_ = require('lodash@4.17.15/lodash.js').catch(() => window["_"])
Insert cell
chroma = require('chroma-js')
Insert cell
ecm_data = {

const map = new Map();
for (const key of Object.keys(wb.Sheets)) {
let excel = wb.Sheets[key];
let dat = xlsx.utils.sheet_to_json(excel);
let f = dat.map(d => Math.max(d["SAVINGS"], 0));
map.set(key, quartiles(f));
}

return map;
}
Insert cell
quartiles = (data) => {

const values = data.sort((a, b) => a - b);
const min = values[0];
const max = values[values.length - 1];
const q1 = d3.quantile(values, 0.25);
const q2 = d3.quantile(values, 0.50);
const q3 = d3.quantile(values, 0.75);
const iqr = q3 - q1; // interquartile range
const r0 = Math.max(min, q1 - iqr * 1.5);
const r1 = Math.min(max, q3 + iqr * 1.5);
values.quartiles = [q1, q2, q3];
values.range = [r0, r1];
values.outliers = values.filter(v => v < r0 || v > r1); // TODO
return values;
}
Insert cell
lookup = ({
"Envelope": "Envelope",
"LPD": "LPD Reductions",
"HRV": "Heat Recovery",
"VENT2": "Ventilation Measures",
"VENT3": "Enhanced Ventilation",
"FanPower": "Fan Energy Reductions",
"Combined": "All Measures Combined"
// "STR60": "Supply Air Temperature Reset",
// "WAC": "Enhanced SAT Reset",
})
Insert cell
Array.from(ecm_data.values()).map(d => d.range[1])
Insert cell
y = d3.scaleBand()
.domain(Object.keys(wb.Sheets).reverse())
.range([height - margin.bottom, margin.top])
.padding(.1)
.paddingOuter(.5)
Insert cell
x = d3.scaleLinear()
.domain([1, d3.max(Array.from(ecm_data.values()).map(d => d.range[1]))]).nice()
.range([margin.left, width - margin.right])
Insert cell
margin = ({top: 80, right: 100, bottom: 50, left: 340})
Insert cell
xAxis = g => g
.attr("transform", `translate(0,${margin.top})`)
.call(d3.axisTop(x).tickPadding(10).tickFormat(d3.format("~s")))
// .call(g => g.select(".domain").remove())
.call(g => g.select(".tick:first-of-type text").clone()
.attr("y", -50)
.attr("x", -3)
.attr("text-anchor", "start")
.attr("font-weight", "bold")
.html("Annual GHG Reductions (Tons CO2e/yr)"))
.call(g => g.selectAll(".tick line").clone()
.attr("stroke-opacity", 0.1)
.attr("y2", height - margin.bottom - 80))
Insert cell
display = d => {
let [building, measure] = d.split("-");
return `${building} ${lookup[measure]}`;
}
Insert cell
yAxis = g => g
.attr("transform", `translate(${5},0)`)
.call(d3.axisRight(y).tickFormat(d => display(d)))
.call(g => g.select(".domain").remove())
.call(g => g.selectAll(".tick line").remove())
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more