Public
Edited
Oct 17, 2022
Insert cell
Insert cell
Insert cell
Insert cell
viewof txt = 'Hotel has a total of ' + floors*rooms+' rooms, using ' + Math.round(bond[2].value + bond[3].value+(36.25*rooms*floors))+ ' liters of water each day.'
Insert cell
bond5 = bond
Insert cell
Insert cell
Insert cell
Insert cell
proposed = md`#### Aera New York Proposed Hotel Room Water Usage`
Insert cell
Insert cell
Insert cell
totalWaterSavings = md ` #### Daily Water Savings: ${savings} liters`
Insert cell
totalWaterCreated = md ` #### Total amount remediated for watering: ${waterSavings} liters`
Insert cell
//difference5 = bond4[4].value
Insert cell
viewof rooms = Inputs.range([15, 25], {step: 1, label: "Rooms per Floor", value:'20'})
Insert cell
viewof floors = Inputs.range([10, 20], {step: 1, label: "Total Floors", value: 15})
Insert cell
viewof flush1 = Inputs.range([3, 18], {step: 1, label: "Flush Volume", value: 6})
Insert cell
viewof radios = Inputs.radio(["1", "2", "3","4"], {label: "Shower Users", value: "2"})
Insert cell
bond[4].value
Insert cell
difference1 =6
Insert cell
mutable newTotal = 0
Insert cell
mutable watering = 0
Insert cell
savings = round(newTotal,0)
Insert cell
waterSavings = round(watering,0)
Insert cell
// Copyright 2021 Observable, Inc.
// Released under the ISC license.
// https://observablehq.com/@d3/sankey-diagram
function SankeyChart({
nodes, // an iterable of node objects (typically [{id}, …]); implied by links if missing
links // an iterable of link objects (typically [{source, target}, …])
}, {
format = ",", // a function or format specifier for values in titles
align = "justify", // convenience shorthand for nodeAlign
nodeId = d => d.id, // given d in nodes, returns a unique identifier (string)
nodeGroup, // given d in nodes, returns an (ordinal) value for color
nodeGroups, // an array of ordinal values representing the node groups
nodeLabel, // given d in (computed) nodes, text to label the associated rect
//nodeTitle = d => `${d.id}\n${format(d.value)}`, // given d in (computed) nodes, hover text
nodeTitle = d => `${format(d.value)}`, // given d in (computed) nodes, hover text
nodeAlign = align, // Sankey node alignment strategy: left, right, justify, center
nodeWidth = 45, // width of node rects
nodePadding = 10, // vertical separation between adjacent nodes
nodeLabelPadding = 6, // horizontal separation between node and label
nodeStroke = "currentColor", // stroke around node rects
nodeStrokeWidth, // width of stroke around node rects, in pixels
nodeStrokeOpacity, // opacity of stroke around node rects
nodeStrokeLinejoin, // line join for stroke around node rects
linkSource = ({source}) => source, // given d in links, returns a node identifier string
linkTarget = ({target}) => target, // given d in links, returns a node identifier string
linkValue = ({value}) => value, // given d in links, returns the quantitative value
linkPath = d3Sankey.sankeyLinkHorizontal(), // given d in (computed) links, returns the SVG path
linkTitle = d => `${d.source.id} → ${d.target.id}\n${format(d.value)}`, // given d in (computed) links
linkColor = "source-target", // source, target, source-target, or static color
linkStrokeOpacity = 0.5, // link stroke opacity
linkMixBlendMode = "multiply", // link blending mode
colors = d3.schemeBlues[6], // array of colors
width = 640, // outer width, in pixels
height = 400, // outer height, in pixels
marginTop = 5, // top margin, in pixels
marginRight = 1, // right margin, in pixels
marginBottom = 5, // bottom margin, in pixels
marginLeft = 1, // left margin, in pixels
} = {}) {

var showerUsers = radios*64705
console.log(showerUsers)
//bond[3].value = showerUsers
//bond[5].value = showerUsers
bond[3].value = 75.68*rooms*floors*radios//
bond[5].value = 75.68*rooms*floors*radios
//bond[1].value = showerUsers+bond[2].value

bond4[3].value = 75.68*rooms*floors*radios//current shower
bond4[8].value = 75.68*rooms*floors*radios// current shower to gray

//var potable = rooms*floors*332
//bond[1].value = potable
bond[4].value = rooms*floors*60.56//sink to remediation
bond[2].value = rooms*floors*60.56//washing to sink

bond4[7].value = rooms*floors*60.56//current sink to gray
bond4[2].value = rooms*floors*60.56//current washing to sink

bond[1].value = bond[2].value + bond[3].value//washing = sink+shower
//bond[0].value = bond[1].value + 31000
bond[0].value = 36.25*rooms*floors//ice

bond4[1].value = bond[2].value + bond[3].value//current washing = sink+shower
//bond[0].value = bond[1].value + 31000
bond4[0].value = 36.25*rooms*floors// current ice

var flush3 = flush1*7*rooms*floors
//console.log(flush3)
bond[7].value = flush3//new flush size
bond[8].value = flush3//new blackwater size
var remediation = bond[4].value+bond[5].value//compute remediation by adding washing and shower
bond[6].value = remediation - bond[7].value//compute watering quantity by subtracting flush from remediation


bond4[5].value = flush3//current new flush size
bond4[6].value = flush3//current new black water
bond4[4].value = 16857//water requirement for 1200 occupants
bond4[9].value = bond4[4].value
//var remediation = bond[4].value+bond[5].value//compute remediation by adding washing and shower
//bond4[6].value = remediation - bond[7].value
//difference1 = 40
//difference1 + bond4[0].value+bond4[1].value+bond4[4].value+bond4[5].value
//difference5 = bond4[0].value+bond4[1].value+bond4[4].value+bond4[5].value

mutable watering = bond[6].value
mutable newTotal = (bond4[0].value+bond4[1].value+bond4[4].value+bond4[5].value)-(bond[1].value+bond[0].value)

// Convert nodeAlign from a name to a function (since d3-sankey is not part of core d3).
if (typeof nodeAlign !== "function") nodeAlign = {
left: d3Sankey.sankeyLeft,
right: d3Sankey.sankeyRight,
center: d3Sankey.sankeyCenter
}[nodeAlign] ?? d3Sankey.sankeyJustify;

// Compute values.
const LS = d3.map(links, linkSource).map(intern);
const LT = d3.map(links, linkTarget).map(intern);
const LV = d3.map(links, linkValue);
if (nodes === undefined) nodes = Array.from(d3.union(LS, LT), id => ({id}));
const N = d3.map(nodes, nodeId).map(intern);
const G = nodeGroup == null ? null : d3.map(nodes, nodeGroup).map(intern);

// Replace the input nodes and links with mutable objects for the simulation.
nodes = d3.map(nodes, (_, i) => ({id: N[i]}));
links = d3.map(links, (_, i) => ({source: LS[i], target: LT[i], value: LV[i]}));

// Ignore a group-based linkColor option if no groups are specified.
if (!G && ["source", "target", "source-target"].includes(linkColor)) linkColor = "currentColor";

// Compute default domains.
if (G && nodeGroups === undefined) nodeGroups = G;

// Construct the scales.
const color = nodeGroup == null ? null : d3.scaleOrdinal(nodeGroups, colors);

// Compute the Sankey layout.
d3Sankey.sankey()
.nodeSort((a, b) => a.index - b.index)
.nodeId(({index: i}) => N[i])
.nodeAlign(nodeAlign)
.nodeWidth(nodeWidth)
.nodePadding(nodePadding)
.extent([[marginLeft, marginTop], [width - marginRight, height - marginBottom]])
({nodes, links});

// Compute titles and labels using layout nodes, so as to access aggregate values.
if (typeof format !== "function") format = d3.format(format);
const Tl = nodeLabel === undefined ? N : nodeLabel == null ? null : d3.map(nodes, nodeLabel);
const Tt = nodeTitle == null ? null : d3.map(nodes, nodeTitle);
const Lt = linkTitle == null ? null : d3.map(links, linkTitle);
const Lv = linkValue == null ? null : d3.map(links, linkValue);

// A unique identifier for clip paths (to avoid conflicts).
const uid = `O-${Math.random().toString(16).slice(2)}`;

const svg = d3.create("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto; height: intrinsic;");

const node = svg.append("g")
.attr("stroke", nodeStroke)
.attr("stroke-width", nodeStrokeWidth)
.attr("stroke-opacity", nodeStrokeOpacity)
.attr("stroke-linejoin", nodeStrokeLinejoin)
.selectAll("rect")
.data(nodes)
.join("rect")
.attr("x", d => d.x0)
.attr("y", d => d.y0)
.attr("height", d => d.y1 - d.y0)
.attr("width", d => d.x1 - d.x0);

if (G) node.attr("fill", ({index: i}) => color(G[i]));
if (Tt) node.append("title").text(({index: i}) => Tt[i]);

const link = svg.append("g")
.attr("fill", "none")
.attr("stroke-opacity", linkStrokeOpacity)
.selectAll("g")
.data(links)
.join("g")
.style("mix-blend-mode", linkMixBlendMode);

if (linkColor === "source-target") link.append("linearGradient")
.attr("id", d => `${uid}-link-${d.index}`)
.attr("gradientUnits", "userSpaceOnUse")
.attr("x1", d => d.source.x1)
.attr("x2", d => d.target.x0)
.call(gradient => gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", ({source: {index: i}}) => color(G[i])))
.call(gradient => gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", ({target: {index: i}}) => color(G[i])));

link.append("path")
.attr("d", linkPath)
.attr("stroke", linkColor === "source-target" ? ({index: i}) => `url(#${uid}-link-${i})`
: linkColor === "source" ? ({source: {index: i}}) => color(G[i])
: linkColor === "target" ? ({target: {index: i}}) => color(G[i])
: linkColor)
.attr("stroke-width", ({width}) => Math.max(1, width))
.call(Lt ? path => path.append("title").text(({index: i}) => Lt[i]) : () => {});

if (Tl) svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 24)
.selectAll("text")
.data(nodes)
.join("text")
.attr("x", d => d.x0 < width / 2 ? d.x1 + nodeLabelPadding : d.x0 - nodeLabelPadding)
.attr("y", d => (d.y1 + d.y0) / 2)
.attr("dy", "0.35em")
.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
.text(({index: i}) => Tl[i]);
//.text(({index: i}) => Lv[i]);

if (Tt) svg.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 24)
.selectAll("text")
.data(nodes)
.join("text")
.attr("x", d => d.x0 < width / 2 ? d.x1 + nodeLabelPadding : d.x0 - nodeLabelPadding)
.attr("y", d => ((d.y1 + d.y0) / 2)+26)
.attr("dy", "0.35em")
.attr("text-anchor", d => d.x0 < width / 2 ? "start" : "end")
.text(({index: i}) => Tt[i]);
//.text(({index: i}) => bond[i].value)

function intern(value) {
return value !== null && typeof value === "object" ? value.valueOf() : value;
}
return Object.assign(svg.node(), {scales: {color}});
}
Insert cell
sheet = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vRoczva03XZk0-WCbNiL4ihA4kPxXX19LOkpOL9hdADkoRNXn7_EVgX12VKqf8nk1ZdXOZ_pZt09BL7/pub?output=csv'
Insert cell
node2 = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vTdiEd9YrA-qOZTkv2qYDFfLKOdTcRLIAUNZH5hm3sXoRD6ctaLAanU9jwDsmakFV7L7-ZzGAuqIq5B/pub?output=csv'
Insert cell
bond = d3.csv(sheet, d3.autoType)
Insert cell
node1 = d3.csv(node2, d3.autoType)
Insert cell
Insert cell
Insert cell
d3Sankey = require.alias({"d3-array": d3, "d3-shape": d3, "d3-sankey": "d3-sankey@0.12.3/dist/d3-sankey.min.js"})("d3-sankey")
Insert cell
import {howto} from "@d3/example-components"
Insert cell
node3 = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vR5xJzEBNwWOz8C5Cgqduzhk01449DsVMZmTpCc3JGGXQN4d_Rl-Qq1KMBlNl_M4u0wnNjiQOA-nnhr/pub?output=csv'
Insert cell
sheet3 = 'https://docs.google.com/spreadsheets/d/e/2PACX-1vTtiPjXi7VaHdWY_vGaI6GZofVHGE19LMhm5xYvRlWAn-vPa4olHNQ39NjcIc03YxESirb-wIQrvxix/pub?output=csv'
Insert cell
node4 = d3.csv(node3, d3.autoType)
Insert cell
bond4 = d3.csv(sheet3, d3.autoType)
Insert cell
round = (n, places) => {
if (!places) return Math.round(n);
const d = 10 ** places;
return Math.round(n * d) / d;
}
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