Public
Edited
Dec 9, 2022
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
get_nodes("ivfflat", test_vector, { nprobe: 12, k: 8 })
Insert cell
Insert cell
Insert cell
Insert cell
// get_control_view("ivfflat", test_vector, { nprobe: 12, k: 8 })
Insert cell
// getControlView = ({indexType, q, searchParams}, style) => {
// const visitedNodes = getVisitedNodes(indexType, q, searchParams);
// const disRange = getDisRange(visitedNodes);
// const {k} = searchParams;

// const viewSvg = null;
// const topKView = null;
// const othersView = null;

// const hist = generateHist; // visitedNode rearrange
// smoothHistogram;
// his2pos => node.binX, node.binY
// draw();

// // interact();
// }
Insert cell
// getExperimentView = (controlParams, experimentParams, style) => {
// const conVisitedNodes
// const expVisitedNodes

// const controlHist
// const exp
// }
Insert cell
get_control_view = async (index_type, target, search_params) => {
const svg = d3.create("svg").attr("width", width).attr("height", height).style("border", "1px solid #ccc");
const view = svg.node();

const { k } = search_params;
const data = await get_nodes(index_type, target, search_params);
const topk_nodes = data.splice(0, k);
const other_nodes = data;

const ratio = 0.3;
const topk_view_g = svg.append("g").attr("id", "topk_view_g");
set_topk_view(topk_nodes, topk_view_g, width * ratio);

const others_view_g = svg
.append("g")
.attr("id", "others_view_g")
.attr("transform", `translate(${width * ratio}, 0)`);
set_others_view_smooth(other_nodes, others_view_g, width * (1 - ratio));

return view;
}
Insert cell
Insert cell
// viewof exp_index_type_ = Inputs.select(index_types)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
get_experiment_view = async (target, control_params, experiment_params) => {
const svg = d3
.create("svg")
.attr("width", width)
.attr("height", height)
.style("border", "1px solid #ccc");
const view = svg.node();

const control_data = await get_nodes(
control_params.index_type,
target,
control_params.search_params
);
const experiment_data = await get_nodes(
experiment_params.index_type,
target,
experiment_params.search_params
);
// const experiment_data = JSON.parse(JSON.stringify(control_data))

const { k } = control_params.search_params;
// const topk_nodes = control_data.splice(0, k);
const other_nodes = control_data;
const experiment_ids = experiment_data.map((node) => node.id);
other_nodes.forEach(
(node) => (node.type = experiment_ids.includes(node.id) ? 1 : 0)
);

const control_ids = control_data.map((node) => node.id);
const more_nodes = experiment_data;
// const new_more_nodes = more_nodes.splice(0,k);
const new_nodes = more_nodes.filter(node => !control_ids.includes(node.id));
// const new_topk_nodes = new_more_nodes.filter(node => !control_ids.includes(node.id));
// console.log(new_topk_nodes)

const ratio = 0;
const topk_view_g = svg.append("g").attr("id", "topk_view_g");
// set_topk_view(topk_nodes, topk_view_g, width * ratio);

const others_view_g = svg
.append("g")
.attr("id", "others_view_g")
.attr("transform", `translate(${width * ratio}, 0)`);
set_others_view_smooth_2(other_nodes, new_nodes, others_view_g, width * (1 - ratio));

return view;
}
Insert cell
set_others_view_smooth_2 = (nodes, new_nodes, g, width) => {
const xDomain = d3.extent([].concat(nodes, new_nodes), (node) => node.distance);
const xDomainLength = xDomain[1] - xDomain[0] + 0.01;
const xBinLength = Math.floor(width / (R * 2));
const histogram = [];
for (let i = 0; i < xBinLength; i++) histogram.push([]);
nodes.forEach((node) => {
node.binX = Math.floor(
((node.distance - xDomain[0]) / xDomainLength) * xBinLength
);
node.binY = histogram[node.binX].length;
histogram[node.binX].push(node);
});

const new_histogram = [];
for (let i = 0; i < xBinLength; i++) new_histogram.push([]);
new_nodes.forEach((node) => {
node.binX = Math.floor(
((node.distance - xDomain[0]) / xDomainLength) * xBinLength
);
node.binY = new_histogram[node.binX].length;
new_histogram[node.binX].push(node);
});
smoothHistogram(histogram);
smoothHistogram(histogram);

smoothHistogram(new_histogram);
smoothHistogram(new_histogram);

histogram.forEach((row) => row.sort((a, b) => -a.type + b.type));

const id2bin_pos = {};
histogram.forEach((row, x) => {
row.forEach(({ id }, y) => (id2bin_pos[id] = { x, y }));
});
new_histogram.forEach((row, x) => {
row.forEach(({ id }, y) => (id2bin_pos[id] = { x, y }));
});
// console.log(id2bin_pos);
const nodes_g = g
.append("g")
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", (node) => {
// console.log(node.id, id2bin_pos[node.id])
return `translate(${(2 * id2bin_pos[node.id].x + 1) * R}, ${
height / 2 - (2 * id2bin_pos[node.id].y + 1) * R
})`;
});

