Public
Edited
Apr 4
Insert cell
Insert cell
Insert cell
Insert cell
limits = {return{limX:100, limY:10}}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let heightRul = distanceRul*heightObj/distanceObj;
let lines = [{dist:distanceObj, height:heightObj},//object
{dist:distanceRul, height:heightRul},//object
];
let dy = 100*0.001
return Plot.plot({
width:1130,
height:360,
x: { domain:[-5,100] },
y: { domain:[-1,30] },
marks: [
Plot.link([lines[1]],{x1:d=>d.dist,x2:d=>d.dist, y1:0, y2:"height", stroke:"gray", strokeWidth:3 }), //ruler
Plot.link([lines[0]],{x1:d=>d.dist,x2:d=>d.dist, y1:0, y2:"height", stroke:"black", strokeWidth:4 }), //object

Plot.link(lines,{x1:0, x2:"dist", y1:(d,i)=>(i*dy), y2:(d,i)=>(i*dy), dy:(d,i,a)=>((+i)+3)*(-8), strokeDasharray:"2 4"}),
Plot.link(lines,{x1:0, x2:"dist", y1:0, y2:"height", dy:(d,i,a)=>((+i)+3)*(-8), strokeDasharray:"2 4"}),
Plot.rect([lines[1]], {x1:d=>d.dist+0.5, x2:d=>d.dist+3, y1:0, y2:26, fill:"white", stroke:"black", strokeWidth:1, opacity:0.9 }),
Plot.text([lines[1]],{x:"dist", y:d=>d.height/2, dx:20, text:"Object's height", fill:"black"}),
Plot.text([lines[0]],{x:"dist", y:d=>d.height/2, dx:30, text:d=>"Object's\nheight", fill:"black"}),
Plot.text([lines[1]],{x:"dist", y:d=>d.height/2, dx:-15, text:d=>"Object's\napparent\nheight", textAnchor:"end", fill:"black"}),
]
})

}

Insert cell
Insert cell
viewof rulerDist = Inputs.range([1, 300], {label: "Ruler Distance:", step:1, value:30}) //Fixed 20cm,30cm or screen distance
Insert cell
viewof objDist = Inputs.range([rulerDist, 300], {label: "Object's Distance", step: 1})
Insert cell
viewof objHeight = Inputs.range([1, 100], {label: "Object's Height at ruler distance (px)", step: 1, value:50}) //Fixed Circle diameter
Insert cell
function objAppHeight(objDistance){return objHeight* rulerDist/objDistance}
Insert cell
Plot.plot({
x:{domain:[0,20]},
marks: [
Plot.dot([1], {x: 10, y: 0, r:objAppHeight(objDist) }),
Plot.dot([1], {x: 10, y: 0, r:objHeight, stroke:"blue", strokeDasharray:"8 8", opacity:1, strokeWidth:1.4 })
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let dotRadius = 40;

const svgSize={height:400, width:800};
const svg = d3.create("svg").attr("height",svgSize.height).attr("width",svgSize.width);
let elps = svg.append("ellipse")
.attr("cx", (svgSize.width/2)).attr("cy", (7*svgSize.height/8) - radius*Math.sin(angleCont*Math.PI/180) )
.attr("rx",radius).attr("ry", radius*Math.sin(angleCont*Math.PI/180))
.attr("stroke", "blue").attr("fill","none")
//.attr("transform", "translate("+(svgSize.width/2)+","+svgSize.height/2+")")

let angDivisions = d3.range(0,(2*Math.PI), (2*Math.PI)/divisions);
let dots = svg.selectAll("circle").data(angDivisions).enter().append("circle")
.attr("cx", d=>+elps.attr("cx")+Math.sin(d)*radius)

.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.sin(angleCont*Math.PI/180))
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.sin(angleCont*Math.PI/180))
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.cos(angleCont*Math.PI/180))
//.attr("r",10);
.attr("r", d=>dotAppHeight( dotDist+Math.cos(angleCont*Math.PI/180)*radius * (Math.sin(d-Math.PI/2)+1)/2 , dotRadius) )
.attr("fill",(d,i)=>d3.interpolateRainbow(i/divisions));

if(raiseDot){
dots.sort((a,b)=>Math.cos(a)-Math.cos(b)); //already re-inserts in the specified sort order.
}
//dots.exit().remove();
return svg.node();
}
Insert cell
dotAppHeight(dotDist, 20)
Insert cell
function dotAppHeight(dotDistance, dotRadius){return dotRadius* rulerDotDist/dotDistance}
Insert cell
viewof rgX = Inputs.range([0, Math.PI*2], {label: "Amount"})
Insert cell
(rgX*180/Math.PI).toFixed(1)+" graus"
Insert cell
Math.sin(rgX-Math.PI/2)
Insert cell
Math.cos(rgX)
Insert cell
Inputs.bind( Inputs.range([1, 90], {label: "Angle", step: 1}), viewof angleCont)
Insert cell
{
let dotRadius = 40;

let svgSize={height:500, width:800};
//Center of the Round Countainer
let center = {cx: (svgSize.width/2),
cy: (svgSize.height/2) };
//cy: svgSize.height*0.9};

let bottomTranslation = -radius*Math.sin( degToRad(angleCont) );
let svg = d3.create("svg").attr("height",svgSize.height).attr("width",svgSize.width);
let elps = svg.append("ellipse")
.attr("cx", center.cx ).attr("cy", center.cy )
.attr("rx",radius).attr("ry", radius*Math.sin( degToRad(angleCont) ))
.attr("stroke", "gray").attr("strokeWidth",3).attr("fill","none")
//.attr("stroke-dasharray", "2 8")
//.attr("transform", "translate("+(svgSize.width/2)+","+svgSize.height/2+")")

let angDivisions = d3.range(0,(2*Math.PI), (2*Math.PI)/divisions);
let dots = svg.selectAll("circle").data(angDivisions).enter().append("circle")
.attr("cx", d=> center.cx+Math.cos(d)*radius)
.attr("cy",d=>(center.cy-Math.sin(d)*radius) * Math.sin( degToRad(angleCont) ) )
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.sin( degToRad(angleCont) ))
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.cos( degToRad(angleCont) ))
//.attr("transform","translate(0,"+bottomTranslation+")")
//.attr("r",10);
.attr("r", d=>dotAppHeight( dotDist+Math.cos( degToRad(angleCont) )*radius * (Math.sin(d)+1)/2 , dotRadius) )
.attr("fill",(d,i)=>d3.interpolateBlues(i/divisions));

