Skip to content

Instantly share code, notes, and snippets.

@Meng-V
Created November 13, 2024 20:42
Show Gist options
  • Save Meng-V/3175fc2e950cc32100429b0d901d8473 to your computer and use it in GitHub Desktop.
Save Meng-V/3175fc2e950cc32100429b0d901d8473 to your computer and use it in GitHub Desktop.
Crowd Index customized for Rec
async function getData() {
await axios
// For Rec, the endpoint is 'https://www.lib.miamioh.edu:3012/recapi'
.get('https://www.lib.miamioh.edu:3012/recapi', {
crossDomain: true
})
.then(res => {
var patronNumber = parseInt(res.data.patronCount);
if (patronNumber < 0) {
$("#crowdIndex").html("Temporarily out of service");
} else {
// Adjust the max capacity number at here.
// Ron said "Let's start with 225, with a note that says 65-70% of users are in the fitness center."
// Because Cisco has a caching problem, the counted number is slightly higher than actural counts.
// Meng recommended putting 375 as the max capacity. 11/13/2024
const MAX_CAPACITY = 375;
const BAR_INTERVAL = MAX_CAPACITY / 15;
var percentageOcc = patronNumber / (MAX_CAPACITY / 100);
var maxmod = percentageOcc % 10 > 5 ? 10 : 5;
// minOcc and maxOcc are the range of the percentage occupancy
var maxOcc = Math.floor(percentageOcc/10)*10 + maxmod;
var minOcc = parseInt(maxOcc)-5;
$("#crowdIndex").html('Estimated ' + minOcc + ' - ' + maxOcc + '% of users are in the fitness center.');
var linearScale = d3.scaleLinear()
.domain([0, MAX_CAPACITY])
.range([0, 255]);
var sequentialScale = d3.scaleSequential()
.domain([MAX_CAPACITY, 0]);
// Using rainbow color to represent the occupancy. Green means low, yellow means medium, red means high occupancy.
var interpolators = ["interpolateRdYlGn"];
var myData = d3.range(0, patronNumber, BAR_INTERVAL);
var maxData = d3.range(0, MAX_CAPACITY, BAR_INTERVAL);
function dots(d) {
sequentialScale
.interpolator(d3[d]);
d3.select(this)
.selectAll('rect')
.data(myData)
.enter()
.append('rect')
.attr('x', function (d) {
return linearScale(d);
})
.attr('width', 15)
.attr('height', 30)
.style('fill', function (d) {
return sequentialScale(d);
});
}
function maxDots(d) {
sequentialScale
.interpolator(d3[d]);
d3.select(this)
.selectAll('rect')
.data(maxData)
.enter()
.append('rect')
.style("stroke", "black")
.attr('x', function (d) {
return linearScale(d);
})
.attr('width', 15)
.attr('height', 30)
.style('fill', function (d) {
return sequentialScale(d);
})
.attr("class", "maxDot");
}
d3.select('#wrapper')
.selectAll('g.interpolator')
.data(interpolators)
.enter()
.append('g')
.classed('interpolator', true)
.each(dots)
.each(maxDots);
d3.selectAll('.maxDot')
.style("opacity", 0.1);
var theMeter = $('svg#crowdBar');
theMeter[0].setAttribute('aria-label', Math.floor(percentageOcc) + "% capacity");
}
}).catch(error => {
console.log('error', error);
$("#crowdIndex").html("Temporarily out of service");
});
}
$(document).ready(() => {
getData();
})
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- jQuery -->
<script
src="https://code.jquery.com/jquery-3.7.1.min.js"
integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="
crossorigin="anonymous"
></script>
<!-- D3 -->
<script src="https://d3js.org/d3.v7.js"></script>
<!-- Axios -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<title>Document</title>
</head>
<body>
<h1 class="">Crowd Index</h1>
<div class="svg-container mb-3">
<svg
id="crowdBar"
class="crowd"
aria-hidden="true"
width="100%"
height="30"
>
<g id="wrapper"></g>
</svg>
<span id="crowdIndex" class="crowd">Loading...</span>
&nbsp;(<a href="/about/locations/king-library/#about-crowd-index"
>Read more</a
>)<br />
</div>
<script src="./crowd-index.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment