Public
Edited
May 12, 2023
Importers
8 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// v and w are vectors represented as arrays
addVector = function(v, w){
let out = [];
for (let i = 0; i < v.length; i++){
out[i] = v[i] + w[i];
}
return out;
}
Insert cell
Insert cell
// v is a vector represented as array
// and c is a number (scalar)
// returns a scaled vector
multiplyScalar = function(v, c){
let out = [];
for (let i = 0; i < v.length; i++){
out[i] = v[i] * c;
}
return out;
}
Insert cell
Insert cell
Insert cell
// v and w are arrays
subtractVector = function(v, w){
return addVector(v, multiplyScalar(w, -1));
}
Insert cell
Insert cell
multiplyMatrix = (v, m) => {
// The output of a linear transformation on the vector v
const o = [];
// Each component of the vector acts as a scalar
// of i-hat and j-hat respectively
for (let i = 0, l = m.length; i < l; i++){
o[i] = multiplyScalar(m[i], v[i]);
}
// Sum the resulting vectors
let s = [0, 0];
for (let i = 0, l = o.length; i < l; i++){
s = addVector(s, o[i]);
}
return s;
}
Insert cell
vector = [2, 4] // some random vector
Insert cell
matrix = [[1, 0], [0, 1]] // basis vectors i-hat and j-hat. change these to get the linear transformation
Insert cell
rotation = [[0, 1], [-1, 0]]; // rotation matrix
Insert cell
shear = [[1, 0], [1, 1]]; // shear matrix
Insert cell
start = multiplyMatrix(vector, matrix);
Insert cell
rotated = multiplyMatrix(vector, rotation);
Insert cell
sheared = multiplyMatrix(vector, shear);
Insert cell
Insert cell
Insert cell
dotProduct = (v1, v2) => {
let o = 0;
for (let i = 0, l = v1.length; i < l; i++){
o += v1[i] * v2[i];
}
return o;
}
Insert cell
u1 = [1/3, -1/3, 1/3]
Insert cell
u2 = [-1/10, 0, 1/10]
Insert cell
dotProduct(u2, u2)
Insert cell
Insert cell
vecLength = v => Math.sqrt(dotProduct(v, v));
Insert cell
vecLength([2, 2, 2, 2]); // It scales easily to multiple dimensions!
Insert cell
vecLength([Math.sqrt(.25), Math.sqrt(.25), Math.sqrt(.25), Math.sqrt(.25)])
Insert cell
// In the xy plane, the unit vector that
// makes an angle "theta" with the x axis
// is (cosθ, sinθ)
vecLength([Math.cos(90), Math.sin(90)]);
Insert cell
sqrt(62)
Insert cell
vecLength([2, 3, -7])
Insert cell
dotProduct([2, 3, -7], [2, 3, -7])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
drawAxes = (sel, x, y) => {
const width = x.range()[1], height = y.range()[0];
const xgrid = sel.append("g")
.attr("class", "grid x")
.call(d3.axisBottom(x).tickSize(height));
xgrid.selectAll("line").style("stroke", "#eee");
xgrid.selectAll("text").remove();
xgrid.select(".domain").remove();
const ygrid = sel.append("g")
.attr("class", "grid y")
.call(d3.axisLeft(y).tickSize(width))
.attr("transform", `translate(${width})`);
ygrid.selectAll("line").style("stroke", "#eee");
ygrid.selectAll("text").remove();
ygrid.select(".domain").remove();
sel.append("g")
.attr("class", "axis x")
.attr("transform", `translate(0, ${height / 2})`)
.call(d3.axisBottom(x));
sel.append("g")
.attr("class", "axis y")
.attr("transform", `translate(${width / 2})`)
.call(d3.axisLeft(y));
return sel;
}
Insert cell
drawVector = (g, x, y) => {
const origin = [0, 0],
scaled = v => [x(v[0]), y(v[1])];
let polyline = g.select("polyline");
if (polyline.empty()){
polyline = g.append("polyline")
.attr("points", d => [scaled(origin), scaled(d)])
.attr("stroke", "black")
.attr("marker-end", "url(#arrow)");
}
else {
polyline
.attr("points", d => [scaled(origin), scaled(d)])
}
let text = g.select("text");
if (text.empty()){
text = g.append("text")
.attr("dx", d => d[0] >= 0 ? 3 : -3)
.attr("transform", d => `translate(${scaled(d)})`)
.style("font-style", "italic")
.style("font-size", 11)
.style("text-anchor", d => d[0] >= 0 ? "start" : "end")
.text(d => d);
}
else {
text
.attr("dx", d => d[0] >= 0 ? 3 : -3)
.attr("transform", d => `translate(${scaled(d)})`)
.style("text-anchor", d => d[0] >= 0 ? "start" : "end")
.text(d => d);
}

}
Insert cell
createArrowhead = (svg, id, color) => {
let defs = svg.select("defs");
if (defs.empty()) {
defs = svg.append("defs");
}
defs.append("marker")
.attr("id", id)
.attr("viewBox", "0 0 10 10")
.attr("refX", "10")
.attr("refY", "5")
.attr("markerWidth", "6")
.attr("markerHeight", "6")
.attr("orient", "auto-start-reverse")
.append("path")
.style("fill", color || "black")
.attr("d", "M 0 0 L 10 5 L 0 10 z");
}
Insert cell
Insert cell
Insert cell
sqrt = Math.sqrt
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