if(raiseDot){
dots.sort((a,b)=>Math.cos(a+Math.PI/2)-Math.cos(b+Math.PI/2)); //already re-inserts in the specified sort order.
}
//dots.exit().remove();
return svg.node();
}
Insert cell
angSamps = d3.range(0,720,15).map(d=>degToRad(d))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function radToDeg(rad, cycle){ if(cycle==true){return rad*180/Math.PI%360}else{return rad*180/Math.PI} }
Insert cell
radToDeg(2*Math.PI, 1)
Insert cell
function degToRad(deg){return Math.PI*deg/180}
Insert cell
degToRad(360)
Insert cell
d3.range( 0,divisions, 1).map(d=> d*2*Math.PI/divisions)
Insert cell
angDivisions = d3.range(0,(2*Math.PI), (2*Math.PI)/divisions);
Insert cell
angDivisions.map(d=>radToDeg(d))
Insert cell
Insert cell
viewof inRadius = Inputs.range([50, 150], {label: "Inner Radius (px)", step: 10})
Insert cell
arcGen = d3.arc().innerRadius(inRadius).outerRadius(100).startAngle(0).endAngle(Math.PI / 4)
Insert cell
arcGen()
Insert cell
{
let svgSize={height:300, width:300};
let svg = d3.create("svg").attr("height",svgSize.height).attr("width",svgSize.width);
let arc = arcGen();

let g = svg.append("g").attr("transform","translate("+svgSize.width/2+","+svgSize.height/2+")")
g.append("path").attr("d",arc ).attr("stroke","purple").attr("fill","orange");
return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Plot.plot({
height: 300,
width: 1100,
marginLeft: 100,
y:{domain:[-5,25]},
marks: [
Plot.arrow(d3.range(0,120, 15), {x1:d=>d/10, x2: d=>d, y1:0, y2: 20, bend:ipBend, headAngle:ipHeadAngle, headLength: ipHeadLength, stroke:"black"}),
Plot.ruleY([0, 20],{opacity:0.5})
]
})
Insert cell
Insert cell
{
let planes = 3;

let svgSize={height:500, width:800};
//Center of the Round Countainer
let center = {cx: (svgSize.width/2),
cy: (svgSize.height/2) };
//cy: svgSize.height*0.9};

let bottomTranslation = -radius*Math.sin( degToRad(angleCont) );
let svg = d3.create("svg").attr("height",svgSize.height).attr("width",svgSize.width);
let elps = svg.append("ellipse")
.attr("cx", center.cx ).attr("cy", center.cy )
.attr("rx",radius).attr("ry", radius*Math.sin( degToRad(angleCont) ))
.attr("stroke", "gray").attr("strokeWidth",3).attr("fill","none")
//.attr("stroke-dasharray", "2 8")
//.attr("transform", "translate("+(svgSize.width/2)+","+svgSize.height/2+")")

let angDivisions = d3.range(0,(2*Math.PI), (2*Math.PI)/divisions);
let dots = svg.selectAll("circle").data(angDivisions).enter().append("circle")
.attr("cx", d=> center.cx+Math.cos(d)*radius)
.attr("cy",d=>(center.cy-Math.sin(d)*radius) * Math.sin( degToRad(angleCont) ) )
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.sin( degToRad(angleCont) ))
//.attr("cy",d=>(+elps.attr("cy")+Math.cos(d)*radius)*Math.cos( degToRad(angleCont) ))
//.attr("transform","translate(0,"+bottomTranslation+")")
//.attr("r",10);
.attr("r", d=>dotAppHeight( dotDist+Math.cos( degToRad(angleCont) )*radius * (Math.sin(d)+1)/2 , dotRadius) )
.attr("fill",(d,i)=>d3.interpolateBlues(i/divisions));

if(raiseDot){
dots.sort((a,b)=>Math.cos(a+Math.PI/2)-Math.cos(b+Math.PI/2)); //already re-inserts in the specified sort order.
}
//dots.exit().remove();
return svg.node();
}
Insert cell
https://observablehq.com/@mbostock/form-input
https://observablehq.com/@mbostock/conditional-form
https://observablehq.com/@erikneves/drugs
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