Public
Edited
Mar 21, 2023
2 forks
1 star
Insert cell
Insert cell
import {
notebook,
notebook_styles
} from "@dralletje/functions-are-notebooks-with-custom-runtime"
Insert cell
ObservableHq = require("@observablehq/runtime@4")
Insert cell
notebook_styles
Insert cell
array = [
{ firstName: 'Michiel', lastName: 'Dral', age: 23 },
{ firstName: 'Jelmar', lastName: 'Gerritsen', age: 22 },
{ firstName: 'Sarah', lastName: null, age: 22 }
]
Insert cell
Insert cell
mutable selected_cell = null
Insert cell
mutable codes = ({
can_drink: `age > 18`,
name: `[firstName, lastName].filter(Boolean).join(' ')`,
thing: `{ let test = 2; return test }`
})
Insert cell
Insert cell
x = ({ hey: 10 })
Insert cell
Insert cell
Notebook = ({ item, codes, column, onCodesChange, ...props }) => {
let ref = React.useRef();
let value = React.useRef(new Mutable(item));

React.useEffect(() => {
let code_with_derived = `
${Object.keys(item)
.map(key => `${key} = row.${key};`)
.join('\n\n')}

${Object.entries(codes)
.map(([key, code]) => `${key} = ${code}`)
.join('\n\n')}
`;

value.current.value = item;
let hmmm = notebook_direct(code_with_derived)({
// replacements: {
row: value.current.generator
// },
// onCodeChange: changed_cell => {
// let new_codes = { ...codes };
// delete new_codes[changed_cell.old_name];
// new_codes[changed_cell.new_name] = changed_cell.code.replace(
// /^[^=]+=/,
// ''
// );

// console.log('new_codes:', new_codes);
// onCodesChange(new_codes);
// }
});
if (ref.current.firstChild) {
ref.current.firstChild.remove();
}
ref.current.appendChild(hmmm);
}, [codes]);

React.useEffect(() => {
value.current.value = item;
console.log('value.current.value:', value.current.value);
}, [item, codes]);

return htm`<div ref=${ref} ...${props} />`;
}
Insert cell
Row = ({ data, index, selected, onSelectedChange, codes, onCodeChange }) => {
let string = `
${Object.entries(codes)
.map(([key, code]) => `${key} = ${code};`)
.join('\n\n')}
`;
let result = notebook(string)({ ...data }, false);

return htm`<tr>
${keys.map(
column => htm`
<${Cell}
column=${column}
row=${index}
value=${data[column]}
selected_cell=${selected}
onClick=${() => {
onSelectedChange({ column, row: index });
}}
/>
`
)}

${Object.entries(codes).map(
([column, code]) => htm`
<${Cell}
column=${column}
row=${index}
selected_cell=${selected}
value=${result[column]}
onClick=${() => {
onSelectedChange({ column, row: index });
}}
/>
`
)}
</tr>`;
}
Insert cell
Table = ({ selected_cell, onSelectedChange, codes, onCodesChange }) => {
return htm`
<table class="list-table" style=${{ width: width / 2 }}>
<tr>
${keys.map(key => htm`<td style=${{ fontWeight: 'bold' }}>${key}</td>`)}
${Object.keys(codes).map(
key => htm`<td style=${{ fontWeight: 'bold' }}>${key}</td>`
)}
</tr>
${array.map(
(data, index) =>
htm`<${Row}
onSelectedChange=${onSelectedChange}
data=${data}
index=${index}
selected=${selected_cell} codes=${codes}
onCodesChange=${onCodesChange}
/>`
)}
</table>
${selected_cell &&
codes[selected_cell.column] &&
htm`
<${Notebook}
style=${{ width: width / 2 }}
item=${array[selected_cell.row]}
codes=${codes}
column=${selected_cell.column}
onCodesChange=${onCodesChange}
/>
`}
`;
}
Insert cell
Insert cell
Cell = ({ column, row, selected_cell, value, ...props }) => {
let column_selected = selected_cell && selected_cell.column === column;
let row_selected = selected_cell && selected_cell.row === row;
let border = 'solid gray 1px';

return htm`
<td
style=${{
// border: 'solid 1px transparent',
// borderTop: row_selected ? border : 'none',
// borderBottom: row_selected ? border : 'none',
// borderLeft: column_selected ? border : 'none',
// borderRight: column_selected ? border : 'none',
border: border,
backgroundColor:
row_selected || column_selected ? 'rgba(0,0,0,.05)' : 'transparent'
}}
...${props}
>
<${Inspector} value=${value} />
</td>
`;
}
Insert cell
notebook_direct = code => {
let string_parts = [code];
string_parts.raw = [code];
return notebook({})(string_parts);
}
Insert cell
Inspector = ({ value }) => {
let container_ref = React.useRef();
let inspector = React.useRef();

React.useEffect(() => {
if (inspector.current == null) {
inspector.current = new ObservableHq.Inspector(container_ref.current);
}
inspector.current.fulfilled(value);
}, [value]);
return htm`<div ref=${container_ref} />`;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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