Skip to content

Commit

Permalink
Merge pull request #42 from GordonSmith/NOTEBOOK
Browse files Browse the repository at this point in the history
fix(renderer): Workaround delay loading of cells
  • Loading branch information
GordonSmith committed Sep 4, 2022
2 parents a04de1d + 22a5683 commit a24be73
Show file tree
Hide file tree
Showing 31 changed files with 715 additions and 1,261 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
],
"main": "./dist/extension.js",
"scripts": {
"clean": "rimraf out lib* dist types *.vsix",
"clean": "rimraf out lib* dist types *.vsix *.tsbuildinfo",
"compile": "tsc",
"compile-watch": "npm run compile -- -watch",
"compile-es6": "tsc --module es6 --outDir ./lib-es6",
Expand Down Expand Up @@ -364,4 +364,4 @@
}
]
}
}
}
2 changes: 1 addition & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default [{
},
plugins: plugins
}, {
input: "./lib-es6/notebook/renderers/index",
input: "./lib-es6/notebook/renderers/renderer",
output: [{
file: "dist/ojsRenderer.js",
format: "es",
Expand Down
219 changes: 167 additions & 52 deletions samples/tmp.ojs
Original file line number Diff line number Diff line change
@@ -1,60 +1,175 @@
md`
# 3D Sample
`;
md`# Projection Transitions

{
const div = DOM.element('div');

Plotly.newPlot(div, data, layout);

return div;
}
This notebook interpolates smoothly between projections; this is easiest when both projections are well-defined over the given viewport (here, the world).`

md`
---
`;
viewof projection = {
const input = projectionInput({
value: new URLSearchParams(location.search).get("projection"),
name: "projection"
});
const interval = setInterval(() => {
input.i.selectedIndex = (input.i.selectedIndex + 1) % projections.length;
input.dispatchEvent(new CustomEvent("input"));
}, 1500);
input.addEventListener("change", () => clearInterval(interval));
invalidation.then(() => clearInterval(interval));
return input;
}

rawData = await d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv');
viewof context = {
const context = DOM.context2d(width, height);
context.canvas.style.display = "block";
context.canvas.style.maxWidth = "100%";
context.canvas.value = context;
return context.canvas;
}

function unpack(rows, key) {
return rows.map(row => row[key]);
function render(projection) {
const path = d3.geoPath(projection, context);
context.clearRect(0, 0, width, height);
context.save();
context.beginPath(), path(outline), context.clip(), context.fillStyle = "#fff", context.fillRect(0, 0, width, height);
context.beginPath(), path(graticule), context.strokeStyle = "#ccc", context.stroke();
context.beginPath(), path(land), context.fillStyle = "#000", context.fill();
context.restore();
context.beginPath(), path(outline), context.strokeStyle = "#000", context.stroke();
}

function zData(rows) {
let z_data=[ ]
for(let i=0;i<24;i++)
{
z_data.push(unpack(rows,i));
}
return z_data;
}

data = [{
z: zData(rawData),
type: 'surface',
contours: {
z: {
show:true,
usecolormap: true,
highlightcolor:"#42f462",
project:{z: true}
}
update = {
const r0 = mutable previousProjection;
const r1 = projection;
if (r0 === r1) return;
mutable previousProjection = r1;
const interpolate = interpolateProjection(r0, r1);
for (let j = 1, m = 45; true; ++j) {
const t = Math.min(1, ease(j / m));
render(interpolate(t).rotate([performance.now() / 100, 0]));
yield;
}
}];


layout = ({
title: 'Mt Bruno Elevation With Projected Contours',
scene: {camera: {eye: {x: 1.87, y: 0.88, z: -0.64}}},
autosize: false,
width,
height: 800,
margin: {
l: 65,
r: 50,
b: 65,
t: 90,
}
})
}

mutable previousProjection = d3.geoEquirectangularRaw

function interpolateProjection(raw0, raw1) {
const {scale: scale0, translate: translate0} = fit(raw0);
const {scale: scale1, translate: translate1} = fit(raw1);
return t => d3.geoProjection((x, y) => lerp2(raw0(x, y), raw1(x, y), t))
.scale(lerp1(scale0, scale1, t))
.translate(lerp2(translate0, translate1, t))
.precision(0.1);
}

function lerp1(x0, x1, t) {
return (1 - t) * x0 + t * x1;
}

function lerp2([x0, y0], [x1, y1], t) {
return [(1 - t) * x0 + t * x1, (1 - t) * y0 + t * y1];
}

function fit(raw) {
const p = d3.geoProjection(raw).fitExtent([[0.5, 0.5], [width - 0.5, height - 0.5]], outline);
return {scale: p.scale(), translate: p.translate()};
}

ease = d3.easeCubicInOut

width = 954

height = 600

outline = ({type: "Sphere"})

graticule = d3.geoGraticule10()

land = topojson.feature(world, world.objects.land)

world = FileAttachment(/* "land-110m.json" */"https://static.observableusercontent.com/files/f75ca3dc7c0b65cf225cea300e01e5e3cb5abf4ad75592936a2b6c79b797e933a208355d31d5b160f5b1db2a7de61fa402fe279d036a052211cd09462f524cad").json()

topojson = require("topojson-client@3")

d3 = require("d3-geo@2", "d3-geo-projection@3", "d3-ease@2")

projections = [
{name: "Aitoff", value: d3.geoAitoffRaw},
{name: "American polyconic", value: d3.geoPolyconicRaw},
{name: "August", value: d3.geoAugustRaw},
{name: "Baker dinomic", value: d3.geoBakerRaw},
{name: "Boggs’ eumorphic", value: d3.geoBoggsRaw},
{name: "Bonne", value: d3.geoBonneRaw(Math.PI / 4)},
{name: "Bottomley", value: d3.geoBottomleyRaw(0.5)},
{name: "Bromley", value: d3.geoBromleyRaw},
{name: "Collignon", value: d3.geoCollignonRaw},
{name: "conic equal-area", value: d3.geoConicEqualAreaRaw(0, Math.PI / 3)},
{name: "conic equidistant", value: d3.geoConicEquidistantRaw(0, Math.PI / 3)},
{name: "Craster parabolic", value: d3.geoCrasterRaw},
{name: "cylindrical equal-area", value: d3.geoCylindricalEqualAreaRaw(38.58 / 180 * Math.PI)},
{name: "cylindrical stereographic", value: d3.geoCylindricalStereographicRaw(0)},
{name: "Eckert I", value: d3.geoEckert1Raw},
{name: "Eckert II", value: d3.geoEckert2Raw},
{name: "Eckert III", value: d3.geoEckert3Raw},
{name: "Eckert IV", value: d3.geoEckert4Raw},
{name: "Eckert V", value: d3.geoEckert5Raw},
{name: "Eckert VI", value: d3.geoEckert6Raw},
{name: "Eisenlohr conformal", value: d3.geoEisenlohrRaw},
{name: "Equal Earth", value: d3.geoEqualEarthRaw},
{name: "Equirectangular (plate carrée)", value: d3.geoEquirectangularRaw},
{name: "Fahey pseudocylindrical", value: d3.geoFaheyRaw},
{name: "flat-polar parabolic", value: d3.geoMtFlatPolarParabolicRaw},
{name: "flat-polar quartic", value: d3.geoMtFlatPolarQuarticRaw},
{name: "flat-polar sinusoidal", value: d3.geoMtFlatPolarSinusoidalRaw},
{name: "Foucaut’s stereographic equivalent", value: d3.geoFoucautRaw},
{name: "Foucaut’s sinusoidal", value: d3.geoFoucautSinusoidalRaw(0.5)},
{name: "Ginzburg V", value: d3.geoGinzburg5Raw},
{name: "Ginzburg VI", value: d3.geoGinzburg6Raw},
{name: "Ginzburg VIII", value: d3.geoGinzburg8Raw},
{name: "Ginzburg IX", value: d3.geoGinzburg9Raw},
{name: "Goode’s homolosine", value: d3.geoHomolosineRaw},
{name: "Hammer", value: d3.geoHammerRaw(2)},
{name: "Hill eucyclic", value: d3.geoHillRaw(1)},
{name: "Hufnagel pseudocylindrical", value: d3.geoHufnagelRaw(1, 0, Math.PI / 4, 2)},
{name: "Kavrayskiy VII", value: d3.geoKavrayskiy7Raw},
{name: "Lagrange conformal", value: d3.geoLagrangeRaw(0.5)},
{name: "Larrivée", value: d3.geoLarriveeRaw},
{name: "Laskowski tri-optimal", value: d3.geoLaskowskiRaw},
{name: "Loximuthal", value: d3.geoLoximuthalRaw(40 / 180 * Math.PI)},
{name: "Miller cylindrical", value: d3.geoMillerRaw},
{name: "Mollweide", value: d3.geoMollweideRaw},
{name: "Natural Earth", value: d3.geoNaturalEarth1Raw},
{name: "Natural Earth II", value: d3.geoNaturalEarth2Raw},
{name: "Nell–Hammer", value: d3.geoNellHammerRaw},
{name: "Nicolosi globular", value: d3.geoNicolosiRaw},
{name: "Patterson cylindrical", value: d3.geoPattersonRaw},
{name: "rectangular polyconic", value: d3.geoRectangularPolyconicRaw(0)},
{name: "Robinson", value: d3.geoRobinsonRaw},
{name: "sinusoidal", value: d3.geoSinusoidalRaw},
{name: "sinu-Mollweide", value: d3.geoSinuMollweideRaw},
{name: "Times", value: d3.geoTimesRaw},
{name: "Tobler hyperelliptical", value: d3.geoHyperellipticalRaw(0, 2.5, 1.183136)},
{name: "Van der Grinten", value: d3.geoVanDerGrintenRaw},
{name: "Van der Grinten II", value: d3.geoVanDerGrinten2Raw},
{name: "Van der Grinten III", value: d3.geoVanDerGrinten3Raw},
{name: "Van der Grinten IV", value: d3.geoVanDerGrinten4Raw},
{name: "Wagner IV", value: d3.geoWagner4Raw},
{name: "Wagner VI", value: d3.geoWagner6Raw},
{name: "Wagner VII", value: d3.geoWagnerRaw(65 / 180 * Math.PI, 60 / 180 * Math.PI, 0, 200)},
{name: "Wagner VIII", value: d3.geoWagnerRaw(65 / 180 * Math.PI, 60 / 180 * Math.PI, 20, 200)},
{name: "Werner", value: d3.geoBonneRaw(Math.PI / 2)},
{name: "Winkel tripel", value: d3.geoWinkel3Raw}
]

Plotly = require("https://cdn.plot.ly/plotly-latest.min.js")
function projectionInput({name = "", value} = {}) {
const form = html`<form><select name=i>${projections.map(p => {
return Object.assign(html`<option>`, {
textContent: p.name,
selected: p.name === value
});
})}</select> <i style="font-size:smaller;">${name}</i>`;
form.onchange = () => form.dispatchEvent(new CustomEvent("input")); // Safari
form.oninput = (event) => {
if (event && event.isTrusted) form.onchange = null;
form.value = projections[form.i.selectedIndex].value;
};
form.oninput();
return form;
}
Loading

0 comments on commit a24be73

Please sign in to comment.