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

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