|
|
|
async () => { |
|
|
|
|
|
|
|
globalThis.testFn = () => { |
|
document.getElementById('demo').innerHTML = "Hello?" |
|
}; |
|
|
|
const d3 = await import("https://cdn.jsdelivr.net/npm/d3@7/+esm"); |
|
|
|
const $ = await import("https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"); |
|
|
|
globalThis.$ = $; |
|
globalThis.d3 = d3; |
|
|
|
globalThis.d3Fn = () => { |
|
d3.select('#viz').append('svg') |
|
.append('rect') |
|
.attr('width', 50) |
|
.attr('height', 50) |
|
.attr('fill', 'black') |
|
.on('mouseover', function(){d3.select(this).attr('fill', 'red')}) |
|
.on('mouseout', function(){d3.select(this).attr('fill', 'black')}); |
|
|
|
}; |
|
|
|
globalThis.testFn_out = (val,model_radio_c) => { |
|
|
|
console.log(val, "testFn_out"); |
|
|
|
return([val,model_radio_c]); |
|
}; |
|
|
|
|
|
globalThis.testFn_out_json = (data) => { |
|
console.log(data, "testFn_out_json --"); |
|
|
|
|
|
return(['string', {}]) |
|
} |
|
|
|
globalThis.testFn_out_json_tr = (data) => { |
|
|
|
|
|
console.log(data, "testFn_out_json_tr new"); |
|
var $ = jQuery; |
|
console.log("$('#d3_embeddings')"); |
|
console.log($('#d3_embeddings')); |
|
|
|
|
|
|
|
d3.select("#d3_embeds_source").html("here"); |
|
|
|
|
|
console.log(d3.select("#select_type").node().value); |
|
d3.select("#select_type").attr("hidden", null); |
|
d3.select("#select_type").on("change", change); |
|
change(); |
|
|
|
|
|
['input', 'output'].forEach(text_type => { |
|
['tokens', 'words'].forEach(text_key => { |
|
|
|
data_i = data[0][text_type][text_key]; |
|
embeddings_network([], data_i['tnse'], data_i['similar_queries'], type=text_type +"_"+text_key, ) |
|
}); |
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return(['string', {}]) |
|
|
|
} |
|
|
|
function change() { |
|
show_type = d3.select("#select_type").node().value; |
|
|
|
d3.selectAll(".d3_embed").attr("hidden",''); |
|
d3.selectAll(".d3_graph").attr("hidden", ''); |
|
|
|
d3.select("#d3_embeds_input_" + show_type).attr("hidden", null); |
|
d3.select("#d3_embeds_output_" + show_type).attr("hidden", null); |
|
d3.select("#d3_graph_input_" + show_type).attr("hidden", null); |
|
d3.select("#d3_graph_output_" + show_type).attr("hidden", null); |
|
} |
|
|
|
|
|
|
|
function embeddings_network(tokens_text, dict_projected_embds, similar_vocab_queries, type="source", ){ |
|
|
|
|
|
console.log("Each token is a node; distance if in similar list", type ); |
|
console.log(tokens_text, dict_projected_embds, similar_vocab_queries); |
|
|
|
|
|
var nodes_tokens = {} |
|
var nodeHash = {}; |
|
var nodes = []; |
|
var edges = []; |
|
var edges_ids = []; |
|
|
|
|
|
console.log('similar_vocab_queries', similar_vocab_queries); |
|
prev_node = ''; |
|
for ([sent_token, value] of Object.entries(similar_vocab_queries)) { |
|
|
|
|
|
token_text = dict_projected_embds[sent_token][3] |
|
if (!nodeHash[sent_token]) { |
|
nodeHash[sent_token] = {id: sent_token, label: token_text, type: 'sentence', type_i: 0}; |
|
nodes.push(nodeHash[sent_token]); |
|
} |
|
sim_tokens = value['similar_topk'] |
|
dist_tokens = value['distance'] |
|
|
|
for (let index = 0; index < sim_tokens.length; index++) { |
|
const sim = sim_tokens[index]; |
|
const dist = dist_tokens[index]; |
|
|
|
token_text_sim = dict_projected_embds[sim][3] |
|
if (!nodeHash[sim]) { |
|
nodeHash[sim] = {id: sim, label: token_text_sim, type:'similar', type_i: 1}; |
|
nodes.push(nodeHash[sim]); |
|
} |
|
edges.push({source: nodeHash[sent_token], target: nodeHash[sim], weight: dist}); |
|
edges_ids.push({source: sent_token, target: sim, weight: dist}); |
|
} |
|
|
|
if (prev_node != '' ) { |
|
edges.push({source: nodeHash[prev_node], target:nodeHash[sent_token], weight: 1}); |
|
edges_ids.push({source: prev_node, target: sent_token, weight: 1}); |
|
} |
|
prev_node = sent_token; |
|
|
|
} |
|
console.log("TYPE", type, edges, nodes, edges_ids, similar_vocab_queries) |
|
|
|
|
|
d3.select('#d3_graph_'+type).html(""); |
|
d3.select('#d3_graph_'+type).append(function(){return networkPlot({nodes: nodes, links:edges}, similar_vocab_queries, dict_projected_embds,div_type=type);}); |
|
|
|
|
|
|
|
} |
|
|
|
function embeddings_graph(data, source_tokens_text_list, source_tokens, similar_vocab_queries, type="source") { |
|
|
|
|
|
|
|
|
|
|
|
console.log("embeddings_graph"); |
|
active_sentences = get_sentences(); |
|
console.log("active_sentences", active_sentences, type); |
|
|
|
active_sentences_tokens_text = active_sentences.map((x) => source_tokens_text_list[x]); |
|
active_sentences_tokens = active_sentences.map((x) => source_tokens[x]); |
|
|
|
console.log(active_sentences_tokens); |
|
|
|
data_sentences = [] |
|
dict_token_sentence_id = {} |
|
|
|
source_tokens_text_list.forEach((sentence, i) => { |
|
|
|
proj = [] |
|
sentence.forEach((tok, tok_j) => { |
|
console.log("tok,tok_j", tok, tok_j); |
|
token_text = source_tokens_text_list[i][tok_j]; |
|
proj.push([data[tok][0], data[tok][1], token_text, i, tok_j, tok]) |
|
if (token_text in dict_token_sentence_id){ |
|
dict_token_sentence_id[token_text].push(i); |
|
} |
|
else{ |
|
dict_token_sentence_id[token_text] = [i]; |
|
} |
|
}); |
|
data_sentences.push(proj); |
|
}); |
|
console.log("data_sentences error here in target", data_sentences); |
|
|
|
console.log(data); |
|
|
|
$('#d3_embeds_' + type).html(scatterPlot(data, data_sentences, dict_token_sentence_id, similar_vocab_queries, 'd3_embeds_'+type, type )); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
function scatterPlot(data, data_sentences, dict_token_sentence_id, similar_vocab_queries, div_name, div_type="source", { |
|
width = 400, // outer width, in pixels |
|
height , // outer height, in pixels |
|
r = 3, // radius of nodes |
|
padding = 1, // horizontal padding for first and last column |
|
// text = d => d[2], |
|
} = {}){ |
|
|
|
var data_dict = { ...data[div_type] }; |
|
data = Object.values(data[div_type]); |
|
|
|
var similar_vocab_queries = { ...similar_vocab_queries[div_type] }; |
|
console.log("div_type, data, data_dict, data_sentences, dict_token_sentence_id, similar_vocab_queries"); |
|
console.log(div_type, data, data_dict, data_sentences, dict_token_sentence_id, similar_vocab_queries); |
|
|
|
|
|
var margin = {top: 10, right: 10, bottom: 30, left: 50 }, |
|
width = width - margin.left - margin.right, |
|
height = 400 - margin.top - margin.bottom; |
|
|
|
|
|
var svg = d3.create("svg") |
|
|
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
|
|
svg.append("g") |
|
.attr("transform", |
|
"translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
min_value_x = d3.min(data, d => d[0]) |
|
max_value_x = d3.max(data, d => d[0]) |
|
|
|
|
|
var x = d3.scaleLinear() |
|
.domain([min_value_x, max_value_x]) |
|
.range([ margin.left , width ]); |
|
|
|
svg.append("g") |
|
|
|
.attr("transform", "translate(0," + height + ")") |
|
.call(d3.axisBottom(x)); |
|
|
|
|
|
min_value_y = d3.min(data, d => d[1]) |
|
max_value_y = d3.max(data, d => d[1]) |
|
|
|
var y = d3.scaleLinear() |
|
.domain([min_value_y, max_value_y]) |
|
.range([ height, margin.top]); |
|
|
|
svg.append("g") |
|
.attr("transform", "translate("+ margin.left +", 0)") |
|
.call(d3.axisLeft(y)); |
|
|
|
svg.selectAll() |
|
.data(data) |
|
.enter() |
|
.append('circle') |
|
.attr("class", function (d) { return "dot-" + d[2] } ) |
|
|
|
.attr("cx", function (d) { return x(d[0]); } ) |
|
.attr("cy", function (d) { return y(d[1] - margin.bottom); } ) |
|
.attr("r", 5) |
|
.style("fill", "#e85252") |
|
.style("fillOpacity",0.2) |
|
.style("stroke", "#000000ff") |
|
.style("strokeWidth", 1) |
|
.style("opacity", 0.7); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
colors = ['#6689c6',"#e0ac2b", "#e0ac2b", "#cb1dd1", "#cb1dd1", "#cb1dd1"]; |
|
|
|
|
|
var Tooltip = d3.select("#"+div_name) |
|
.append("div") |
|
.style("opacity", 0) |
|
.attr("class", "tooltip") |
|
.style("background-color", "white") |
|
.style("border", "solid") |
|
.style("border-width", "2px") |
|
.style("border-radius", "5px") |
|
.style("padding", "5px") |
|
.text("I'm a circle!"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let i_snt = 0; i_snt < data_sentences.length; i_snt++) { |
|
const sentence = data_sentences[i_snt]; |
|
|
|
console.log("sentence: ", sentence); |
|
|
|
svg.selectAll() |
|
.data(sentence) |
|
.enter() |
|
.append('text') |
|
.text(d => d[2]) |
|
.attr("class", function (d) { return "text-" + d[2] + " sent-" + i_snt } ) |
|
|
|
.attr("x", function (d) { return x(d[0]); } ) |
|
.attr("y", function (d) { return y(d[1] - margin.bottom); } ) |
|
.attr("dy", "0.35em") |
|
.attr("sentence_i", i_snt ); |
|
|
|
svg.selectAll() |
|
.data(sentence) |
|
.enter() |
|
.append('circle') |
|
.attr("class", function (d) { return "dot " + d[2] + " " + i_snt } ) |
|
|
|
.attr("cx", function (d) { return x(d[0]); } ) |
|
.attr("cy", function (d) { return y(d[1] - margin.bottom); } ) |
|
.attr("sentence_i", i_snt ) |
|
.attr("r", 6) |
|
.style("fill", colors[0]) |
|
.style("fillOpacity",0.2) |
|
.style("stroke", "#000000") |
|
.style("strokeWidth", 1) |
|
.style("opacity", 1) |
|
.on('click', change_legend ) |
|
.on('mouseover', highlight_mouseover ) |
|
.on('mouseout', highlight_mouseout ) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
function change_legend(d,i) { |
|
console.log(d,i); |
|
if (i[2] in dict_token_sentence_id){ |
|
show_sentences(dict_token_sentence_id[i[2]], i[2]); |
|
|
|
show_similar_tokens(i[5], '#d3_legend_similar_'+type); |
|
|
|
console.log(dict_token_sentence_id[i[2]]); |
|
} |
|
else{console.log("no sentence")}; |
|
} |
|
|
|
function highlight_mouseover(d,i) { |
|
console.log("highlight_mouseover", d,i); |
|
|
|
similar_ids = similar_vocab_queries[token_id]['similar_topk']; |
|
d3.select(this).transition() |
|
.duration('50') |
|
.style('opacity', '1') |
|
.attr("r", 12) |
|
|
|
similar_ids.forEach(similar_token => { |
|
d3.selectAll('.dot-' + similar_token).attr("r",12 ).style('opacity', '1') |
|
}); |
|
|
|
Tooltip |
|
.style("opacity", 1) |
|
.style("visibility", "visible") |
|
|
|
d3.select(this) |
|
.style("stroke", "red") |
|
.attr("strokeWidth", 2) |
|
.style("opacity", 0.7) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
function highlight_mouseout(d,i) { |
|
|
|
console.log("similar_vocab_queries", similar_vocab_queries); |
|
similar_ids = similar_vocab_queries[token_id]['similar_topk']; |
|
|
|
d3.select(this).transition() |
|
.duration('50') |
|
.style('opacity', '.7') |
|
.attr("r", 6) |
|
|
|
similar_ids.forEach(similar_token => { |
|
d3.selectAll('.dot-' + similar_token).attr("r",6 ).style('opacity', '.7') |
|
}); |
|
|
|
Tooltip |
|
.style("opacity", 0) |
|
d3.select(this) |
|
.style("stroke", "none") |
|
.style("opacity", 0.8) |
|
} |
|
|
|
function mousemove(d,i) { |
|
console.log("mousemove", d, i) |
|
pointer = d3.pointer(d); |
|
Tooltip |
|
.html("The exact value of<br> ") |
|
|
|
|
|
.style("top", height - pointer[1] +"px") |
|
.style("left", pointer[0]+"px") |
|
} |
|
|
|
|
|
function show_sentences(sentences_id, token) { |
|
|
|
|
|
d3.select('#d3_legend_data_'+div_type).html(""); |
|
console.log("show_sentences", data_sentences, sentences_id); |
|
sentences_id.forEach(sent_id => { |
|
console.log(data_sentences[sent_id]) |
|
|
|
|
|
d3.select('#d3_legend_data_'+div_type) |
|
.selectAll().append("p") |
|
.data(data_sentences[sent_id]) |
|
.enter() |
|
.append('text') |
|
.attr('class_data', sent_id) |
|
.attr('class_id', d => d[5]) |
|
.style("background", d=> {if (d[2]== token) return "yellow"} ) |
|
.text( d => d[2] + " "); |
|
d3.select('#d3_legend_data_'+div_type).append("p").enter(); |
|
}); |
|
|
|
|
|
} |
|
|
|
function clean_sentences() { |
|
d3.select('#d3_legend_data_'+div_type).html(""); |
|
} |
|
|
|
function show_similar_tokens(token, div_name_similar= '#d3_legend_similar_') { |
|
d3.select(div_name_similar).html(""); |
|
console.log("token", token); |
|
console.log("similar_vocab_queries[token]", similar_vocab_queries[token]); |
|
token_data = similar_vocab_queries[token]; |
|
console.log(token, token_data); |
|
var decForm = d3.format(".3f"); |
|
|
|
d3.select(div_name_similar) |
|
.selectAll().append("p") |
|
.data(token_data['similar_topk']) |
|
.enter() |
|
.append("p").append('text') |
|
|
|
.attr('class_id', d => d) |
|
.style("background", d=> {if (d == token) return "yellow"} ) |
|
|
|
.text((d,i) => do_text(d,i) ); |
|
|
|
function do_text(d,i){ |
|
console.log("do_text d,i" ); |
|
console.log(d,i); |
|
console.log("data_dict[d], data_dict"); |
|
|
|
|
|
return " " + decForm(token_data['distance'][i]) + " "; |
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return svg.node(); |
|
} |
|
|
|
|
|
|
|
function networkPlot(data, similar_vocab_queries,dict_proj, div_type="source", { |
|
width = 400, // outer width, in pixels |
|
height , // outer height, in pixels |
|
r = 3, // radius of nodes |
|
padding = 1, // horizontal padding for first and last column |
|
// text = d => d[2], |
|
} = {}){ |
|
|
|
data = data |
|
similar_vocab_queries = similar_vocab_queries |
|
console.log("data, similar_vocab_queries, div_type"); |
|
console.log(data, similar_vocab_queries, div_type); |
|
|
|
|
|
var margin = {top: 10, right: 10, bottom: 30, left: 50 }, |
|
width = width |
|
height = 400 |
|
|
|
width_box = width + margin.left + margin.right; |
|
height_box = height + margin.top + margin.bottom |
|
totalWidth = width*2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var svg = d3.create("svg") |
|
|
|
|
|
|
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var link = svg |
|
.selectAll("line") |
|
.data(data.links) |
|
.enter() |
|
.append("line") |
|
.style("fill", d => d.weight == 1 ? "#dfd5d5" : "#000000") |
|
.style("stroke", "#aaa") |
|
|
|
|
|
|
|
var text = svg |
|
.selectAll("text") |
|
.data(data.nodes) |
|
.enter() |
|
.append("text") |
|
.style("text-anchor", "middle") |
|
.attr("y", 15) |
|
.attr("class", d => 'text_token-'+ dict_proj[d.id][4] + div_type) |
|
.attr("div-type", div_type) |
|
|
|
.text(function (d) {return d.label} ) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var node = svg |
|
.selectAll("circle") |
|
.data(data.nodes) |
|
.enter() |
|
.append("circle") |
|
.attr("r", 6) |
|
|
|
.attr("class", d => 'node_token-'+ dict_proj[d.id][4] + div_type) |
|
.attr("div-type", div_type) |
|
.style("fill", d => d.type_i ? "#e85252" : "#6689c6") |
|
.on('mouseover', highlight_mouseover ) |
|
|
|
.on('mouseout',highlight_mouseout ) |
|
.on('click', change_legend ) |
|
|
|
|
|
|
|
|
|
|
|
var simulation = d3.forceSimulation(data.nodes) |
|
.force("link", d3.forceLink() |
|
.id(function(d) { return d.id; }) |
|
.links(data.links) |
|
) |
|
.force("charge", d3.forceManyBody(-400)) |
|
.force("center", d3.forceCenter(width / 2, height / 2)) |
|
|
|
.on("end", ticked); |
|
|
|
|
|
function ticked() { |
|
link |
|
.attr("x1", function(d) { return d.source.x; }) |
|
.attr("y1", function(d) { return d.source.y; }) |
|
.attr("x2", function(d) { return d.target.x; }) |
|
.attr("y2", function(d) { return d.target.y; }); |
|
|
|
node |
|
.attr("cx", function (d) { return d.x+3; }) |
|
.attr("cy", function(d) { return d.y-3; }); |
|
|
|
text |
|
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) |
|
} |
|
|
|
function highlight_mouseover(d,i) { |
|
console.log("highlight_mouseover", d,i, d3.select(this).attr("div-type")); |
|
if (i.type_i == 0 ){ |
|
token_id = i.id |
|
similar_ids = similar_vocab_queries[token_id]['similar_topk']; |
|
d3.select(this).transition() |
|
.duration('50') |
|
.style('opacity', '1') |
|
.attr("r", 12) |
|
type = d3.select(this).attr("div-type") |
|
similar_ids.forEach(similar_token => { |
|
node_id_name = dict_proj[similar_token][4] |
|
d3.selectAll('.node_token-'+ node_id_name + type).attr("r",12 ).style('opacity', '1') |
|
|
|
}); |
|
} |
|
} |
|
|
|
|
|
function highlight_mouseout(d,i) { |
|
if (i.type_i == 0 ){ |
|
token_id = i.id |
|
console.log("similar_vocab_queries", similar_vocab_queries, "this type:", d3.select(this).attr("div-type")); |
|
similar_ids = similar_vocab_queries[token_id]['similar_topk']; |
|
|
|
d3.select(this).transition() |
|
.duration('50') |
|
.style('opacity', '.7') |
|
.attr("r", 6) |
|
type = d3.select(this).attr("div-type") |
|
similar_ids.forEach(similar_token => { |
|
node_id_name = dict_proj[similar_token][4] |
|
d3.selectAll('.node_token-' + node_id_name + type).attr("r",6 ).style('opacity', '.7') |
|
d3.selectAll("circle").raise() |
|
}); |
|
} |
|
} |
|
|
|
function change_legend(d,i,j) { |
|
console.log(d,i,dict_proj); |
|
if (i['id'] in dict_proj){ |
|
|
|
|
|
show_similar_tokens(i['id'], '#similar_'+type); |
|
|
|
console.log(dict_proj[i['id']]); |
|
} |
|
else{console.log("no sentence")}; |
|
} |
|
|
|
function show_similar_tokens(token, div_name_similar='#similar_input_tokens') { |
|
d3.select(div_name_similar).html(""); |
|
console.log("token", token); |
|
console.log("similar_vocab_queries[token]", similar_vocab_queries[token]); |
|
token_data = similar_vocab_queries[token]; |
|
console.log(token, token_data); |
|
var decForm = d3.format(".3f"); |
|
|
|
d3.select(div_name_similar) |
|
.selectAll().append("p") |
|
.data(token_data['similar_topk']) |
|
.enter() |
|
.append("p").append('text') |
|
|
|
.attr('class_id', d => d) |
|
.style("background", d=> {if (d == token) return "yellow"} ) |
|
|
|
.text((d,i) => do_text(d,i) ); |
|
|
|
function do_text(d,i){ |
|
console.log("do_text d,i" ); |
|
console.log(d,i); |
|
console.log("data_dict[d], data_dict"); |
|
console.log(dict_proj[d], dict_proj); |
|
return dict_proj[d][3] + " " + decForm(token_data['distance'][i]) + " "; |
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return svg.node(); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|