Public
Edited
Nov 8, 2023
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
inputs
Insert cell
{
formula_inputs.forEach((d, i) => {
y.value.insert(`selection_${d}_store`, [{unit: `concat_${i}_layer_0`, fields: [{"field":d,"channel":"x","type":"E"}] , values:[viewof inputs.value[d]]}]).run(); // this is a lot of run calls !
});
}
Insert cell
/*{y.value.insert('selection_age_0_in_store', [{unit: "concat_1_layer_0", fields: [{"field":"age_0_in","channel":"x","type":"E"}] , values:[viewof inputs.value.age_0_in]}]);
y.value.insert('selection_age_in_store', [{unit: "concat_0_layer_0", fields: [{"field":"age_in","channel":"x","type":"E"}] , values:[viewof inputs.value.age_in]}]);
y.value.insert('selection_salary_inflation_rate_in_store', [{unit: "concat_3_layer_0", fields: [{"field":"salary_inflation_rate_in","channel":"x","type":"E"}] , values:[viewof inputs.value.salary_inflation_rate_in]}])
//w.value.insert('selection_dampener_in_store', [{unit: "concat_2_concat_2_layer_0", fields: [{"field":"dampener_in","channel":"x","type":"E"}] , values:[0.95]}])
.run()}*/
Insert cell
//formula_select1 = "annual_salary"
Insert cell
ooo = {
var o = {}
formulae_info_inputs.forEach(d => {
o[d] = [inputs[d]]
})
return o
}
Insert cell
Insert cell
[10,20].indexOf(20)
Insert cell
domains['age_in'].find(d => d == 60)
Insert cell
cursorStepIndex = {
var o = {}
//o.age_in = domains['age_in'].find(d => d == cursor['age_in'][0])
o.age_in = domains['age_in'].indexOf(cursor['age_in'][0])
return o;
}

