Public
Edited
Jan 20, 2024
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sortedData = sortbyAPandTime(apdata)
Insert cell
Insert cell
Insert cell
sortedAPData = sortbyAPandTime(apdata)
Insert cell
collapsed = collapseByAP(sortedData)
Insert cell
Insert cell
Insert cell
Insert cell
// sortbyAPandTime(apdata).filter(o => o.ap === 16 && o.timestamp === 1684951785)
Insert cell
Insert cell
Insert cell
// apdata.filter(o => o.ap === 36)
Insert cell
// apdata.filter(o => o.state === 5)
Insert cell
Insert cell
Insert cell
Insert cell
getDate = (timestamp) => {
return new Date(timestamp * 1000);
}
Insert cell
Insert cell
sortedbyMac = sortByField(apdata, "mac")
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
input1 = [
{ ap: 27, user: 2, mac: 6, state: 1, timestamp: 1684867845 },
{ ap: 27, user: 2, mac: 6, state: 1, timestamp: 1684867905 },
{ ap: 44, user: 2, mac: 6, state: 3, timestamp: 1684867965 }, // yes, state also changes but we're ignoring that for now
{ ap: 25, user: 2, mac: 6, state: 1, timestamp: 1684868025 },
{ ap: 25, user: 2, mac: 6, state: 1, timestamp: 1684868085 }
]
Insert cell
output1 = mapByDevice(sortByUserMacTime(input1))
Insert cell
Insert cell
input2 = [
{ ap: 52, user: 1, mac: 4, state: 1, timestamp: 1684951725 },
{ ap: 52, user: 1, mac: 4, state: 1, timestamp: 1684951785 },
{ ap: 52, user: 1, mac: 6, state: 1, timestamp: 1684866885 },
{ ap: 52, user: 1, mac: 6, state: 1, timestamp: 1684866945 },
{ ap: 52, user: 1, mac: 6, state: 1, timestamp: 1684867005 }
]
Insert cell
output2 = mapByDevice(sortByUserMacTime(input2))
Insert cell
Insert cell
input3 = [
{ ap: 52, user: 1, mac: 4, state: 1, timestamp: 1684951725 },
{ ap: 52, user: 1, mac: 4, state: 1, timestamp: 1684951785 },
{ ap: 52, user: 3, mac: 4, state: 1, timestamp: 1684866885 },
{ ap: 52, user: 3, mac: 4, state: 1, timestamp: 1684866945 },
{ ap: 52, user: 3, mac: 4, state: 1, timestamp: 1684867005 }
]
Insert cell
output3 = mapByDevice(sortByUserMacTime(input3))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
output6 = mapByDevice(sortByUserMacTime(input6))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function findTimeGaps(arr, n) {
const gapsBtwn = [];
for (let i = 1; i < arr.length; i++) {
const currT = arr[i].timestamp;
const prevT = arr[i - 1].timestamp;
const diff = currT - prevT;
if (
diff !== 60 &&
arr[i].ap === arr[i - 1].ap &&
arr[i].mac === arr[i - 1].mac &&
arr[i].user === arr[i - 1].user
) {
gapsBtwn.push(arr[i - 1]);
gapsBtwn.push(arr[i]);
gapsBtwn.push(`seconds between: ${diff}`);
}
}

return gapsBtwn;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
allTheAPS = Array.from(collapsed.keys())
Insert cell
getdataOfAP = (ap) => {
//const collapsed = collapseByAP(apdata).get(ap);
const collapsedAP = collapsed.get(ap);
return makeFieldsNum(collapsedAP);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
width,
marginTop: 50,
x: {
label: "AP identifier"
},
y: {
grid: true,
tickFormat: "+f",
label: "# MACs connected"
},
marks: [
Plot.ruleY([0]),
Plot.dot(APcounts, {
x: "fieldVal",
y: "count",
r: "count",
stroke: "count",
tip: true
}),
// r channel allows dot size to represent quantitative value
Plot.text(APcounts, {
x: "fieldVal",
y: "count",
text: "fieldVal",
dy: -12,
lineAnchor: "bottom",
filter: (d) => d.count > 100
})
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
marginLeft: 50,
height: 1600,
width,
padding: 0,
fy: { grid: true },
// sets the y-axis domain by grouping the data by facets
color: {
scheme: "YlGnBu",
legend: true,
range: [0.2, 1.4],
label: "proportion of data points"
},
marks: [
Plot.rect(
APSubset,
Plot.binX(
{ fill: "proportion-facet" }, // the color of each bin represents the proportion of data points in that bin
// relative to the total data points in that particular facet (i.e, that particular ap)
{ x: "date", fy: "ap", inset: 0.5, tip: true }
)
)
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
width,
height: 1600,
padding: 0,
x: { label: "time" },
fy: { grid: true, label: "Access point" },
color: {
scheme: "BuGn",
legend: true,
range: [0.2, 3]
},
marks: [
Plot.rect(
APSubset,
Plot.binX({ fill: "count" }, { x: "date", fy: "ap", inset: 0.2 })
)
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {getSubset} from "14fd093abbdf9097"
Insert cell
import {mapToArr} from "14fd093abbdf9097"
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more