Public
Edited
Jan 11, 2023
1 fork
Insert cell
Insert cell
cloneData = await FileAttachment("y2.json").json()
Insert cell
createBellPlotTree = function(cloneData) {
const nodes = new Map(
cloneData.map(clone => [
clone.lab,
{
id: clone.lab,
fraction: clone.vaf,
color: clone.color,
children: [],
data: clone
}
])
);

let root;
for (const node of nodes.values()) {
if (node.data.parent > 0) {
nodes.get(node.data.parent).children.push(node);
} else if (node.data.parent == -1) {
root = node;
}
}

const rootFraction = root.fraction;
for (const node of nodes.values()) {
node.fraction /= rootFraction;
}

return root;
}
Insert cell
tree = createBellPlotTree(cloneData.models.XXXX_pOme1_DNA[2])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
const domNode = DOM.svg(700, 300);
const svg = SVG.SVG(domNode);

const g = svg.group().transform({
translateY: 150
});

const rootHeight = 200;
const rootWidth = 400;

const straightPincher = (x) => 1;
const hornPincher = (x) => hornSlope + x * (1 - hornSlope);

const zeroShifter = (x) => 0;

function drawNode(
node,
shifter,
pincher,
parentPosition = 0,
position = 0,
depth = 0
) {
const segmentCount = 100;

const newPincher = node.shared
? pincher
: (x) =>
pincher(x) *
growthStep(
depth,
depth + growthPeriod,
x,
depth == 0 ? rootTipSize / hornPincher(0) : 0
);

const yf = (x, side) =>
side * newPincher(x) * node.fraction + position - shifter(x);

const p = d3.path();
p.moveTo(0, (yf(0, 1) * rootHeight) / 2);
// TODO: Skip parts that are invisibly thin
for (let i = 1; i <= segmentCount; i++) {
const x = i / segmentCount;
p.lineTo(x * rootWidth, (yf(x, 1) * rootHeight) / 2);
}
for (let i = segmentCount; i >= 0; i--) {
const x = i / segmentCount;
p.lineTo(x * rootWidth, (yf(x, -1) * rootHeight) / 2);
}
// TODO: Convert to splines and béziers:
// https://github.com/d3/d3-shape/blob/master/README.md#curveCatmullRom
// Consider http://paperjs.org/tutorials/paths/smoothing-simplifying-flattening/
const clonePath = g.path(p.toString());
if (typeof node.driftTo === "number") {
clonePath.fill(
svg
.gradient("linear", function (add) {
/* TODO
add.stop(0, scheme[node.id]);
add.stop(1, scheme[node.driftTo])
*/
})
.from(depth, 0)
.to(1, 0)
);
} else {
clonePath.fill(node.color);
}
clonePath.addClass("clone");
clonePath.data("clone", node.data);

const positions = computeChildPositions(node);
for (let i = 0; i < node.children.length; i++) {
const childNode = node.children[i];
console.log(`id: ${childNode.id}: ${positions[i] * 2 - position}`);
drawNode(
childNode,
(y) => positions[i] * 2 * (1 - newPincher(y)) + shifter(y),
newPincher,
position,
position + positions[i] * 2,
depth + depthStep
);
}
}

drawNode(tree, zeroShifter, hornPincher, 0);

return domNode;
}
Insert cell
Insert cell
Insert cell
clamp = (lower, upper, x) => Math.max(lower, Math.min(upper, x))
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
SVG = import("@svgdotjs/svg.js")
Insert cell
d3scaleChromatic = require('d3-scale-chromatic')
Insert cell
import {slider} from '@jashkenas/inputs'
Insert cell
dataframeToD3 = function(df) {
// source: https://github.com/ramnathv/htmlwidgets/blob/master/inst/www/htmlwidgets.js
var names = [];
var length;
for (var name in df) {
if (df.hasOwnProperty(name))
names.push(name);
if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
throw new Error("All fields must be arrays");
} else if (typeof(length) !== "undefined" && length !== df[name].length) {
throw new Error("All fields must be arrays of the same length");
}
length = df[name].length;
}
var results = [];
var item;
for (var row = 0; row < length; row++) {
item = {};
for (var col = 0; col < names.length; col++) {
item[names[col]] = df[names[col]][row];
}
results.push(item);
}
return results;
};
Insert cell
d3 = require("d3")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more