Insert cell
introspection.cul_functions
Insert cell
formulae_info
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
sensitivity_data
Insert cell
vega({ //make this useindept xscales optional.. example to do: how much sales to make to compensate for lower prices?
data: {name: 'projection'},
mark: {type: 'bar', tooltip:true},
"resolve": {"scale": {"y": "independent"}},
encoding: {
x: {field: 'step'},
y: {field: 'value', type:'quantitative'},
detail: {field: 'sens'},
//detail: {expr: 'datum[datum.sens]'},
color: { condition: { test: "datum.step == 0", value: 'brown'}},
row: {field: 'sens'},
},
width: 500,
height:50,
datasets: {projection: [...sensitivity_data]}
})
Insert cell
vega({
data: {name: 'projection'},
"resolve": {"scale": {"x": "independent"}},

repeat: {layer: formula_inputs/*, row:["value", "v2"] breaks independent x scale*/},//["age_in", "age_0_in"]},//formula_inputs,
spec: {
mark: {type: 'line', tooltip:true},
encoding: {
//x: {field: 'step'},

x: { field: { repeat: 'layer', type:'quantitative' , scale: {range:[-1,1]}}}, // will work if I move to offsets from cursor. Configurable step size and annotation step, done?? Still needs domain limits
//y: {field: {repeat:'l2'}, type:'quantitative'},//'value', type:'quantitative'},
y: {field:'value', type:'quantitative'},
detail: {field: 'sens'},
//detail: {expr: 'datum[datum.sens]'},
color: { field:'sens'},
//color: { condition: { test: "datum.step == 0", value: 'brown'}},
//row: {field: 'sens'},
}},
width: 500,
height:500,
datasets: {projection: [...sensitivity_data]}
})
Insert cell
y = { var spec_1 = Object.assign({}, JSON.parse(facet2_custom(formula_inputs,[formula_select1]))); spec_1.data = {values: [...data_part_1,...data_part_2b.flat()]}; // needed to init correctly, because of..?
spec_1.width = 200;
return vega_interactive(spec_1, { renderer: 'svg' })}
// I don't want the same event handlers here!!!
Insert cell
Insert cell
Insert cell
data_part_1 = { // all of multi domain, against cursor-only of e/t else
var cpObj = Object.assign(Object({}), cursor); delete cpObj.multi
cpObj[cursor.multi] = domains[cursor.multi];
cpObj.function$ = [model[formula_select1]] //function_inputs_cp_restricted[function_inputs_cp_restricted.length-1].function$
var cpArr = []
for (const i in cpObj)
cpArr.push({[i]:cpObj[i]})
//return cpArr
return cartesianProduct(cpArr).map(({function$, ...d}) => ({...d, function:formula_select1, value: function$(d)}))
}
Insert cell
data_part_2b = { // nonCursor c-ps (made in a loop over inputs (excluding the multi one): should be more efficient?)
var cpObj = Object.assign(Object({}), cursor); delete cpObj.multi; //delete cpObj.function$
//cpObj[cursor.multi] = cursor[cursor.multi];
//cpObj.function$ = function_inputs_cp_restricted[function_inputs_cp_restricted.length-1].function$

var out = []
for (const i in cpObj) { // must be inputs for fn only (not others)
if (formula_inputs.some(d => d==i)) {
var cpObj2 = Object.assign({}, cursor);; delete cpObj2.multi;
cpObj2.function$ = [model[formula_select1]] //function_inputs_cp_restricted[function_inputs_cp_restricted.length-1].function$

cpObj2[i] = nonCursor[i]//domains[i]
var arr2 = []
for (const j in cpObj2)
/*if (j != 'function$')*/ arr2.push({[j]:cpObj2[j]});

//return arr2
if (i != cursor.multi)
out[out.length] = cartesianProduct(arr2).map(({function$, ...d}) => ({...d, function:formula_select1, value: function$(d)}))
//out.push(cartesianProduct(arr2).map(({function$, ...d}) => ({...d, function:formula_select, value: function$(d)})));
}
}
//return cpArr
return out;
//return cartesianProduct(cpArr).map(({function$, ...d}) => ({...d, function:formula_select, value: function$(d)}))
}
Insert cell
// using cul_functions rather than cul_input_map because of lack scope id dependence in cul_input_map (this needs to improve!)
formula_inputs = Object.values(introspection.cul_functions).find(d => d.name == formula_select1).inputs
Insert cell
Insert cell
Insert cell
Insert cell
domainsWithStepOffsets = {
var o = {}
formulae_info_inputs.forEach(f => {
var c = cursor[f][0];
o[f] = domains[f].map((d,i) => ({step:i-domainsSteps[f].find(e => e.v==c).step,value:d}))
})
return o
}
Insert cell
domainsSteps = {
var o = {};
for (var i in input_domains_config) {
var d = input_domains_config[i];
o[d.input] = _.range(d.min, d.max, d.step).map((d, i) => ({v:+d.toFixed(2),step:i}))// input_domains_config[i];
};
return o
}
Insert cell
Insert cell
Insert cell
Insert cell
formulae_info_inputs
Insert cell
domains
Insert cell
sensitivity_data = {
var o = []
var c = {}
formulae_info_inputs.forEach(i => {
c[i] = cursor[i][0]
})
formulae_info_inputs.forEach(i => {
domains[i].forEach(v => {
o.push(Object.assign({...c}, {[i]:v, step:domainsWithStepOffsets[i].find(g => g.value == v).step, sens:i, annotation: [i,`${domainsWithStepOffsets[i].find(g => g.value == v).step >= 0 ? '+' : '-'}= ${Math.abs(domainsWithStepOffsets[i].find(g => g.value == v).step)* input_domains_config.find(d => d.input == i).step}`]}))
})
})
return o.map(d => ({...d, formula: formula_select1, value: model[formula_select1](d), v2: model[formula_select1](d)}))
}
Insert cell
input_domains_config
Insert cell
nonCursorSensitivities = {
var out = {}
for (const f in domains) {
if (cursor[f] != undefined && f != 'range' && formula_inputs.some(d => d == f))
out[f] = domains[f]//.filter(d => cursor[f].indexOf(d) == -1)
}
return out
}
Insert cell
data_new_sensitivities.flat().map(d => {
var step = 0
formulae_info_inputs.forEach(f => {
if (d[f] != cursor[f][0]) {
step = domainsWithStepOffsets[f].find(g => g.value == d[f]).step
return;
}
//domains[f].map((d,i) => ({step:i-domainsSteps[f].find(e => e.v==c).step,value:d}))
})
return {...d, step}
}
)
Insert cell
formulae_info
Insert cell
Insert cell
Insert cell
Insert cell
selected_formulae
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
model.rec_order
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mapped_inputs
Insert cell
viewof viz_spec.querySelector(`input[id="y_formula"]`).checked = true;
Insert cell
viewof viz_spec.querySelector(`input[id="color_formula"]`).checked = true;

Insert cell
viewof viz_spec.querySelector(`input[id="text_value"]`).checked = true;

