Public
Edited
Apr 30, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
barChart()
Insert cell
barChart = async () => {
const data = await getDataForChart();
return vl
.markBar({ tooltip: true, cornerRadius: 10 })
.encode(
vl.y().fieldN("backend"),
vl.x().fieldQ("time"),
vl.color().fieldN("backend"),
vl.facet().fieldN("comb").columns(6),
vl.text().count()
)
.data(data)
.height(100)
.width(100)
.render();
}
Insert cell
attribs = ["arqueroExecTime", "duckDBExecTime", "nativeJSExecTime"]
Insert cell
viewof time = Inputs.range([100, 5000], { step: 1 })
Insert cell
Insert cell
chartWithFaster = {
const height = 400;
const hover = vl.selectSingle().on("mouseover").nearest(true).empty("none");

const base = vl
.markRule({ color: "#ccc" })
.encode(vl.x().fieldN("key"), vl.detail().count());

const line = base.markLine().encode(
vl
.color()
.fieldN("faster")
.scale({
domain: ["Arquero", "duckDB", "nativeJS"],
range: ["#1f77b4", "#ff7f0e", "#2ca02c"]
}),
vl.detail().fieldN("index"),
vl.opacity().if(hover, vl.value(1)).value(0.3),
vl.y().fieldQ("norm_val").axis(null),
vl.tooltip([...attribs, "comb", "faster"])
);

const points = line
.markCircle()
.select(hover)
.encode(vl.size().if(hover, vl.value(50)).value(5));

// Generates a spec to show tick values at an specific value of y0
const tick = (y0) =>
vl
.layer(
base.markText({ style: "label" }).encode(vl.text().max("max")),
base.markTick({ style: "tick", size: 8, color: "#ccc" })
)
.encode(vl.y().value(y0));

// Create an array with *numTicks* ticks
const ticks = Array.from({ length: 3 }).map((_, i) =>
tick((height / (3 - 1)) * i)
);

return vl
.layer(base, line, points, ...ticks)
.data(data_)
.transform(
// vl.filter(attribs.map((a) => `datum["${a}"] != null`).join(" && ")),
vl.window(vl.count().as("index")),
vl.fold(attribs),
vl
.groupby("key")
.joinaggregate(vl.min("value").as("min"), vl.max("value").as("max")),
vl
.calculate("(datum.value - datum.min) / (datum.max - datum.min)")
.as("norm_val"),
vl.calculate("(datum.min + datum.max) / 2").as("mid")
)
.config({
axisX: { domain: false, labelAngle: 0, tickColor: "#ccc", title: null },
view: { stroke: null },
style: {
label: { baseline: "middle", align: "right", dx: -5 },
tick: { orient: "horizontal" }
}
})
.width(width - 100)
.height(height)
.render();
}
Insert cell
chart = {
const height = 400;
const hover = vl.selectSingle().on("mouseover").nearest(true).empty("none");

const base = vl
.markRule({ color: "#ccc" })
.encode(vl.x().fieldN("key"), vl.detail().count());

const line = base
.markLine()
.encode(
vl.color().fieldN("comb"),
vl.detail().fieldN("index"),
vl.opacity().if(hover, vl.value(1)).value(0.3),
vl.y().fieldQ("norm_val").axis(null),
vl.tooltip([...attribs, "comb"])
);

const points = line
.markCircle()
.select(hover)
.encode(vl.size().if(hover, vl.value(50)).value(5));

// Generates a spec to show tick values at an specific value of y0
const tick = (y0) =>
vl
.layer(
base.markText({ style: "label" }).encode(vl.text().max("max")),
base.markTick({ style: "tick", size: 8, color: "#ccc" })
)
.encode(vl.y().value(y0));

// Create an array with *numTicks* ticks
const ticks = Array.from({ length: 3 }).map((_, i) =>
tick((height / (3 - 1)) * i)
);

return vl
.layer(base, line, points, ...ticks)
.data(data_)
.transform(
// vl.filter(attribs.map((a) => `datum["${a}"] != null`).join(" && ")),
vl.window(vl.count().as("index")),
vl.fold(attribs),
vl
.groupby("key")
.joinaggregate(vl.min("value").as("min"), vl.max("value").as("max")),
vl
.calculate("(datum.value - datum.min) / (datum.max - datum.min)")
.as("norm_val"),
vl.calculate("(datum.min + datum.max) / 2").as("mid")
)
.config({
axisX: { domain: false, labelAngle: 0, tickColor: "#ccc", title: null },
view: { stroke: null },
style: {
label: { baseline: "middle", align: "right", dx: -5 },
tick: { orient: "horizontal" }
}
})
.width(width - 100)
.height(height)
.render();
}
Insert cell
import { vl } from "@vega/vega-lite-api"
Insert cell
data_ = {
function check(a, b, c) {
if (a <= b && a <= c) {
return "Arquero";
}
if (c <= a && c <= b) {
return "nativeJS";
}
if (b <= a && b <= c) {
return "duckDB";
}
}
let data_ = data
.map((d) => {
return {
comb: d["comb"],
arqueroExecTime: d["arquero"]["filter_time"],
duckDBExecTime: d["duckDB"]["filter_time"],
nativeJSExecTime: d["nativeJS"]["filter_time"]
};
})
.map((d) => {
return {
...d,
faster: check(
d["arqueroExecTime"],
d["duckDBExecTime"],
d["nativeJSExecTime"]
)
};
})
.filter(
(d) =>
comb.includes(d["comb"]) &&
d["arqueroExecTime"] <= time &&
d["duckDBExecTime"] <= time &&
d["nativeJSExecTime"] <= time
);
return data_;
}
Insert cell
data = await mongodbClient({
db: "benchmark",
collection: "queryExecutor",
operation: "find",
query: {}
})
Insert cell
async function getDataForChart(id = "defaultExperiment") {
let res = await mongodbClient({
db: "benchmark",
collection: "queryExecutor",
operation: "find",
query: { experimentName: id }
});

let target = [];
for (let data of res) {
let res = {};
res["comb"] = data.comb;
res["duckdb"] = data?.duckDB?.filter_time / 1000;
res["arquero"] = data?.arquero?.filter_time / 1000;
res["nativeJS"] = data?.nativeJS?.filter_time / 1000;
res["dataset"] = data.dataset;
target.push(res);
}

let data = [];
if (target.length) {
data = aq
.from(target)
.fold(["duckdb", "arquero", "nativeJS"], { as: ["backend", "time"] })
.objects();
}
return data;
return res;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import { queryPlanner } from "@kasivisu4/query-planner-v2"
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