Public
Edited
Oct 12, 2023
Insert cell
md`# Stressed Trout 3`
Insert cell
viewof v1 = html`<input type=checkbox>`
Insert cell
Insert cell
expand = function(cells){
cells.each(function (d) {
var u = 1 / Math.sqrt(d.surface);
d.children.forEach(function (t) {
t.length *= u;
t.length = Math.min(t.length, 1.1);
})
})
}
Insert cell
redScale = d3.scaleSequentialPow(["#534542","red"]).exponent(4)
Insert cell
import {ramp} from "@d3/sequential-scales"
Insert cell
ramp(redScale)
Insert cell
redSpots = {
const min = ratios[1]
const max = ratios[2]
let number = max - min
for (var i=0; i<number; i++) {
var index = Math.floor(Math.random() * (max - min) + min) ;
data[index].color = redScale(Math.random())
}
return data
}
Insert cell
data = generateData()
Insert cell
spotBlur = function(defs){
var filter = defs.append("filter")
.attr("id","blur")
.attr("width","400%")
.attr("height","400%")
.attr("x","-100%")
.attr("y","-100%");
filter.append("feGaussianBlur")
.attr("stdDeviation","0.3")
.attr("result","coloredBlur");
var feMerge = filter.append("feMerge");
feMerge.append("feMergeNode")
.attr("in","coloredBlur");
// feMerge.append("feMergeNode")
// .attr("in","SourceGraphic");
}

Insert cell
blur = function(defs) {
var filter = defs.append("filter")
.attr("id","glow")
.attr("width","400%")
.attr("height","400%")
.attr("x","-100%")
.attr("y","-100%")
filter.append("feMorphology")
.attr("in", "SourceGraphic")
.attr("result", "upperLayer")
.attr("operator", "dilate")
.attr("radius", "3 3");
filter.append("feGaussianBlur")
.attr("in", "SoureGraphic")
.attr("stdDeviation","1 1")
.attr("result","LowerBlur");
filter.append("feMorphology")
.attr("in", "SourceGraphic")
.attr("result", "englargedAlpha")
.attr("operator", "dilate")
.attr("radius", "3 3");
filter.append("feGaussianBlur")
.attr("in", "enlargedAlpha")
.attr("stdDeviation","4 4")
.attr("result","coloredBlur");
// Control opacity of shadow filter
var feMerge = filter.append("feMerge");
// feMerge.append("feMergeNode")
// .attr("in","coloredBlur");
feMerge.append("feMergeNode")
.attr("in","lowerBlur");
feMerge.append("feMergeNode")
.attr("in","SourceGraphic");
}
Insert cell
gradientDef = function(container,defs) {
var gradient = defs
.append('linearGradient')
.attr('x1', '0%')
.attr('x2', '0%')
.attr('y1', '0%')
.attr('y2', '100%')
.attr("id","gradient");
gradient.append("stop")
.attr("offset",0)
.style("stop-color", "#2d2319");
gradient.append("stop")
.attr("offset",0.07)
.style("stop-color", "#534542");
gradient.append("stop")
.attr("offset",0.23)
.style("stop-color", "#776554");

gradient.append("stop")
.attr("offset",0.72)
.style("stop-color", "#dbbf75");

gradient.append("stop")
.attr("offset",1)
.style("stop-color", "#f6f6f6");
}
Insert cell
color = function(i) { return d3.cubehelix((i%100)*3.60, 1.2, 0.6); }
Insert cell
function nodes(quadtree){
var nodes = [];
quadtree.visit(function(node,x0,y0,x1,y1){
node.x0 = x0, node.y0 = y0;
node.x1 = x1, node.y1 = y1;
nodes.push(node);
});
return nodes;
}
Insert cell
width = 500;
Insert cell
height = 150;
Insert cell
radiusSorted = {let radiusArray = [];
let data = generateData();

data.map(function(d,i){
radiusArray.push([i,d.r])
})

radiusArray.sort(function(a,b){return a[1]-b[1]})
return radiusArray
}

Insert cell
bandSizing = function(numPoints, bandRatio) {
let unit = numPoints / d3.sum(bandRatio)
let sizes = bandRatio.map(d => d * unit)

let breakpoints = []

for (let i=0; i < sizes.length; i++){
breakpoints[i] = i == 0? sizes[i] : breakpoints[i-1] + sizes[i]
}
return breakpoints
}
Insert cell
dataSize = 200;
Insert cell
ratios = bandSizing(dataSize,[6,3,3]);
Insert cell
function generateData(){
let data = d3.range(dataSize)
.map(function (i) {
var a = 2 * Math.PI * Math.random(), //A random point along a circle
d = Math.sqrt(Math.random()) //Distribution Factor
// bandSize = dataSize / 3
return {
band: i >= ratios[1] ? 3 : (i > ratios[0] ? 2 : 1),
id: i,
// r: 4 * (1 + 5 * Math.random() * Math.random()),
// x: width * Math.cos(a) * d,
x: width * Math.random(),
// y: 200 * Math.sin(a) * d,
y: height * Math.sqrt(Math.random()),
// y: d.r < 7 ? height * 0.3 : height,
color: '#534542',
};
})
//Add n feelers
.map(function (d) {
d.y = d.band == 2 ? height * 0.5 :
d.band == 1 ? height * 0.3 :
height * 0.7
// d.y = d.band == 2 ? height*0.5 + (height - height*0.3) * Math.random() :
// d.band == 1 ? height * 0.3 :
// height * 0.7
// d.r = d.band == 2 ? 2 * (Math.random() * 3 + 1.5) :
// (Math.random() * 2 + 1.5);
d.r = d.band == 2 ? 7 : 4;
d.buffer = (d.r * 0.2) + 1;
var n = Math.floor(4 + d.r) //Start at a random point along circle
d.children = d3.range(n)
.map(function (i) {
//Plot points around the radius of a circle
var angle = Math.PI - (i * (Math.PI * 2 / n)),
// var angle = i * (Math.PI * 2 / n),
t = {
length: 1,
angle: angle,
sin: Math.sin(angle),
cos: Math.cos(angle),
parent: d,
};
return t;
});
return d;
});
return data;
}
Insert cell
line = d3.radialLine()
.curve(d3.curveCatmullRomClosed);
Insert cell
d3 = require("d3@5", "d3-scale@^3.2.0")
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