xxxxxxxxxx
269
// setTimeout(), setInterval()
let entries = null;
let displayEntries = [];
let overArchingAngleRandomizer = 0;
const oneHourInMs = 3600000;
const oneDayInMs = 86400000;
const maxSize = 600 / 7;
let bg = null;
function preload() {
entries = loadJSON('csvjson.json');
}
function setup() {
createCanvas(600, 600);
bg = color(250);
for (const index in entries) {
const call = entries[index];
// set day into int
let day = 0;
switch (call.Day) {
case 'Mon':
day = 7;
break;
case 'Tue':
day = 1;
break;
case 'Wed':
day = 2;
break;
case 'Thu':
day = 3;
break;
case 'Fri':
day = 4;
break;
case 'Sat':
day = 5;
break;
case 'Sun':
day = 6;
break;
}
// let start = new Date( call['Start Time'] );
let start = parseTime(call['Start Time'])
let end = parseTime(call['End Time'])
if ( end < start ){
end = end + oneDayInMs;
}
let chats = [];
let callChat = call['Chat'];
if( Array.isArray( callChat ) ){
callChat.forEach( (chat) => {
let chatTimeStamp = parseTime(chat)
chats.push({
type: 'normal',
time: chatTimeStamp
});
})
}
let callPrivChat = call['Private Chat'];
if( Array.isArray( callPrivChat ) ){
callPrivChat.forEach( (chat) => {
let chatTimeStamp = parseTime(chat)
chats.push({
type: 'private',
time: chatTimeStamp
});
})
}
let cameras = []
let cameraArr = call['Camera Off'];
if( Array.isArray( cameraArr ) ){
cameraArr.forEach( (cam) => {
cameras.push(splitTimes(cam))
} )
}
let disturb = []
let disturbArr = call['Do Not Disturb'];
if( Array.isArray( disturbArr ) ){
disturbArr.forEach( (dist) => {
disturb.push(splitTimes(dist))
} )
}
let newZoom = new ZoomEntry(call['Cause'],day,start,end,chats,cameras,disturb);
displayEntries.push(newZoom);
}
noLoop();
setInterval( ()=>{
overArchingAngleRandomizer = random( 0 , TWO_PI );
redraw();
}, 2000 )
}
function draw() {
background(bg);
blendMode(MULTIPLY);
displayEntries.forEach((entry) => {
entry.display();
});
blendMode(BLEND);
}
class ZoomEntry {
constructor(type,day,start,end,chats,cameras,disturb) {
this.type = type;
this.day = day;
this.start = start;
this.end = end;
this.duration = end-start;
this.chats = chats;
this.camOff = cameras;
this.doNotDist = disturb;
let mappedDuration = map( this.duration, 0, oneHourInMs/2, 0, maxSize*3);
// this.radius = mappedDuration / PI / 2; // with circumference
this.radius = Math.sqrt( mappedDuration / PI ); // with area
}
display() {
push();
noFill();
let displayColor = 0;
let displayColorLight = 50;
switch( this.type.toLowerCase() ){
case 'class':
displayColor = color('#C1E015');
displayColorLight = color('#C1E01566');
break;
case 'private':
displayColor = color('#66DAFF');
displayColorLight = color('#66DAFF44');
break;
case 'school':
displayColor = color('#FF6000');
displayColorLight = color('#FF600044');
break;
}
let topMargin = height/10;
let top = map( this.start+this.duration/2, 0, oneDayInMs, topMargin, height-topMargin);
// top = top . maxSize / 2;
let left = maxSize * (this.day - 1) + maxSize / 2;
stroke(displayColor)
translate(left, top);
push();
rotate( random(overArchingAngleRandomizer) )
line( 0, -1*this.radius+5, 0, -1*this.radius-5);
circle(0, 0, this.radius*2);
// cam off
this.camOff.forEach( (cam, i) => {
let startTime = this.start - cam.start;
let endTime = this.start - cam.end;
let startAngle = map( startTime, 0, this.duration, 0, TWO_PI);
let endAngle = map( endTime, 0, this.duration, 0, TWO_PI);
arc(0, 0, this.radius*2+6, this.radius*2+6, TWO_PI - startAngle-HALF_PI, TWO_PI - endAngle-HALF_PI);
});
// do not disturb
this.doNotDist.forEach( (dist, i) => {
push();
stroke(displayColorLight);
let startTime = this.start - dist.start;
let endTime = this.start - dist.end;
let startAngle = map( startTime, 0, this.duration, 0, TWO_PI);
let endAngle = map( endTime, 0, this.duration, 0, TWO_PI);
arc(0, 0, this.radius*2+12, this.radius*2+12, TWO_PI - startAngle-HALF_PI, TWO_PI - endAngle-HALF_PI);
pop();
});
// chat
let prevTime = 0;
let multiChat = 0;
this.chats.forEach( (c, i) => {
push();
if( prevTime === c.time ){
multiChat++;
}else{
multiChat = 0;
}
let thisTime = this.start - c.time;
let angle = map( thisTime, 0, this.duration, 0, TWO_PI);
//rotate(PI / 3.0);
rotate(angle*-1)
noStroke();
if( c.type === 'private' ){
// fill(displayColorLight);
noFill();
stroke(displayColor);
}else{
fill(displayColor);
}
//circle(0, this.radius*-1-10-(6*i), 4);
circle(0, this.radius*-1-10-(6*multiChat), 3);
noStroke();
prevTime = c.time;
pop();
})
pop();
pop();
}
}
// https://stackoverflow.com/questions/141348/how-to-parse-a-time-into-a-date-object-from-user-input-in-javascript
function parseTime(t) {
var d = new Date();
var time = t.match(/(\d+)(?::(\d\d))?\s*(p?)/);
time[3] = ( t.includes('AM') ? false : true );
d.setHours(parseInt(time[1]) + (time[3] ? 12 : 0));
d.setMinutes(parseInt(time[2]) || 0);
let startOfDay = new Date();
startOfDay.setHours(0);
startOfDay.setMinutes(0);
d = d - startOfDay;
return d;
}
// https://stackoverflow.com/questions/20474257/split-string-into-two-parts
function splitTimes ( str ) {
let index = str.indexOf("-"); // Gets the first index where a space occours
let start = str.substr(0, index); // Gets the first part
let end = str.substr(index + 1); // Gets the text part
return {
start: parseTime(start),
end: parseTime(end)
}
}