|
|
@ -1,10 +1,15 @@
|
|
|
|
// Create some global variables
|
|
|
|
// Create some global variables
|
|
|
|
var width, height, audioEl;
|
|
|
|
var width, height, audioEl, textEl;
|
|
|
|
|
|
|
|
let currentTransform;
|
|
|
|
var links = [],
|
|
|
|
var links = [],
|
|
|
|
nodes = [],
|
|
|
|
nodes = [],
|
|
|
|
groups = [];
|
|
|
|
groups = [];
|
|
|
|
let zoomLvl = 1;
|
|
|
|
let zoomLvl = 1;
|
|
|
|
let lastK = 0;
|
|
|
|
let lastK = 0;
|
|
|
|
|
|
|
|
let svg;
|
|
|
|
|
|
|
|
var zoom;
|
|
|
|
|
|
|
|
let simulation;
|
|
|
|
|
|
|
|
const ROOT = "https://hub.xpub.nl/chopchop/archive_non-tree/";
|
|
|
|
|
|
|
|
|
|
|
|
function parseExifData(files) {
|
|
|
|
function parseExifData(files) {
|
|
|
|
// loop trough all files in JSON and add each to the list of nodes
|
|
|
|
// loop trough all files in JSON and add each to the list of nodes
|
|
|
@ -72,8 +77,9 @@ function parseExifData(files) {
|
|
|
|
function createGraph() {
|
|
|
|
function createGraph() {
|
|
|
|
// Create a scale to set the radius based on a file size (0 to 3 GB)
|
|
|
|
// Create a scale to set the radius based on a file size (0 to 3 GB)
|
|
|
|
var rScale = d3.scaleLinear().domain([0, 30000000]).range([2, 15]);
|
|
|
|
var rScale = d3.scaleLinear().domain([0, 30000000]).range([2, 15]);
|
|
|
|
|
|
|
|
currentTransform = [width / 2, height / 2, height];
|
|
|
|
|
|
|
|
|
|
|
|
const simulation = d3
|
|
|
|
simulation = d3
|
|
|
|
.forceSimulation(nodes)
|
|
|
|
.forceSimulation(nodes)
|
|
|
|
.force("center", d3.forceCenter(width / 2, height / 2))
|
|
|
|
.force("center", d3.forceCenter(width / 2, height / 2))
|
|
|
|
.force(
|
|
|
|
.force(
|
|
|
@ -95,7 +101,7 @@ function createGraph() {
|
|
|
|
|
|
|
|
|
|
|
|
// .alphaTarget(0.3); // stay hot
|
|
|
|
// .alphaTarget(0.3); // stay hot
|
|
|
|
|
|
|
|
|
|
|
|
const svg = d3
|
|
|
|
svg = d3
|
|
|
|
.create("svg") //
|
|
|
|
.create("svg") //
|
|
|
|
.attr("width", width)
|
|
|
|
.attr("width", width)
|
|
|
|
.attr("height", height);
|
|
|
|
.attr("height", height);
|
|
|
@ -132,11 +138,20 @@ function createGraph() {
|
|
|
|
.attr("r", 3)
|
|
|
|
.attr("r", 3)
|
|
|
|
.attr("stroke", "black")
|
|
|
|
.attr("stroke", "black")
|
|
|
|
.attr("fill", (d) => {
|
|
|
|
.attr("fill", (d) => {
|
|
|
|
return d.FileType === "directory" ? "orange" : "white";
|
|
|
|
if (d.FileType === "directory") {
|
|
|
|
|
|
|
|
return "orange";
|
|
|
|
|
|
|
|
} else if (d.FileType === "TXT") {
|
|
|
|
|
|
|
|
return "blue";
|
|
|
|
|
|
|
|
} else if (d.FileType === "PNG") {
|
|
|
|
|
|
|
|
return "pink";
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return "white";
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
// .attr("fill","rgba(255,255,255,.5)")
|
|
|
|
// .attr("fill","rgba(255,255,255,.5)")
|
|
|
|
.attr("label", (d) => d.id)
|
|
|
|
.attr("label", (d) => d.id)
|
|
|
|
.attr("path", (d) => d.id)
|
|
|
|
.attr("path", (d) => d.id)
|
|
|
|
|
|
|
|
.attr("file-type", (d) => d.FileType)
|
|
|
|
.attr("group", (d) => d.group);
|
|
|
|
.attr("group", (d) => d.group);
|
|
|
|
|
|
|
|
|
|
|
|
// Add a drag behavior.
|
|
|
|
// Add a drag behavior.
|
|
|
@ -161,17 +176,15 @@ function createGraph() {
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// add zoom behavior
|
|
|
|
// add zoom behavior
|
|
|
|
svg.call(
|
|
|
|
var zoom = d3
|
|
|
|
d3
|
|
|
|
|
|
|
|
.zoom()
|
|
|
|
.zoom()
|
|
|
|
.extent([
|
|
|
|
.extent([
|
|
|
|
[0, 0],
|
|
|
|
[0, 0],
|
|
|
|
[width, height],
|
|
|
|
[width, height],
|
|
|
|
])
|
|
|
|
])
|
|
|
|
.scaleExtent([1, 100])
|
|
|
|
.scaleExtent([1, 100])
|
|
|
|
.on("zoom", zoomed)
|
|
|
|
.on("zoom", zoomed);
|
|
|
|
);
|
|
|
|
svg.call(zoom);
|
|
|
|
|
|
|
|
|
|
|
|
// add some mouse behaviors
|
|
|
|
// add some mouse behaviors
|
|
|
|
svg
|
|
|
|
svg
|
|
|
|
.selectAll("circle")
|
|
|
|
.selectAll("circle")
|
|
|
@ -185,10 +198,20 @@ function createGraph() {
|
|
|
|
d3.select(this).attr("fill", "black");
|
|
|
|
d3.select(this).attr("fill", "black");
|
|
|
|
var path = this.getAttribute("path");
|
|
|
|
var path = this.getAttribute("path");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
svg
|
|
|
|
|
|
|
|
.transition() //
|
|
|
|
|
|
|
|
.duration(300)
|
|
|
|
|
|
|
|
.ease(d3.easeCubic)
|
|
|
|
|
|
|
|
.call(zoom.translateTo, this.getAttribute("cx"), this.getAttribute("cy"));
|
|
|
|
|
|
|
|
|
|
|
|
// do things based on the file type
|
|
|
|
// do things based on the file type
|
|
|
|
if (path.match(/\.(?:wav|mp3|flac)$/i)) {
|
|
|
|
if (path.match(/\.(?:wav|mp3|flac)$/i)) {
|
|
|
|
playAudio(path);
|
|
|
|
playAudio(path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (path.match(/\.(?:txt|png)$/i)) {
|
|
|
|
|
|
|
|
playText(path);
|
|
|
|
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.on("mouseleave", function () {
|
|
|
|
.on("mouseleave", function () {
|
|
|
|
if (d3.select(this).attr("fill") !== "black") {
|
|
|
|
if (d3.select(this).attr("fill") !== "black") {
|
|
|
@ -234,20 +257,56 @@ function createGraph() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function playAudio(src) {
|
|
|
|
function playAudio(src) {
|
|
|
|
console.log("play audio: ", src);
|
|
|
|
|
|
|
|
audioEl.src = src;
|
|
|
|
audioEl.src = src;
|
|
|
|
audioEl.currentTime = 0;
|
|
|
|
audioEl.currentTime = 0;
|
|
|
|
audioEl.play();
|
|
|
|
audioEl.play();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function playText(src) {
|
|
|
|
|
|
|
|
textEl.setAttribute("active", "true");
|
|
|
|
|
|
|
|
textEl.querySelector(".fn-title").textContent = src.split("/")[src.split("/").length - 1];
|
|
|
|
|
|
|
|
textEl.querySelector("iframe").src = ROOT + "/" + src;
|
|
|
|
|
|
|
|
window.setTimeout(function () {
|
|
|
|
|
|
|
|
svg.on("click", onBodyClick);
|
|
|
|
|
|
|
|
}, 300);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function onBodyClick() {
|
|
|
|
|
|
|
|
textEl.setAttribute("active", "false");
|
|
|
|
|
|
|
|
svg.on("click", null);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateWindow() {
|
|
|
|
|
|
|
|
width = window.innerWidth - 10;
|
|
|
|
|
|
|
|
height = window.innerHeight - 10;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
simulation.force("center", d3.forceCenter(width / 2, height / 2));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
svg.attr("width", width).attr("height", height);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
window.onload = function () {
|
|
|
|
window.onload = function () {
|
|
|
|
// TODO: add resize function
|
|
|
|
// TODO: add resize function
|
|
|
|
width = window.innerWidth;
|
|
|
|
width = window.innerWidth - 10;
|
|
|
|
height = window.innerHeight;
|
|
|
|
height = window.innerHeight - 10;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
audioEl = document.querySelector(".fn-audio");
|
|
|
|
|
|
|
|
textEl = document.querySelector(".fn-text");
|
|
|
|
|
|
|
|
|
|
|
|
parseExifData(dataset);
|
|
|
|
parseExifData(dataset);
|
|
|
|
createGraph();
|
|
|
|
createGraph();
|
|
|
|
|
|
|
|
var filetypes = [];
|
|
|
|
|
|
|
|
nodes.forEach((node) => {
|
|
|
|
|
|
|
|
if (filetypes.indexOf(node.FileType) == -1) {
|
|
|
|
|
|
|
|
filetypes.push(node.FileType);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
console.log(filetypes);
|
|
|
|
|
|
|
|
|
|
|
|
// clear loading screen
|
|
|
|
// clear loading screen
|
|
|
|
document.querySelector(".loading").style.display = "none";
|
|
|
|
document.querySelector(".loading").style.display = "none";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Add resize features
|
|
|
|
|
|
|
|
d3.select(window).on("resize.updatesvg", updateWindow);
|
|
|
|
};
|
|
|
|
};
|
|
|
|