const new_nodes_g = g
.append("g")
.selectAll("g")
.data(new_nodes)
.join("g")
.attr("transform", (node) => {
// console.log(node.id, id2bin_pos[node.id])
return `translate(${(2 * id2bin_pos[node.id].x + 1) * R}, ${
height / 2 + (2 * id2bin_pos[node.id].y + 1) * R
})`;
});

nodes_g
.append("circle")
.attr("r", r)
.attr("fill", (node) => colors[node.type])
new_nodes_g
.append("circle")
.attr("r", r)
.attr("fill", colors[2]);
}
Insert cell
set_topk_view = (nodes, g, width) => {}
Insert cell
set_others_view_smooth = (nodes, g, width) => {
const xDomain = d3.extent(nodes, (node) => node.distance);
const xDomainLength = xDomain[1] - xDomain[0] + 0.01;
const xBinLength = Math.floor(width / (R * 2));
const binx2count = {};
const histogram = [];
for (let i = 0; i < xBinLength; i++) histogram.push([]);
nodes.forEach((node) => {
node.binX = Math.floor(
((node.distance - xDomain[0]) / xDomainLength) * xBinLength
);
node.binY = histogram[node.binX].length;
histogram[node.binX].push(node.id);
});
smoothHistogram(histogram);
// smoothHistogram(histogram);
// smoothHistogram(histogram);
const id2bin_pos = {};
histogram.forEach((row, x) => {
row.forEach((id, y) => (id2bin_pos[id] = { x, y }));
});
// console.log(id2bin_pos);
const nodes_g = g
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", (node) => {
// console.log(node.id, id2bin_pos[node.id])
return `translate(${(2 * id2bin_pos[node.id].x + 1) * R}, ${
height / 2 - (2 * id2bin_pos[node.id].y + 1) * R
})`;
});

nodes_g.append("circle").attr("r", r).attr("fill", colors[1]);
}
Insert cell
set_others_view = (nodes, g, width) => {
const xDomain = d3.extent(nodes, (node) => node.distance);
const xDomainLength = xDomain[1] - xDomain[0];
const xBinLength = Math.floor(width / (R * 2));
const binx2count = {};
nodes.forEach((node) => {
node.binX = Math.round(
((node.distance - xDomain[0]) / xDomainLength) * xBinLength
);
if (!(node.binX in binx2count)) binx2count[node.binX] = 0;
node.binY = binx2count[node.binX];
binx2count[node.binX] += 1;
});
g.append("g")
const nodes_g = g
.selectAll("g")
.data(nodes)
.join("g")
.attr("transform", node => `translate(${(2 * node.binX + 1) * R}, ${(2 * node.binY + 1) * R})`);

nodes_g.append("circle").attr("r", r).attr("fill", colors[1])
}
Insert cell
smoothHistogram = (rows) => {
if (rows.length <= 1) return;
[rows[0], rows[1]] = smoothRow_2(rows[0], rows[1]);
for (let i = 1; i < rows.length - 1; i++) {
const left = rows[i - 1];
const cur = rows[i];
const right = rows[i + 1];
if (cur.length > left.length && cur.length > right.length) {
[rows[i - 1], rows[i], rows[i + 1]] = smoothRow_3(
rows[i - 1],
rows[i],
rows[i + 1]
);
} else if (cur.length > left.length) {
[rows[i - 1], rows[i]] = smoothRow_2(rows[i - 1], rows[i]);
} else if (cur.length > right.length) {
[rows[i], rows[i + 1]] = smoothRow_2(rows[i], rows[i + 1]);
}
}

[rows[rows.length - 2], rows[rows.length - 1]] = smoothRow_2(
rows[rows.length - 2],
rows[rows.length - 1]
);
}
Insert cell
{
const rows = [
[1, 2, 3, 4, 5, 6],
[11, 12, 13, 14, 15, 16],
[21, 22, 23, 24, 25, 26],
[31, 32, 33],
];
smoothHistogram(rows);
return rows;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
r = 2.5
Insert cell
R = 3
Insert cell
padding = 20
Insert cell
colors = ['#ece7f2', '#636363', '#3182bd']
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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more