Published
Edited
Feb 23, 2022
1 star
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
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
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
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
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
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
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function toc(selector = "h1,h2,h3", heading = "<b>Table of Contents</b>") {
return Generators.observe(notify => {
let headings = [];

function observed() {
const h = Array.from(document.querySelectorAll(selector));
if (h.length !== headings.length || h.some((h, i) => headings[i] !== h)) {
notify(
html`${heading}<ul>${Array.from((headings = h), h => {
return Object.assign(
html`<li><a href=#${h.id}>${DOM.text(h.textContent)}`,
{ onclick: e => (e.preventDefault(), h.scrollIntoView()) }
);
})}`
);
}
}

const observer = new MutationObserver(observed);
observer.observe(document.body, { childList: true, subtree: true });
observed();
return () => observer.disconnect();
});
}
Insert cell
function getAnchorCell(
keyword = "",
heading = "",
ending = "",
selector = "h1,h2,h3"
) {
return Generators.observe(notify => {
let headings = [];

function observed() {
const h = Array.from(document.querySelectorAll(selector));
if (h.length !== headings.length || h.some((h, i) => headings[i] !== h)) {
notify(
html`${heading}${Array.from((headings = h), h => {
if (h.id == keyword)
return Object.assign(
html`
<td><a href=#${h.id}><figure style="display: inline"><img src="https://ialab.it.monash.edu/~kche0088/images/Icon_play.PNG" width="30" height="30" /></figure>Play</a></td>
`,
{ onclick: e => (e.preventDefault(), h.scrollIntoView()) }
);
// return Object.assign(
// html`<a href=#${h.id}>${DOM.text(h.textContent)}`,
// { onclick: e => (e.preventDefault(), h.scrollIntoView()) }
// );
else return "";
})}${ending}`
);
}
}

const observer = new MutationObserver(observed);
observer.observe(document.body, { childList: true, subtree: true });
observed();
return () => observer.disconnect();
});
}
Insert cell
bHorizontalWrappingConfig = true
Insert cell
bVerticalWrappingConfig = true
Insert cell
Insert cell
{
if (datasetname == "graph2") {
mutable cellWidth = 650;
mutable cellHeight = 650;
mutable horizontalAxisWidth = 0;
mutable horizontalAxisHeight = 0;
mutable verticalAxisWidth = 0;
mutable verticalAxisHeight = 0;
}
}
Insert cell
mutable cellWidth = 0
Insert cell
mutable cellHeight = 0
Insert cell
mutable horizontalAxisWidth = 0
Insert cell
mutable horizontalAxisHeight = 0
Insert cell
mutable verticalAxisWidth = 0
Insert cell
mutable verticalAxisHeight = 0
Insert cell
mutable imgBank01 = FileAttachment('1.1.png').url()
Insert cell
mutable imgBank02 = FileAttachment('1.2.png').url()
Insert cell
mutable imgBank03 = FileAttachment('1.3.png').url()
Insert cell
mutable imgBank04 = FileAttachment('1.4.png').url()
Insert cell
mutable imgBank05 = FileAttachment('1.5.png').url()
Insert cell
mutable imgBank06 = FileAttachment('1.6.png').url()
Insert cell
mutable imgBank07 = FileAttachment('1.7.png').url()
Insert cell
mutable imgBank08 = FileAttachment('1.8.png').url()
Insert cell
mutable imgBank09 = FileAttachment('1.9.png').url()
Insert cell
mutable imgBank10 = FileAttachment('1.10.png').url()
Insert cell
mutable imgBank11 = FileAttachment('1.11.png').url()
Insert cell
mutable imgBank12 = FileAttachment('1.12.png').url()
Insert cell
mutable imgBank13 = FileAttachment('1.13.png').url()
Insert cell
mutable imgBank14 = FileAttachment('1.14.png').url()
Insert cell
mutable imgBank15 = FileAttachment('1.15.png').url()
Insert cell
mutable imgBank16 = FileAttachment('1.16.png').url()
Insert cell
mutable imgBank17 = FileAttachment('1.17.png').url()
Insert cell
mutable imgBank18 = FileAttachment('1.18.png').url()
Insert cell
mutable imgBank19 = FileAttachment('1.19.png').url()
Insert cell
mutable imgBank20 = FileAttachment('1.20.png').url()
Insert cell
mutable imgBank21 = FileAttachment('1.21.png').url()
Insert cell
mutable imgBank22 = FileAttachment('1.22.png').url()
Insert cell
mutable imgBank23 = FileAttachment('1.23.png').url()
Insert cell
mutable imgBank24 = FileAttachment('1.24.png').url()
Insert cell
mutable imgBank25 = FileAttachment('1.25.png').url()
Insert cell
mutable imgBank26 = FileAttachment('1.26.png').url()
Insert cell
mutable imgBank27 = FileAttachment('1.27.png').url()
Insert cell
mutable imgBank28 = FileAttachment('1.28.png').url()
Insert cell
mutable imgBank29 = FileAttachment('1.29.png').url()
Insert cell
mutable imgBank30 = FileAttachment('1.30.png').url()
Insert cell
mutable imgBank31 = FileAttachment('1.31.png').url()
Insert cell
mutable imgBank32 = FileAttachment('1.32.png').url()
Insert cell
mutable imgBank33 = FileAttachment('1.33.png').url()
Insert cell
mutable imgBank34 = FileAttachment('1.34.png').url()
Insert cell
mutable imgBank35 = FileAttachment('1.35.png').url()
Insert cell
mutable imgBank36 = FileAttachment('1.36.png').url()
Insert cell
mutable imgBank37 = FileAttachment('1.37.png').url()
Insert cell
mutable imgBank38 = FileAttachment('1.38.png').url()
Insert cell
mutable imgBank39 = FileAttachment('1.39.png').url()
Insert cell
mutable imgBank40 = FileAttachment('1.40.png').url()
Insert cell
whiteRectangleImgSrc = FileAttachment('whiterectangle.png').url();
Insert cell
svgs = {
let svgs = [];
configuration.dragStartX.splice(0, configuration.dragStartX.length);
configuration.dragStartX.splice(0, configuration.dragStartY.length);
configuration.canvasX.splice(0, configuration.canvasX.length);
configuration.canvasY.splice(0, configuration.canvasY.length);

// for (let i = 1; i <= 40; i++) svgs.push(d3.select("Task" + i + "_visual"));
svgs.push(d3.select(Task1_visual));
svgs.push(d3.select(Task2_visual));
svgs.push(d3.select(Task3_visual));
svgs.push(d3.select(Task4_visual));
svgs.push(d3.select(Task5_visual));
svgs.push(d3.select(Task6_visual));
svgs.push(d3.select(Task7_visual));
svgs.push(d3.select(Task8_visual));
svgs.push(d3.select(Task9_visual));
svgs.push(d3.select(Task10_visual));
svgs.push(d3.select(Task11_visual));
svgs.push(d3.select(Task12_visual));
svgs.push(d3.select(Task13_visual));
svgs.push(d3.select(Task14_visual));
svgs.push(d3.select(Task15_visual));
svgs.push(d3.select(Task16_visual));
svgs.push(d3.select(Task17_visual));
svgs.push(d3.select(Task18_visual));
svgs.push(d3.select(Task19_visual));
svgs.push(d3.select(Task20_visual));
svgs.push(d3.select(Task21_visual));
svgs.push(d3.select(Task22_visual));
svgs.push(d3.select(Task23_visual));
svgs.push(d3.select(Task24_visual));
svgs.push(d3.select(Task25_visual));
svgs.push(d3.select(Task26_visual));
svgs.push(d3.select(Task27_visual));
svgs.push(d3.select(Task28_visual));
svgs.push(d3.select(Task29_visual));
svgs.push(d3.select(Task30_visual));
svgs.push(d3.select(Task31_visual));
svgs.push(d3.select(Task32_visual));
svgs.push(d3.select(Task33_visual));
svgs.push(d3.select(Task34_visual));
svgs.push(d3.select(Task35_visual));
svgs.push(d3.select(Task36_visual));
svgs.push(d3.select(Task37_visual));
svgs.push(d3.select(Task38_visual));
svgs.push(d3.select(Task39_visual));
svgs.push(d3.select(Task40_visual));

for (let i = 0; i < svgs.length; i++) {
configuration.dragStartX.push(0);
configuration.dragStartY.push(0);
configuration.canvasX.push(0);
configuration.canvasY.push(0);
}
return svgs;
}
Insert cell
svgGroup = {
let svgGroup = [];

svgs.forEach((element, index) => {
let foreignObject = foreignObjectArray[index];

let tmpSvgGroup = element
.selectAll(".draggableGroup")
.data([{ x: 0, y: 0 }])
.enter()
.append("g")
.attr("class", "draggableGroup" + " cleanOnInit")
.attr("id", "parentGroup")
.attr("draggable", true)
.on('touchstart', () => {
configuration.dragStartX[index] = d3.event.touches[0].clientX;
configuration.dragStartY[index] = d3.event.touches[0].clientY;
})
.on("touchmove", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,
d3.event.touches[0].clientX - configuration.dragStartX[index],
d3.event.touches[0].clientY - configuration.dragStartY[index],
foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.touches[0].clientX;
configuration.dragStartY[index] = d3.event.touches[0].clientY;
})
.on("touchend", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,

d3.event.touches[0].clientX - configuration.dragStartX[index],
d3.event.touches[0].clientY - configuration.dragStartY[index],

foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.touches[0].clientX;
configuration.dragStartY[index] = d3.event.touches[0].clientY;
})
.call(
d3
.drag()
.on('start', () => {
configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
.on("drag", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,
d3.event.x - configuration.dragStartX[index],
d3.event.y - configuration.dragStartY[index],
foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
.on("end", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,

d3.event.x - configuration.dragStartX[index],
d3.event.y - configuration.dragStartY[index],

foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
);
svgGroup.push(tmpSvgGroup);
});

return svgGroup;
}
Insert cell
eventhandler = {
bHorizontalWrappingConfig;
bVerticalWrappingConfig;

svgs.forEach((element, index) => {
let foreignObject = foreignObjectArray[index];
element
.selectAll(".draggableGroup")
.data([{ x: 0, y: 0 }])
.attr("class", "draggableGroup" + " cleanOnInit")
.attr("id", "parentGroup")
.attr("draggable", true)
.call(
d3
.drag()
.on('start', () => {
configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
.on("drag", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,

d3.event.x - configuration.dragStartX[index],
d3.event.y - configuration.dragStartY[index],

foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
.on("end", () => {
transformGroup(
bHorizontalWrappingConfig,
bVerticalWrappingConfig,

d3.event.x - configuration.dragStartX[index],
d3.event.y - configuration.dragStartY[index],

foreignObject,
element,
index
);

configuration.dragStartX[index] = d3.event.x;
configuration.dragStartY[index] = d3.event.y;
})
);
});

return svgGroup;
}
Insert cell
configuration = new Object({
canvasX: [],
canvasY: [],
originX: 0,
originY: 0,
dragStartX: [],
dragStartY: [],
width: 30000,
height: 30000,
svgWidth: cellWidth * 3,
svgHeight: cellHeight * 3,
currentDraggingNode: {},
nonOverlappingDistance: 20,
hasBeenFixed: false
})
Insert cell
boundaryConfig = ({
"oneThirdWidth": cellWidth,
"twoThirdsWidth": cellWidth + cellWidth,
"oneThirdHeight": cellHeight,
"twoThirdsHeight": cellHeight + cellHeight
});
Insert cell
rectangle = {
let rectangle = [];
svgGroup.forEach(element => {
let tmpRectangle = element
.selectAll(".background")
.data([{ x: 0, y: 0 }])
.enter()
.append("rect")
.attr("x", configuration.originX)
.attr("y", configuration.originY)
.attr("rx", 0)
.attr("ry", 0)
.attr("fill-opacity", 0)
.attr("width", configuration.width)
.attr("height", configuration.height)
.attr("class", "background" + " cleanOnInit")
.style("stroke", "black")
.lower();
rectangle.push(tmpRectangle);
});

return rectangle;
}
Insert cell
foreignObjectArray = {
let foreignObjectArray = [];

svgs.forEach((element, index) => {
let foreignObject = [];
for (let i = 0; i < 9; i++) {
let originX = 0;
let originY = 0;
originX = configuration.canvasX[index] + shiftDistance[i].x;
originY = configuration.canvasY[index] + shiftDistance[i].y;

foreignObject.push(
element
.append("foreignObject")
.attr("x", originX)
.attr("y", originY)
.attr("width", cellWidth)
.attr("height", cellHeight)
.lower()
);

// add embedded body to foreign object
// let foBody = foreignObject[foreignObject.length - 1]
// .append("xhtml:body")
// .style("margin", "0px")
// .style("padding", "0px")
// .style("background-color", "none")
// .style("width", cellWidth + "px")
// .style("height", cellHeight + "px")
// .style("border", "0px none lightgray")
// .lower();

// add embedded canvas to embedded body
// let canvas = foBody
// .append("canvas")
// .attr("x", 0)
// .attr("y", 0)
// .style("display", "block")
// .style("margin", 0)
// .style("border", "0px none black")
// .attr("width", cellWidth)
// .attr("height", cellHeight)
// .lower();

// get drawing context of canvas
// let ctx = canvas.node().getContext("2d");

let canvas = foreignObject[foreignObject.length - 1]
.node()
.appendChild(document.createElement('canvas'));

d3.select(canvas)
.attr("x", 0)
.attr("y", 0)
.style("display", "block")
.style("margin", 0)
.style("border", "0px none black")
.attr("width", cellWidth)
.attr("height", cellHeight)
.lower();

// get drawing context of canvas
let ctx = canvas.getContext("2d");
let tmpImgSrc = "";
switch (index) {
case 0:
if (rbviewoption == "bw") tmpImgSrc = imgBank01;
else tmpImgSrc = imgBank01;
break;
case 1:
if (rbviewoption == "bw") tmpImgSrc = imgBank02;
else tmpImgSrc = imgBank02;
break;
case 2:
if (rbviewoption == "bw") tmpImgSrc = imgBank03;
else tmpImgSrc = imgBank03;
break;
case 3:
if (rbviewoption == "bw") tmpImgSrc = imgBank04;
else tmpImgSrc = imgBank04;
break;
case 4:
if (rbviewoption == "bw") tmpImgSrc = imgBank05;
else tmpImgSrc = imgBank05;
break;
case 5:
if (rbviewoption == "bw") tmpImgSrc = imgBank21;
else tmpImgSrc = imgBank21;
break;
case 6:
if (rbviewoption == "bw") tmpImgSrc = imgBank22;
else tmpImgSrc = imgBank22;
break;
case 7:
if (rbviewoption == "bw") tmpImgSrc = imgBank23;
else tmpImgSrc = imgBank23;
break;
case 8:
if (rbviewoption == "bw") tmpImgSrc = imgBank24;
else tmpImgSrc = imgBank24;
break;
case 9:
if (rbviewoption == "bw") tmpImgSrc = imgBank25;
else tmpImgSrc = imgBank25;
break;
case 10:
if (rbviewoption == "bw") tmpImgSrc = imgBank11;
else tmpImgSrc = imgBank11;
break;
case 11:
if (rbviewoption == "bw") tmpImgSrc = imgBank12;
else tmpImgSrc = imgBank12;
break;
case 12:
if (rbviewoption == "bw") tmpImgSrc = imgBank13;
else tmpImgSrc = imgBank13;
break;
case 13:
if (rbviewoption == "bw") tmpImgSrc = imgBank14;
else tmpImgSrc = imgBank14;
break;
case 14:
if (rbviewoption == "bw") tmpImgSrc = imgBank15;
else tmpImgSrc = imgBank15;
break;
case 15:
if (rbviewoption == "bw") tmpImgSrc = imgBank31;
else tmpImgSrc = imgBank31;
break;
case 16:
if (rbviewoption == "bw") tmpImgSrc = imgBank32;
else tmpImgSrc = imgBank32;
break;
case 17:
if (rbviewoption == "bw") tmpImgSrc = imgBank33;
else tmpImgSrc = imgBank33;
break;
case 18:
if (rbviewoption == "bw") tmpImgSrc = imgBank34;
else tmpImgSrc = imgBank34;
break;
case 19:
if (rbviewoption == "bw") tmpImgSrc = imgBank35;
else tmpImgSrc = imgBank35;
break;
case 20:
if (rbviewoption == "bw") tmpImgSrc = imgBank06;
else tmpImgSrc = imgBank06;
break;
case 21:
if (rbviewoption == "bw") tmpImgSrc = imgBank07;
else tmpImgSrc = imgBank07;
break;
case 22:
if (rbviewoption == "bw") tmpImgSrc = imgBank08;
else tmpImgSrc = imgBank08;
break;
case 23:
if (rbviewoption == "bw") tmpImgSrc = imgBank09;
else tmpImgSrc = imgBank09;
break;
case 24:
if (rbviewoption == "bw") tmpImgSrc = imgBank10;
else tmpImgSrc = imgBank10;
break;
case 25:
if (rbviewoption == "bw") tmpImgSrc = imgBank26;
else tmpImgSrc = imgBank26;
break;
case 26:
if (rbviewoption == "bw") tmpImgSrc = imgBank27;
else tmpImgSrc = imgBank27;
break;
case 27:
if (rbviewoption == "bw") tmpImgSrc = imgBank28;
else tmpImgSrc = imgBank28;
break;

case 28:
if (rbviewoption == "bw") tmpImgSrc = imgBank29;
else tmpImgSrc = imgBank29;
break;
case 29:
if (rbviewoption == "bw") tmpImgSrc = imgBank30;
else tmpImgSrc = imgBank30;
break;
case 30:
if (rbviewoption == "bw") tmpImgSrc = imgBank16;
else tmpImgSrc = imgBank16;
break;
case 31:
if (rbviewoption == "bw") tmpImgSrc = imgBank17;
else tmpImgSrc = imgBank17;
break;
case 32:
if (rbviewoption == "bw") tmpImgSrc = imgBank18;
else tmpImgSrc = imgBank18;
break;
case 33:
if (rbviewoption == "bw") tmpImgSrc = imgBank19;
else tmpImgSrc = imgBank19;
break;
case 34:
if (rbviewoption == "bw") tmpImgSrc = imgBank20;
else tmpImgSrc = imgBank20;
break;
case 35:
if (rbviewoption == "bw") tmpImgSrc = imgBank36;
else tmpImgSrc = imgBank36;
break;
case 36:
if (rbviewoption == "bw") tmpImgSrc = imgBank37;
else tmpImgSrc = imgBank37;
break;
case 37:
if (rbviewoption == "bw") tmpImgSrc = imgBank38;
else tmpImgSrc = imgBank38;
break;
case 38:
if (rbviewoption == "bw") tmpImgSrc = imgBank39;
else tmpImgSrc = imgBank39;
break;
case 39:
if (rbviewoption == "bw") tmpImgSrc = imgBank40;
else tmpImgSrc = imgBank40;
break;
case 40:
if (rbviewoption == "bw") tmpImgSrc = imgBank40;
else tmpImgSrc = imgBank40;
break;
}
draw(ctx, tmpImgSrc);
}
foreignObjectArray.push(foreignObject);
});

return foreignObjectArray;
}
Insert cell
//draw image
draw = (ctx, srcUrl) => {
let img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = srcUrl;
}
Insert cell
transformGroup = (
bHorizontalWrappingConfig,
bVerticalWrappingConfig,
offsetX,
offsetY,
foreignObject,
svgs,
index
) => {
if (bHorizontalWrappingConfig != null && bHorizontalWrappingConfig)
configuration.canvasX[index] += offsetX;
if (bVerticalWrappingConfig != null && bVerticalWrappingConfig)
configuration.canvasY[index] += offsetY;

if (configuration.canvasX[index] > boundaryConfig.twoThirdsWidth) {
configuration.canvasX[index] -= boundaryConfig.oneThirdWidth;
} else if (configuration.canvasX[index] < boundaryConfig.oneThirdWidth) {
configuration.canvasX[index] += boundaryConfig.oneThirdWidth;
}

if (configuration.canvasY[index] > boundaryConfig.twoThirdsHeight) {
configuration.canvasY[index] -= boundaryConfig.oneThirdHeight;
} else if (configuration.canvasY[index] < boundaryConfig.oneThirdHeight) {
configuration.canvasY[index] += boundaryConfig.oneThirdHeight;
}

for (var i = 0; i < 9; i++) {
foreignObject[i].attr(
"x",
configuration.canvasX[index] + shiftDistance[i].x
);
foreignObject[i].attr(
"y",
configuration.canvasY[index] + shiftDistance[i].y
);
}
svgs
.selectAll(".draggableGroup")
.selectAll(".whiteRectangle")
.raise();
}
Insert cell
shiftDistance = {
let width = cellWidth;
let height = cellHeight;
let shiftDistance = [
{"x": -width, "y": -height},
{"x": 0, "y": -height},
{"x": width, "y": -height},
{"x": -width, "y": 0},
{"x": 0, "y": 0},
{"x": width, "y": 0},
{"x": -width, "y": height},
{"x": 0, "y": height},
{"x": width, "y": height},
];
return shiftDistance;
}
Insert cell
d3 = require("d3@5")
Insert cell
Insert cell
import { radio } from "@jashkenas/inputs"
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