async () => { // set testFn() function on globalThis, so you html onlclick can access it globalThis.testFn = () => { document.getElementById('demo').innerHTML = "Hello?" }; const d3 = await import("https://cdn.jsdelivr.net/npm/d3@7/+esm"); // const d3 = await import("https://cdn.jsdelivr.net/npm/d3@5/+esm"); const $ = await import("https://cdn.jsdelivr.net/npm/jquery@3.7.1/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) => { // document.getElementById('demo').innerHTML = val console.log(val, "testFn_out"); // globalThis.d3Fn(); return([val,model_radio_c]); }; globalThis.testFn_out_json = (data) => { console.log(data, "testFn_out_json --"); // var $ = jQuery; // console.log( d3.select('#d3_embeddings')); return(['string', {}]) } globalThis.testFn_out_json_tr = (data) => { // data['input|output']['words|tokens'] console.log(data, "testFn_out_json_tr new"); var $ = jQuery; console.log("$('#d3_embeddings')"); console.log($('#d3_embeddings')); // d3.select('#d3_embeddings').html(""); d3.select("#d3_embeds_source").html("here"); // words or token visualization ? console.log(d3.select("#select_type").node().value); d3.select("#select_type").attr("hidden", null); d3.select("#select_type").on("change", change); change(); // tokens // network plots; ['input', 'output'].forEach(text_type => { ['tokens', 'words'].forEach(text_key => { // console.log(type, key, data[0][text_type]); data_i = data[0][text_type][text_key]; embeddings_network([], data_i['tnse'], data_i['similar_queries'], type=text_type +"_"+text_key, ) }); }); // data_proj = data['tsne']; // it is not a dict. // d3.select("#d3_embeds_" + type).html(scatterPlot(data_proj, data_sentences, dict_token_sentence_id, similar_vocab_queries, 'd3_embeds_'+type, type )); // d3.select('#d3_embeddings').append(function(){return Tree(root);}); // embeddings_network(data['source_tokens'], data['dict_projected_embds_all']['source'], data['similar_vocab_queries']['source'], "source") // source // embeddings_graph(data['dict_projected_embds_all'],source_tks_list, data['source_tokens'], data['similar_vocab_queries'], "source"); //, data['similar_text'], data['similar_embds']); // target decision: all tokens ? or separeted by language ? hint: do not assume they share the same dict. // embeddings_graph(data['dict_projected_embds_all'], translated_tks_text, translated_tks_ids_by_sent, data['similar_vocab_queries'], "target"); //, data['similar_text'], data['similar_embds']); return(['string', {}]) } function change() { show_type = d3.select("#select_type").node().value; // hide all d3.selectAll(".d3_embed").attr("hidden",''); d3.selectAll(".d3_graph").attr("hidden", ''); // show current type; 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", ){ // tokens_text : not used; // dict_projected_embds = tnse console.log("Each token is a node; distance if in similar list", type ); console.log(tokens_text, dict_projected_embds, similar_vocab_queries); // similar_vocab_queries_target[key]['similar_topk'] var nodes_tokens = {} var nodeHash = {}; var nodes = []; // [{id: , label: }] var edges = []; // [{source: , target: weight: }] var edges_ids = []; // [{source: , target: weight: }] // similar_vocab_queries {key: {similar_topk : [], distance : []}} console.log('similar_vocab_queries', similar_vocab_queries); prev_node = ''; for ([sent_token, value] of Object.entries(similar_vocab_queries)) { // console.log('dict_projected_embds',sent_token, parseInt(sent_token), value, dict_projected_embds); // sent_token = parseInt(sent_token); // Object.entries assumes key:string; 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_input_tokens').html(networkPlot({nodes: nodes, links:edges}, similar_vocab_queries, div_type=type) ); // type +"_"+key 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);}); // $('#d3_embeds_network_target').html(networkPlot({nodes: nodes, links:edges})); // $('#d3_embeds_network_'+type).html(etworkPlot({nodes: nodes, link:edges})); } function embeddings_graph(data, source_tokens_text_list, source_tokens, similar_vocab_queries, type="source") { /* ### source data: dict_projected_embds_all = { token_id: [tns1, tns2, token_id, token_text] ...} ### target */ console.log("embeddings_graph"); active_sentences = get_sentences(); console.log("active_sentences", active_sentences, type); // working 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 = {} // active_sentences_tokens.forEach((sentence, i) => { source_tokens_text_list.forEach((sentence, i) => { /// opt1 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 )); } /* data: dict_projected_embds_all = { token_id: [tns1, tns2, token_id, token_text] ...} */ 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], } = {}){ // data_dict = data[div_type]; var data_dict = { ...data[div_type] }; data = Object.values(data[div_type]); // similar_vocab_queries = similar_vocab_queries[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); // Create the SVG container. var margin = {top: 10, right: 10, bottom: 30, left: 50 }, width = width - margin.left - margin.right, height = 400 - margin.top - margin.bottom; // append the svg object to the body of the page var svg = d3.create("svg") // .attr("style", "max-width: 100%; height: auto; height: intrinsic;") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // const svg = d3.create("svg") // .attr("width", width) // .attr("height", height); // Add X axis 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("+ margin.left +"," + height + ")") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)); // Add Y axis 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] + margin.left); } ) .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); // svg.selectAll() // .data(data) // .enter() // .append('text') // .text(d => d[3]) // .attr("class", function (d) { return "text-" + d[2] } ) // // .attr("cx", function (d) { return x(d[0] + margin.left); } ) // .attr("x", function (d) { return x(d[0]); } ) // .attr("y", function (d) { return y(d[1] - margin.bottom); } ) // .attr("dy", "0.35em"); // colors = ['#cb1dd1',"#e0ac2b", "#e85252", "#6689c6", "#9a6fb0", "#a53253"]; colors = ['#6689c6',"#e0ac2b", "#e0ac2b", "#cb1dd1", "#cb1dd1", "#cb1dd1"]; // create a tooltip 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!"); // const colorScale = d3.scaleOrdinal() // .domain(domain_values) // .range(["#e0ac2b", "#e85252", "#6689c6", "#9a6fb0", "#a53253"]); // colorScale(d.group) for (let i_snt = 0; i_snt < data_sentences.length; i_snt++) { const sentence = data_sentences[i_snt]; // similar_tokens; 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("cx", function (d) { return x(d[0] + margin.left); } ) .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] + margin.left); } ) .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 ) // .on("mousemove", mousemove); } 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); // token_id = parseInt(i[5]) 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')//.raise() }); Tooltip .style("opacity", 1) .style("visibility", "visible") // .style("top", (event.pageY-height)+"px").style("left",(event.pageX-width)+"px") d3.select(this) .style("stroke", "red") .attr("strokeWidth", 2) .style("opacity", 0.7) // .html("The exact value of
this cell is: ") // .style("left", (d3.mouse(this)[0]+70) + "px") // .style("top", (d3.mouse(this)[1]) + "px") } function highlight_mouseout(d,i) { // token_id = parseInt(i[5]) console.log("similar_vocab_queries", similar_vocab_queries); similar_ids = similar_vocab_queries[token_id]['similar_topk']; // clean_sentences(); 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
") // .style("top", ((e.pageY ) - (height*2)) +"px") // .attr("transform", `translate(${pointer[0]},0)`) .style("top", height - pointer[1] +"px") .style("left", pointer[0]+"px") } function show_sentences(sentences_id, token) { // Show sentences with token "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]) // console.log(data_sentences[sent_id].map( x => x[2] )); // p = d3.select('#d3_legend_data').append("p").enter(); 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(); }); // $("#d3_legend_data") // data_sentences } 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_data', sent_id) .attr('class_id', d => d) .style("background", d=> {if (d == token) return "yellow"} ) // .text( d => d + " \n "); .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(data_dict[d], data_dict); // return data_dict[d][3] + " " + decForm(token_data['distance'][i]) + " "; return " " + decForm(token_data['distance'][i]) + " "; } } // data_sentences // .attr('x', (d) => x_scale(d[0]) + margin.left) // .attr('y', (d) => y_scale(d[1]) + margin_top_extra) // .attr("rx", 4) // .attr("ry", 4) // .attr("stroke", "#F7F7F7") // .attr("stroke-width","2px") // .attr('width', x_scale.bandwidth()) // .attr('height', (d) => height_text); // // .attr('fill', (d) => color_scale(d.value)); // Add dots // svg.append('g') // // .selectAll("dot") // .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]); } ) // .attr("r", 5) // .style("fill", function (d) { return color(d.Species) } ) // .on("mouseover", highlight) // .on("mouseleave", doNotHighlight ) 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_dict = data; data = data// [div_type]; similar_vocab_queries = similar_vocab_queries// [div_type]; console.log("data, similar_vocab_queries, div_type"); console.log(data, similar_vocab_queries, div_type); // Create the SVG container. var margin = {top: 10, right: 10, bottom: 30, left: 50 }, width = width //- margin.left - margin.right, height = 400 //- margin.top - margin.bottom; width_box = width + margin.left + margin.right; height_box = height + margin.top + margin.bottom totalWidth = width*2; // append the svg object to the body of the page // const parent = d3.create("div"); // const body = parent.append("div") // .style("overflow-x", "scroll") // .style("-webkit-overflow-scrolling", "touch"); var svg = d3.create("svg") // var svg = body.create("svg") // .style("display", "block") // .attr("style", "max-width: 100%; height: auto; height: intrinsic;") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) // .attr("viewBox", [-width_box / 2, -height_box / 2, width_box, height_box]) // .attr("viewBox", [0, 0, width, height]); // .attr("style", "max-width: 100%; height: auto;"); // svg.append("g") // .attr("transform", // "translate(" + margin.left + "," + margin.top + ")"); // Initialize the links var link = svg .selectAll("line") .data(data.links) .enter() .append("line") .style("fill", d => d.weight == 1 ? "#dfd5d5" : "#000000") // , "#69b3a2" : "#69b3a2") .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) // .attr("class", d => 'text_token-'+ d.index) .text(function (d) {return d.label} ) // .on('mouseover', function(d) { (d.type_i == 0) ? highlight_mouseover_text : console.log(0)} ) // .on('mouseover', function(d) { (d.type_i == 0) ? highlight_mouseout_text : '' } ) // .on('mouseout', highlight_mouseout_text ) // .join('text') // .text(function(d) { // return d.id // }) // Initialize the nodes var node = svg .selectAll("circle") .data(data.nodes) .enter() .append("circle") .attr("r", 6) // .attr("class", d => 'node_token-'+ d.id) .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") // , "#69b3a2" : "#69b3a2") .on('mouseover', highlight_mouseover ) // .on('mouseover', function(d) { return (d.type_i == 0) ? highlight_mouseover : console.log(0)} ) .on('mouseout',highlight_mouseout ) .on('click', change_legend ) // .on('click', show_similar_tokens ) // Let's list the force we wanna apply on the network var simulation = d3.forceSimulation(data.nodes) // Force algorithm is applied to data.nodes .force("link", d3.forceLink() // This force provides links between nodes .id(function(d) { return d.id; }) // This provide the id of a node .links(data.links) // and this the list of links ) .force("charge", d3.forceManyBody(-400)) // This adds repulsion between nodes. Play with the -400 for the repulsion strength .force("center", d3.forceCenter(width / 2, height / 2)) // This force attracts nodes to the center of the svg area // .force("collision", d3.forceCollide()) .on("end", ticked); // This function is run at each iteration of the force algorithm, updating the nodes position. 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')//.raise() // d3.selectAll('.text_token-'+ node_id_name).raise() }); } } 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']; // clean_sentences(); 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_sentences(dict_proj[i[2]], i[2]); 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_data', sent_id) .attr('class_id', d => d) .style("background", d=> {if (d == token) return "yellow"} ) // .text( d => d + " \n "); .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]) + " "; } } // svg.call(d3.zoom() // .extent([[0, 0], [width, height]]) // .scaleExtent([1, 8]) // .on("zoom", zoomed)); // function zoomed({transform}) { // circle.attr("transform", d => `translate(${transform.apply(d)})`); // } // svg.call( // d3.zoom().on("zoom", (event) => { // g.attr("transform", event.transform); // }) // ); // body.node().scrollBy(totalWidth, 0); return svg.node(); // return parent.node(); }; }