Insert cell
Insert cell
viz_spec
Insert cell
Insert cell
inputs
Insert cell
viz_spec.cursor
Insert cell
use_cursor_from_table
Insert cell
input_domains_A_new = use_cursor_from_table.length ? input_domains_A_projection : input_domains_A
Insert cell
Insert cell
input_domains_A_projection = {
var o = {}
Object.entries(viz_spec.cursor).forEach(([k,v]) => {
o[k] = [v]
})
Object.entries(input_domains_A_overrides).forEach(([k,v]) => {
o[k] = v
})
//o.formula = Object.values(model)
return o
}
Insert cell
Insert cell
input_combos_A_projection = cartesianProduct(Object.entries(input_domains_A_projection).map(([k,v]) => ({[k]: v})))
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
model_path = /*q.get('path') ??*/ model_path1
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
//q = ({get:() => (undefined)})// OFF for publish. new URLSearchParams(location.search)
q = new URLSearchParams(location.search)
Insert cell
Insert cell
Insert cell
//repo = q.get('repo') ?? "calculang-miscellaneous-models"
repo = "calculang-miscellaneous-models"
Insert cell
Insert cell
Insert cell
Insert cell
calcuin_response = await octokit.request('GET /repos/{owner}/{repo}/contents/{model_path}-nomemo_esm/cul_scope_{cul_scope_id}.cul.js?ref={ref}', {
owner, repo, model_path, cul_scope_id, ref
})
Insert cell
calcuin_response_fv = await octokit.request('GET /repos/{owner}/{repo}/contents/{model_path}-nomemo_esm/cul_scope_{cul_scope_id}.cul.js?ref={ref}', {
owner, repo, model_path, cul_scope_id: 0, ref // won't work for scope > 9
})
Insert cell
calcuin = b64_to_utf8(calcuin_response.data.content)
Insert cell
calcuin_fv = b64_to_utf8(calcuin_response_fv.data.content)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
vega_interactive = { // credit to Mike Bostock (starting point): https://observablehq.com/@mbostock/hello-vega-embed
const v = window.vega = await require("vega");
const vl = window.vl = await require("vega-lite");
const ve = await require("vega-embed");
async function vega(spec, options) {
const div = document.createElement("div");
div.value = (await ve(div, spec, options)).view;
div.value.addEventListener('mousemove', (event, item) => {
//console.log(item);
if (item.datum != undefined && item.datum.formula != undefined) {
viewof formula_select.value = item.datum.formula;
viewof formula_select.dispatchEvent(new CustomEvent("input"))

}
})
div.value.addEventListener('click', (event, item) => {
console.log(item.datum);
/*viewof formula_select.value = item.datum.formula;
viewof formula_select.dispatchEvent(new CustomEvent("input"));
viewof month_select.value = item.datum.month_in;
viewof month_select.dispatchEvent(new CustomEvent("input"));*/
//if (item.datum.age_0_in != undefined) {viewof inputs.value = {...viewof inputs.value, age_0_in:item.datum.age_0_in}; //cursor.month_in.push(item.datum.month_in);
//viewof inputs.dispatchEvent(new CustomEvent("input"))};

// if (item.datum.age_in != undefined) {viewof inputs.value = {...viewof inputs.value, age_in:item.datum.age_in}; //cursor.month_in.push(item.datum.month_in);
//viewof inputs.dispatchEvent(new CustomEvent("input"))};

viewof inputs.value = { ...viewof inputs.value, ...item.datum };
viewof inputs.dispatchEvent(new CustomEvent("input"))

viewof formula_select.value = item.datum.formula;
viewof formula_select.dispatchEvent(new CustomEvent("input"))

//y.value.insert('selection_age_0_in_store', [{unit: "concat_1_layer_0", fields: [{"field":"age_0_in","channel":"x","type":"E"}] , values:[10]}])
//y.value.insert('selection_dampener_in_store', [{unit: "concat_2_concat_2_layer_0", fields: [{"field":"dampener_in","channel":"x","type":"E"}] , values:[0.95]}])
//.run()
// NOW TODO addSignalListener stuff... is it trigerred for above??
// until there is a selection api...
//https://github.com/vega/vega-lite/issues/2790#issuecomment-976633121
// https://github.com/vega/vega-lite/issues/1830#issuecomment-926138326
}) // DN
return div;
}
vega.changeset = v.changeset;
return vega;
}
Insert cell
Insert cell
Insert cell
Insert cell
cql = require("compassql")
Insert cell
projection
Insert cell
schema = cql.schema.build(projection)
Insert cell
encodings = Object.entries(viz_spec.encodings).filter(([k,v]) => v != '' && k != 'cursor' && k != 'independent_scales' && k != 'types' && k != 'formats').map(([k,v]) => ({channel:k,field:v,type:viz_spec.types[v],format:viz_spec.formats[v]}))
Insert cell
output = cql.recommend({
spec: {data: projection,
mark: mark == 'bar' ? 'line' : mark,
//tooltip: true,
encodings/*: [
{
channel: "x",
//aggregate: "mean",
field: x_channel,
//type: "quantitative",
},
{
channel: "y",
field: y_channel,
//type: "quantitative",
},
{
channel: "text",
field: text_channel,
type: "quantitative",
format: "s"
},
{
channel: "row",
field: row_channel,
//type: "quantitative",
//format: "s"
},
{
channel: "color",
field: color_channel
}
]*/,
},
chooseBy: "effectiveness",
}, schema);
Insert cell
vlTree = cql.result.mapLeaves(output.result, function (item) {
return item//.toSpec();
});
Insert cell
c_spec = vlTree.items[0].toSpec()
Insert cell
c_spec1 = {
var s = c_spec;
s.data = {name: 'projection'};
s.width = 600;
s.height = height;
s.datasets = {projection}
var r = {}
Object.entries(viz_spec.independent_scales).filter(([k,v]) => v == true).forEach(([k,v]) => { r[k] = 'independent' })
s.resolve = {scale: r}
if (mark == "bar") s.mark = "bar"; //{"type": "bar", "tooltip": true};
var p = s.mark;
s.mark = {type: p, tooltip:true}
if (mark == "line") s.mark.point = true
s["config"] ={"legend": {"disable": true}}
return s
}
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