calcuvizspec = ({
models,
introspections = [],
input_cursors,
mark,
encodings,
width,
height,
spec_post_process = (spec) => spec
}) => {
if (!models.length) return;
let encodings_for_cql = Object.entries(encodings)
.filter(([k, v]) => k != "detail_only_proj")
.map(([k, v]) => ({
type: v.type ?? "nominal",
channel: k,
field: v.name ?? v
}));
let input_domains = {};
let input_domains2 = Object.values(encodings).filter(
({ name }) => name == "formulae" || name.substr(-3) == "_in"
);
input_domains2.forEach(({ name, domain }) => {
input_domains[name] = domain;
});
let outputs = [
...Object.values(encodings)
.map((d) => d.name)
.filter(
(name) =>
name != "formula" &&
name != "value" &&
name != "input_cursor_id" &&
name.substr(-3) != "_in"
)
];
let outputs2 = Object.values(encodings)
.filter(({ name }) => name == "formula")
.map((d) => d.domain);
if (outputs2.length) outputs = [...outputs, ...outputs2[0]];
let data = calcudata({
models,
introspections,
input_domains,
input_cursors,
outputs,
pivot:
Object.values(encodings).filter((d) => d.name == "formula").length == 0
});
let schema = cql.schema.build(data);
let cql_output = cql.recommend(
{
spec: {
data,
mark,
encodings: encodings_for_cql
},
chooseBy: "effectiveness"
},
schema
);
let vlTree = cql.result.mapLeaves(cql_output.result, function (item) {
return item;
});
let c_spec = vlTree.items[0].toSpec();
c_spec.data = { name: "data" };
c_spec.datasets = { data };
if (typeof mark === "string") mark = { type: mark, tooltip: true };
else if (mark.tooltip == undefined) mark.tooltip = true;
c_spec.mark = mark;
if (width) c_spec.width = width;
if (height) c_spec.height = height;
if (encodings.x?.name == "formula")
c_spec.encoding.x.axis = { labelAngle: 0, orient: "top", labelLimit: 90 };
if (encodings.row?.name == "formula")
c_spec.encoding.row.header = { labelLimit: 70 };
Object.entries(encodings).forEach(([v, e]) => {
if (e.format) {
c_spec.encoding[v].format = e.format;
if (c_spec.encoding[v].axis == undefined)
c_spec.encoding[v].axis = { format: e.format };
}
if (e.scale) c_spec.encoding[v].scale = e.scale;
if (e.sort) c_spec.encoding[v].sort = e.sort;
if (e.zero != undefined) c_spec.encoding[v].scale = { zero: e.zero };
if (e.nice != undefined) c_spec.encoding[v].scale = { nice: e.nice };
if (e.grid != undefined) c_spec.encoding[v].axis = { grid: e.grid };
if (e.legend == false) c_spec.config = { legend: { disable: true } };
if (e.legend == null && e.legend != undefined)
c_spec.encoding[v].legend = null;
if (e.independent) c_spec.resolve = { scale: { [v]: "independent" } };
});
return spec_post_process(c_spec);
}