mirror of
https://github.com/moses-smt/mosesdecoder.git
synced 2025-01-07 12:10:36 +03:00
1704 lines
55 KiB
JavaScript
1704 lines
55 KiB
JavaScript
var xmlns="http://www.w3.org/2000/svg";
|
|
var RECOMBINED = 0;
|
|
var FROM = 1;
|
|
var TO = 2;
|
|
var OUTPUT = 3;
|
|
var ALIGNMENT = 4;
|
|
var CHILDREN = 5;
|
|
var RULE_SCORE = 6;
|
|
var HEURISTIC_RULE_SCORE = 7;
|
|
var HYP_SCORE = 8;
|
|
var LHS = 9;
|
|
var DERIVATION_SCORE = 10;
|
|
var CHART_WIDTH = window.innerWidth * 0.8;
|
|
var CHART_HEIGHT = window.innerHeight;
|
|
var CELL_WIDTH = CHART_WIDTH/input.length;
|
|
var CELL_HEIGHT = CHART_HEIGHT/(input.length+1);
|
|
var CELL_MARGIN = 4;
|
|
var CELL_BORDER = 2;
|
|
var CELL_PADDING = 2;
|
|
if (input.length < 6) { CELL_MARGIN = 5; CELL_BORDER = 3; CELL_PADDING = 3; }
|
|
if (input.length > 10) { CELL_MARGIN = 1; CELL_BORDER = 1; CELL_PADDING = 2; }
|
|
if (input.length > 20) { CELL_MARGIN = 0; CELL_BORDER = 0; CELL_PADDING = 1; }
|
|
var BUTTON_WIDTH = 170;
|
|
var BUTTON_HEIGHT = 30;
|
|
var OPTION_WIDTH = 60;
|
|
var OPTION_HEIGHT = BUTTON_HEIGHT;
|
|
var CELL_HIGHLIGHT_COLOR = "#c0ffc0";
|
|
var CELL_REGULAR_COLOR = "#ffff80";
|
|
var INPUT_HIGHLIGHT_COLOR = "#c0c0c0";
|
|
var INPUT_REGULAR_COLOR = "#ffffff";
|
|
var SORT_OPTION = 2;
|
|
var ZOOM = 0;
|
|
var ZOOM_FROM = 0;
|
|
var ZOOM_TO = input.length+1;
|
|
var ZOOM_WIDTH = input.length;
|
|
|
|
var length = input.length;
|
|
var chart = document.getElementById("chart");
|
|
var reachable = new Array();
|
|
var cell_hyps = new Array(length);
|
|
var cell_derivation_score = Array();
|
|
|
|
// init basic layout
|
|
draw_chart();
|
|
draw_menu();
|
|
draw_options();
|
|
|
|
// process hypotheses
|
|
function process_hypotheses() {
|
|
index_hypotheses_by_cell();
|
|
find_reachable_hypotheses();
|
|
compute_best_derivation_scores();
|
|
}
|
|
|
|
//
|
|
// INITIALIZATION
|
|
//
|
|
|
|
function index_hypotheses_by_cell() {
|
|
// init edge_lists
|
|
for(var from=0; from<length; from++) {
|
|
cell_hyps[from] = new Array(length);
|
|
for(var to=0; to<length; to++) {
|
|
cell_hyps[from][to] = new Array();
|
|
}
|
|
}
|
|
// populate
|
|
for (var id in edge) {
|
|
var from = edge[id][FROM];
|
|
var to = edge[id][TO];
|
|
edge[id][FROM] = parseInt(from);
|
|
edge[id][TO] = parseInt(to);
|
|
edge[id][RULE_SCORE] = parseFloat(edge[id][RULE_SCORE]);
|
|
edge[id][HEURISTIC_RULE_SCORE] = parseFloat(edge[id][HEURISTIC_RULE_SCORE]);
|
|
edge[id][HYP_SCORE] = parseFloat(edge[id][HYP_SCORE]);
|
|
edge[id][DERIVATION_SCORE] = parseFloat(edge[id][DERIVATION_SCORE]);
|
|
cell_hyps[from][to].push(id);
|
|
}
|
|
}
|
|
|
|
function find_reachable_hypotheses() {
|
|
for (var i=0;i<cell_hyps[0][length-1].length;i++) {
|
|
id = cell_hyps[0][length-1][i];
|
|
find_reachable_hypotheses_recursive( id );
|
|
}
|
|
}
|
|
|
|
function find_reachable_hypotheses_recursive( id ) {
|
|
if (!(reachable[id] === undefined)) { return; }
|
|
reachable[id] = 1;
|
|
var children = get_children( id );
|
|
for(var c=0;c<children.length;c++) {
|
|
find_reachable_hypotheses_recursive( children[c] );
|
|
}
|
|
}
|
|
|
|
function compute_best_derivation_scores() {
|
|
for(var from=0; from<length; from++ ) {
|
|
cell_derivation_score[from] = Array();
|
|
}
|
|
for(var width=length-1; width>=0; width-- ) {
|
|
for(var from=0; from<length-width; from++ ) {
|
|
var to = from+width;
|
|
var cell_max_score = -9.9e9;
|
|
for (var i=0;i<cell_hyps[from][to].length;i++) {
|
|
var id = cell_hyps[from][to][i];
|
|
if (width == length-1) {
|
|
edge[id][DERIVATION_SCORE] = edge[id][HYP_SCORE];
|
|
}
|
|
if (edge[id][DERIVATION_SCORE] != null) {
|
|
var children = get_children(id);
|
|
for(var c=0;c<children.length;c++) {
|
|
if (edge[children[c]][DERIVATION_SCORE] == null ||
|
|
edge[children[c]][DERIVATION_SCORE] < edge[id][DERIVATION_SCORE]) {
|
|
edge[children[c]][DERIVATION_SCORE] = edge[id][DERIVATION_SCORE];
|
|
}
|
|
}
|
|
}
|
|
if (edge[id][DERIVATION_SCORE] != null &&
|
|
edge[id][DERIVATION_SCORE] > cell_max_score) {
|
|
cell_max_score = edge[id][DERIVATION_SCORE];
|
|
}
|
|
}
|
|
cell_derivation_score[from][to] = cell_max_score;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// MENU
|
|
//
|
|
|
|
function draw_menu() {
|
|
draw_menu_button(1,"Best Derivation");
|
|
draw_menu_button(2,"Number of Hypotheses");
|
|
draw_menu_button(3,"Number of Rule Cubes");
|
|
draw_menu_button(4,"Derivation Score");
|
|
draw_menu_button(5,"Non-Terminals")
|
|
draw_menu_button(6,"Hypotheses")
|
|
}
|
|
var MENU_POSITION_HYPOTHESES = 6; // where is "Hypotheses" in the menu?
|
|
|
|
var current_menu_selection = 0;
|
|
var menu_processing = 0;
|
|
function click_menu( id, force_flag ) {
|
|
if (!force_flag && (menu_processing || current_menu_selection == id)) {
|
|
return;
|
|
}
|
|
menu_processing = 1;
|
|
|
|
if (current_menu_selection == 1) { best_derivation(0); }
|
|
if (current_menu_selection == 2) { unannotate_cells(); }
|
|
if (current_menu_selection == 3) { unannotate_cells(); }
|
|
if (current_menu_selection == 4) { unannotate_cells(); }
|
|
if (current_menu_selection == 5) { remove_non_terminal_treemap(0); }
|
|
if (current_menu_selection == 6 && SORT_OPTION != 3) { remove_hypothesis_overview(); }
|
|
if (current_menu_selection == 6 && SORT_OPTION == 3) { remove_hypothesis_overview(); remove_non_terminal_treemap(); }
|
|
if (current_menu_selection > 0) {
|
|
highlight_menu_button( current_menu_selection, 0 );
|
|
}
|
|
|
|
if (id == 1) { best_derivation(1); }
|
|
if (id == 2) { annotate_cells_with_hypcount(); }
|
|
if (id == 3) { annotate_cells_with_rulecount(); }
|
|
if (id == 4) { annotate_cells_with_derivation_score(); }
|
|
if (id == 5) { non_terminal_treemap(); }
|
|
if (id == 6 && SORT_OPTION != 3) { hypothesis_overview(); }
|
|
if (id == 6 && SORT_OPTION == 3) { draw_hypothesis_sort_buttons(); non_terminal_treemap(1); }
|
|
highlight_menu_button( id, 1 );
|
|
current_menu_selection = id;
|
|
menu_processing = 0;
|
|
}
|
|
|
|
function draw_menu_button( id, label ) {
|
|
var button = document.createElementNS(xmlns,"rect");
|
|
button.setAttribute("id", "button-" + id);
|
|
button.setAttribute("x", 5);
|
|
button.setAttribute("y", 5 + BUTTON_HEIGHT*(id-1));
|
|
button.setAttribute("rx", 3);
|
|
button.setAttribute("ry", 3);
|
|
button.setAttribute("width", BUTTON_WIDTH-10);
|
|
button.setAttribute("height", BUTTON_HEIGHT-10);
|
|
//button.setAttribute("opacity",.75);
|
|
button.setAttribute("fill", "#c0c0ff");
|
|
button.setAttribute("stroke", "black");
|
|
button.setAttribute("stroke-width", "1");
|
|
button.setAttribute("onclick","click_menu(" + id + ",0);")
|
|
chart.appendChild( button );
|
|
|
|
var button_label = document.createElementNS(xmlns,"text");
|
|
button_label.setAttribute("x", BUTTON_WIDTH/2);
|
|
button_label.setAttribute("y", 4+BUTTON_HEIGHT/2 + BUTTON_HEIGHT*(id-1));
|
|
button_label.setAttribute("style", "font-size: 12; font-family: Verdana, Arial;");
|
|
button_label.setAttribute("text-anchor", "middle");
|
|
button_label.setAttribute("pointer-events", "none");
|
|
var content = document.createTextNode( label );
|
|
button_label.appendChild( content );
|
|
button_label.setAttribute("onclick","click_menu(" + id + ",0);")
|
|
|
|
chart.appendChild( button_label );
|
|
}
|
|
|
|
function highlight_menu_button( id, on_off ) {
|
|
var button = document.getElementById("button-" + id);
|
|
if (on_off) {
|
|
button.setAttribute("fill", "#8080ff");
|
|
}
|
|
else {
|
|
button.setAttribute("fill", "#c0c0ff");
|
|
}
|
|
}
|
|
|
|
// OPTIONS
|
|
|
|
function draw_options() {
|
|
draw_option_button(0,1,"score");
|
|
draw_option_button(0,2,"deriv.");
|
|
draw_option_button(0,3,"id");
|
|
}
|
|
|
|
function draw_rule_options() {
|
|
draw_option_button(1,1,"score");
|
|
draw_option_button(1,2,"deriv.");
|
|
draw_option_button(1,3,"zoom");
|
|
highlight_option_button(1,1,show_hyp_score);
|
|
highlight_option_button(1,2,show_derivation_score);
|
|
}
|
|
|
|
function draw_option_button( rule_option, id, label ) {
|
|
var button = document.createElementNS(xmlns,"rect");
|
|
button.setAttribute("id", (rule_option?"rule-":"") + "option-" + id);
|
|
button.setAttribute("x", rule_option ? CHART_WIDTH-BUTTON_WIDTH-OPTION_WIDTH : BUTTON_WIDTH+10);
|
|
button.setAttribute("y", 5 + OPTION_HEIGHT*(id-1));
|
|
button.setAttribute("rx", 3);
|
|
button.setAttribute("ry", 3);
|
|
button.setAttribute("width", OPTION_WIDTH-10);
|
|
button.setAttribute("height", OPTION_HEIGHT-10);
|
|
button.setAttribute("fill", "#fdd017");
|
|
button.setAttribute("stroke", "black");
|
|
button.setAttribute("stroke-width", "1");
|
|
button.setAttribute("onclick","click_"+(rule_option?"rule_":"")+"option(" + id + ");")
|
|
chart.appendChild( button );
|
|
|
|
var button_label = document.createElementNS(xmlns,"text");
|
|
var distance_from_side = BUTTON_WIDTH+5+OPTION_WIDTH/2;
|
|
button_label.setAttribute("id", (rule_option?"rule-":"") + "option-label-" + id);
|
|
button_label.setAttribute("x", rule_option ? CHART_WIDTH-distance_from_side : distance_from_side);
|
|
button_label.setAttribute("y", 4+OPTION_HEIGHT/2 + OPTION_HEIGHT*(id-1));
|
|
button_label.setAttribute("style", "font-size: 12; font-family: Verdana, Arial;");
|
|
button_label.setAttribute("text-anchor", "middle");
|
|
button_label.setAttribute("pointer-events", "none");
|
|
var content = document.createTextNode( label );
|
|
button_label.appendChild( content );
|
|
|
|
chart.appendChild( button_label );
|
|
}
|
|
|
|
function draw_sort_button( id, label ) {
|
|
var BASE_X = 5 + id/SORT_BUTTON_COUNT * (BUTTON_WIDTH-10+5);
|
|
var BASE_Y = -5 + BUTTON_HEIGHT * MENU_POSITION_HYPOTHESES;
|
|
var WIDTH = ((BUTTON_WIDTH-10+5)/SORT_BUTTON_COUNT)-5;
|
|
|
|
var button = document.createElementNS(xmlns,"rect");
|
|
|
|
button.setAttribute("id", "sort-" + id);
|
|
button.setAttribute("x", BASE_X);
|
|
button.setAttribute("y", BASE_Y);
|
|
button.setAttribute("width", WIDTH);
|
|
button.setAttribute("height", BUTTON_HEIGHT-12);
|
|
if (id==0) {
|
|
button.setAttribute("fill", "none");
|
|
}
|
|
else {
|
|
button.setAttribute("rx", 3);
|
|
button.setAttribute("ry", 3);
|
|
if (SORT_OPTION == id) {
|
|
button.setAttribute("fill", "#6080ff");
|
|
}
|
|
else {
|
|
button.setAttribute("fill", "#a0c0ff");
|
|
}
|
|
button.setAttribute("onclick","click_sort(" + id + ");")
|
|
button.setAttribute("stroke", "black");
|
|
button.setAttribute("stroke-width", "1");
|
|
}
|
|
chart.appendChild( button );
|
|
|
|
var button_label = document.createElementNS(xmlns,"text");
|
|
button_label.setAttribute("id", "sort-label-" + id);
|
|
button_label.setAttribute("x", BASE_X + WIDTH/2);
|
|
button_label.setAttribute("y", BASE_Y + 12);
|
|
button_label.setAttribute("style", "font-size: 10; font-family: Verdana, Arial;");
|
|
button_label.setAttribute("text-anchor", "middle");
|
|
button_label.setAttribute("pointer-events", "none");
|
|
var content = document.createTextNode( label );
|
|
button_label.appendChild( content );
|
|
|
|
chart.appendChild( button_label );
|
|
}
|
|
|
|
function click_sort( id ) {
|
|
if (SORT_OPTION == 3) {
|
|
remove_non_terminal_treemap(1)
|
|
}
|
|
remove_hypothesis_overview();
|
|
|
|
SORT_OPTION = id;
|
|
|
|
if (SORT_OPTION == 3) {
|
|
non_terminal_treemap(1);
|
|
draw_hypothesis_sort_buttons();
|
|
}
|
|
else {
|
|
hypothesis_overview();
|
|
}
|
|
}
|
|
|
|
var show_scores = 0;
|
|
var show_id = 0;
|
|
var show_derivation = 0;
|
|
function click_option( id ) {
|
|
if (id == 1) {
|
|
show_scores = !show_scores;
|
|
highlight_option_button( 0, 1, show_scores );
|
|
}
|
|
if (id == 2) {
|
|
show_derivation = !show_derivation;
|
|
color_cells();
|
|
highlight_option_button( 0, 2, show_derivation );
|
|
}
|
|
if (id == 3) {
|
|
show_id = !show_id;
|
|
highlight_option_button( 0, 3, show_id );
|
|
}
|
|
if (current_menu_selection > 0) {
|
|
click_menu( current_menu_selection, 1 );
|
|
}
|
|
}
|
|
|
|
var show_hyp_score = 0;
|
|
var show_derivation_score = 0;
|
|
function click_rule_option( id ) {
|
|
if (id == 1) {
|
|
show_hyp_score = !show_hyp_score;
|
|
highlight_option_button( 1, 1, show_hyp_score );
|
|
}
|
|
if (id == 2) {
|
|
show_derivation_score = !show_derivation_score;
|
|
highlight_option_button( 1, 2, show_derivation_score );
|
|
}
|
|
if (id == 3) {
|
|
if (ZOOM > 0) {
|
|
ZOOM = 0;
|
|
}
|
|
else {
|
|
ZOOM = 0.3;
|
|
}
|
|
assign_chart_coordinates();
|
|
highlight_option_button( 1, 3, ZOOM );
|
|
}
|
|
draw_rule_cube(current_z_pos_string);
|
|
}
|
|
|
|
function highlight_option_button( rule_option, id, on_off ) {
|
|
var button = document.getElementById((rule_option?"rule-":"") + "option-" + id);
|
|
if (on_off) {
|
|
button.setAttribute("fill", "#cd853f");
|
|
}
|
|
else {
|
|
button.setAttribute("fill", "#fdd017");
|
|
}
|
|
}
|
|
|
|
// INITIALIZE THE CHART
|
|
|
|
function draw_chart() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
|
|
// logical container
|
|
var container = document.createElementNS(xmlns,"svg");
|
|
container.setAttribute("id", "cell-container-" + from + "-" + to);
|
|
chart.appendChild( container );
|
|
var transform = document.createElementNS(xmlns,"g");
|
|
transform.setAttribute("id", "cell-" + from + "-" + to);
|
|
container.appendChild( transform );
|
|
|
|
// yellow box for the cell
|
|
var cell = document.createElementNS(xmlns,"rect");
|
|
cell.setAttribute("id", "cellbox-" + from + "-" + to);
|
|
cell.setAttribute("x", CELL_MARGIN);
|
|
cell.setAttribute("y", CELL_MARGIN);
|
|
cell.setAttribute("rx", CELL_BORDER);
|
|
cell.setAttribute("ry", CELL_BORDER);
|
|
cell.setAttribute("width", CELL_WIDTH-2*CELL_MARGIN);
|
|
cell.setAttribute("height", CELL_HEIGHT-2*CELL_MARGIN);
|
|
cell.setAttribute("opacity", .75);
|
|
cell.setAttribute("fill", get_cell_color(from,to));
|
|
cell.setAttribute("stroke", "black");
|
|
cell.setAttribute("stroke-width", "1");
|
|
cell.setAttribute("onmouseover","hover_cell(" + from + "," + to + ");")
|
|
cell.setAttribute("onclick","click_cell(" + from + "," + to + ");")
|
|
transform.appendChild( cell );
|
|
}
|
|
|
|
// box for the input word
|
|
var input_box = document.createElementNS(xmlns,"rect");
|
|
input_box.setAttribute("id", "inputbox-" + from);
|
|
input_box.setAttribute("x", CELL_MARGIN+from*CELL_WIDTH);
|
|
input_box.setAttribute("y", CELL_MARGIN+(length)*CELL_HEIGHT);
|
|
input_box.setAttribute("rx", 3);
|
|
input_box.setAttribute("ry", 3);
|
|
input_box.setAttribute("width", CELL_WIDTH-2*CELL_MARGIN);
|
|
input_box.setAttribute("height", CELL_HEIGHT/2);
|
|
//cell.setAttribute("opacity", .75);
|
|
input_box.setAttribute("fill", INPUT_REGULAR_COLOR);
|
|
chart.appendChild( input_box );
|
|
|
|
// input word
|
|
input_word = document.createElementNS(xmlns,"text");
|
|
input_word.setAttribute("id", "input-" + from);
|
|
input_word.setAttribute("x", (from+0.5)*CELL_WIDTH);
|
|
input_word.setAttribute("y", 10+(length+0.25)*CELL_HEIGHT);
|
|
input_word.setAttribute("style", "font-size:18;");
|
|
input_word.setAttribute("text-anchor", "middle");
|
|
var content = document.createTextNode( input[from] );
|
|
input_word.appendChild( content );
|
|
chart.appendChild( input_word );
|
|
}
|
|
assign_chart_coordinates();
|
|
}
|
|
|
|
function assign_chart_coordinates() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
|
|
var x = from*CELL_WIDTH + (width-1)*CELL_WIDTH/2;
|
|
var y = (length-width)*CELL_HEIGHT*(1-ZOOM);
|
|
//alert("(x,y) = (" + length + "," + width + "), width = " + ZOOM + ", height = " + (1-ZOOM));
|
|
var cell_width = CELL_WIDTH;
|
|
var cell_height = CELL_HEIGHT;
|
|
if (ZOOM > 0) {
|
|
// adjust (x,y)
|
|
if (width > ZOOM_WIDTH) { // above
|
|
}
|
|
else if (width == ZOOM_WIDTH) { // same level
|
|
x = from*CELL_WIDTH*(1-ZOOM) + (width-1)*CELL_WIDTH*(1-ZOOM)/2
|
|
if (from < ZOOM_FROM) { // left
|
|
y += (CHART_HEIGHT-2*CELL_HEIGHT)*ZOOM/2;
|
|
}
|
|
else if (from == ZOOM_FROM) { // the focus
|
|
}
|
|
else { // right
|
|
x += CHART_WIDTH*ZOOM;
|
|
y += (CHART_HEIGHT-2*CELL_HEIGHT)*ZOOM/2;
|
|
}
|
|
}
|
|
else { // below
|
|
y += CHART_HEIGHT*ZOOM-CELL_HEIGHT*(1-ZOOM);
|
|
}
|
|
|
|
// adjust width and height
|
|
if (width == ZOOM_WIDTH) { // same level
|
|
cell_width *= 1-ZOOM;
|
|
if (from < ZOOM_FROM) { // left
|
|
}
|
|
else if (from == ZOOM_FROM) { // the focus
|
|
cell_width += CHART_WIDTH*ZOOM;
|
|
cell_height = CHART_HEIGHT*ZOOM;
|
|
}
|
|
}
|
|
else {
|
|
cell_height *= 1-ZOOM;
|
|
}
|
|
}
|
|
|
|
var container = document.getElementById("cell-container-" + from + "-" + to);
|
|
container.setAttribute("x", x);
|
|
container.setAttribute("y", y);
|
|
var transform = document.getElementById("cell-" + from + "-" + to);
|
|
transform.setAttribute("transform", "scale(" + (cell_width/CELL_WIDTH) + "," + (cell_height/CELL_HEIGHT) + ")");
|
|
}
|
|
}
|
|
}
|
|
|
|
function remove_chart() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
var container = document.getElementById("cell-" + from + "-" + to);
|
|
chart.removeChild(container);
|
|
var cell = document.getElementById("cellbox-" + from + "-" + to);
|
|
chart.removeChild(cell);
|
|
}
|
|
var input_word = document.getElementById("input-" + from);
|
|
chart.removeChild(input_word);
|
|
var input_box = document.getElementById("inputbox-" + from);
|
|
chart.removeChild(input_box);
|
|
}
|
|
}
|
|
|
|
var current_from = -1;
|
|
var current_to;
|
|
function hover_cell( from, to ) {
|
|
if (current_from >= 0) {
|
|
highlight_input( current_from, current_to, 0)
|
|
}
|
|
highlight_input( from, to, 1)
|
|
current_from = from;
|
|
current_to = to;
|
|
}
|
|
|
|
function click_cell( from, to ) {
|
|
if (from == current_rule_from && to == current_rule_to) {
|
|
unshow_rules();
|
|
current_rule_from = -1;
|
|
ZOOM = 0;
|
|
}
|
|
else {
|
|
show_rules( from, to );
|
|
ZOOM_FROM = current_rule_from;
|
|
ZOOM_TO = current_rule_to;
|
|
ZOOM_WIDTH = to-from+1;
|
|
}
|
|
assign_chart_coordinates();
|
|
}
|
|
|
|
function highlight_input( from, to, on_off ) {
|
|
for(var i=from; i<=to; i++) {
|
|
var input_box = document.getElementById("inputbox-" + i);
|
|
input_box.setAttribute("fill", on_off ? INPUT_HIGHLIGHT_COLOR : INPUT_REGULAR_COLOR);
|
|
}
|
|
}
|
|
|
|
//
|
|
// VISUALIZATION OF CHART CELLS
|
|
//
|
|
|
|
// BASIC ANNOTATION WITH NUMBERS
|
|
|
|
function annotate_cells_with_hypcount() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
annotate_cell( from, to, cell_hyps[from][to].length, 20 )
|
|
}
|
|
}
|
|
}
|
|
|
|
function annotate_cells_with_rulecount() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
var rule_hash = Array();
|
|
var rule_count = 0;
|
|
for (var i=0;i<cell_hyps[from][to].length;i++) {
|
|
var rule = get_rule( cell_hyps[from][to][i] );
|
|
if (rule_hash[rule] === undefined) {
|
|
rule_hash[rule] = 1;
|
|
rule_count++;
|
|
}
|
|
}
|
|
annotate_cell( from, to, rule_count, 20 )
|
|
}
|
|
}
|
|
}
|
|
|
|
function annotate_cells_with_derivation_score() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
var score = cell_derivation_score[from][to];
|
|
if (score < -9e9) { score = "dead end"; }
|
|
annotate_cell( from, to, score, 15 )
|
|
}
|
|
}
|
|
}
|
|
|
|
function annotate_cell( from, to, label, font_size ) {
|
|
var cell_label_group = document.createElementNS(xmlns,"svg");
|
|
cell_label_group.setAttribute("id", "celllabel-" + from + "-" + to);
|
|
cell_label_group.setAttribute("x", 0);
|
|
cell_label_group.setAttribute("y", -3);
|
|
cell_label_group.setAttribute("pointer-events", "none");
|
|
|
|
label = "" + label; // make it a string, if not already
|
|
var line = label.split("<br>");
|
|
for(var i=0; i<line.length; i++) {
|
|
var cell_label = document.createElementNS(xmlns,"text");
|
|
cell_label.setAttribute("id", "celllabelline-" + from + "-" + to + "-" + i);
|
|
cell_label.setAttribute("x", CELL_WIDTH/2);
|
|
cell_label.setAttribute("y", CELL_HEIGHT/2 + font_size * (1 - line.length/2 + i));
|
|
cell_label.setAttribute("style", "font-size: " + font_size + ";font-family: Verdana, Arial;");
|
|
cell_label.setAttribute("pointer-events", "none");
|
|
cell_label.setAttribute("text-anchor", "middle");
|
|
var content = document.createTextNode(line[i]);
|
|
cell_label.appendChild( content );
|
|
cell_label_group.appendChild( cell_label );
|
|
}
|
|
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
cell.appendChild( cell_label_group );
|
|
}
|
|
|
|
function unannotate_cells() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
unannotate_cell( from, to );
|
|
}
|
|
}
|
|
}
|
|
|
|
function unannotate_cell( from, to ) {
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
var cell_label = document.getElementById("celllabel-" + from + "-" + to);
|
|
cell.removeChild(cell_label);
|
|
}
|
|
|
|
// NON-TERMINAL TREEMAP
|
|
|
|
function non_terminal_treemap( with_hyps ) {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
// get nt counts
|
|
var lhs = new Array();
|
|
var lhs_list = new Array();
|
|
for (var i=0;i<cell_hyps[from][to].length;i++) {
|
|
var id = cell_hyps[from][to][i];
|
|
var nt = edge[id][LHS];
|
|
if (lhs[nt] === undefined) {
|
|
lhs[nt] = 1;
|
|
lhs_list.push(nt);
|
|
}
|
|
else {
|
|
lhs[nt]++;
|
|
}
|
|
}
|
|
// sort
|
|
function sortByCount(a,b) {
|
|
return lhs[b] - lhs[a];
|
|
}
|
|
lhs_list.sort(sortByCount);
|
|
treemap_squarify( from, to, lhs_list, lhs, cell_hyps[from][to].length, with_hyps );
|
|
}
|
|
}
|
|
}
|
|
|
|
function remove_non_terminal_treemap() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
var done = false;
|
|
var j=0;
|
|
while(!done) {
|
|
var rect = document.getElementById("rect-" + from + "-" + to + "-" + j);
|
|
if (rect == null) {
|
|
done = true;
|
|
}
|
|
else {
|
|
cell.removeChild(rect);
|
|
var rect_label = document.getElementById("rect-label-" + from + "-" + to + "-" + j);
|
|
if (rect_label != null) {
|
|
cell.removeChild(rect_label);
|
|
}
|
|
}
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function treemap_cell( from, to, label, count, total, with_hyps ) {
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
var x = CELL_MARGIN;
|
|
var y = CELL_MARGIN;
|
|
var width = CELL_WIDTH - 2*CELL_MARGIN;
|
|
var height = CELL_HEIGHT - 2*CELL_MARGIN;
|
|
// TO DO
|
|
for (var i=0;i<label.length;i++) {
|
|
var rect = document.createElementNS(xmlns,"rect");
|
|
rect.setAttribute("id", "-" + id);
|
|
rect.setAttribute("x", x);
|
|
rect.setAttribute("y", y);
|
|
rect.setAttribute("width", width * count[label[i]] / total);
|
|
rect.setAttribute("height", height);
|
|
rect.setAttribute("opacity",.75);
|
|
rect.setAttribute("fill", "#c0c0ff");
|
|
rect.setAttribute("stroke", "black");
|
|
rect.setAttribute("stroke-width", "0.5");
|
|
rect.setAttribute("onclick","click_menu(" + id + ",0);")
|
|
cell.appendChild( rect );
|
|
x += width * count[label[i]] / total;
|
|
}
|
|
}
|
|
|
|
function treemap_squarify( from, to, label, count, total, with_hyps ) {
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
// conversion of counts to area
|
|
var width = CELL_WIDTH - 2*CELL_MARGIN;
|
|
var height = CELL_HEIGHT - 2*CELL_MARGIN;
|
|
var area_factor = width*height / total;
|
|
var scale_factor = Math.sqrt( area_factor );
|
|
width /= scale_factor;
|
|
height /= scale_factor;
|
|
var offset_x = 0;
|
|
var offset_y = 0;
|
|
|
|
// main algorithm
|
|
var extend = Math.min(width,height);
|
|
var current_worst = squarify_worst( label, count, 0, 0, extend );
|
|
var start = 0;
|
|
for(var i=1; i<=label.length; i++) {
|
|
// add to sequence or start new one?
|
|
var next_worst = 0;
|
|
if (i != label.length) {
|
|
next_worst = squarify_worst( label, count, start, i, extend );
|
|
}
|
|
if (i != label.length && current_worst >= next_worst) {
|
|
current_worst = next_worst; // ... and keep going
|
|
}
|
|
else {
|
|
// compute rectangles...
|
|
var sum = 0;
|
|
for(var j=start; j<i; j++) {
|
|
sum += count[label[j]];
|
|
}
|
|
var cum_x = 0;
|
|
var cum_y = 0;
|
|
var remaining_ratio = sum / ((width - offset_x) * (height - offset_y));
|
|
var this_width = (width - offset_x) * remaining_ratio;
|
|
var this_height = (height - offset_y) * remaining_ratio;
|
|
var adding_on_left = height-offset_y < width-offset_x;
|
|
for(var j=start; j<i; j++) {
|
|
if (adding_on_left) { this_height = count[label[j]] / sum * (height - offset_y); }
|
|
else { this_width = count[label[j]] / sum * (width - offset_x); }
|
|
// rectangle
|
|
var rect = document.createElementNS(xmlns,"rect");
|
|
rect.setAttribute("id", "rect-" + from + "-" + to + "-" + j);
|
|
rect.setAttribute("x", CELL_MARGIN + (offset_x + cum_x) * scale_factor);
|
|
rect.setAttribute("y", CELL_MARGIN + (offset_y + cum_y) * scale_factor);
|
|
rect.setAttribute("width", this_width * scale_factor);
|
|
rect.setAttribute("height", this_height * scale_factor);
|
|
rect.setAttribute("fill-opacity",0);
|
|
rect.setAttribute("pointer-events", "none");
|
|
rect.setAttribute("stroke", "black");
|
|
rect.setAttribute("stroke-width", "0.5");
|
|
cell.appendChild( rect );
|
|
// hypotheses
|
|
if (with_hyps) {
|
|
var hyp_list = Array();
|
|
for(var k=0; k<cell_hyps[from][to].length; k++) {
|
|
var id = cell_hyps[from][to][k];
|
|
var nt = edge[id][LHS];
|
|
if (nt == label[j]) {
|
|
hyp_list.push( id );
|
|
}
|
|
}
|
|
hypothesis_in_rect( this_width * scale_factor - 2,
|
|
this_height * scale_factor - 2,
|
|
CELL_MARGIN + (offset_x + cum_x) * scale_factor + 1,
|
|
CELL_MARGIN + (offset_y + cum_y) * scale_factor + 1,
|
|
cell, hyp_list );
|
|
}
|
|
// label
|
|
var font_size = Math.min( Math.round(this_width * scale_factor / label[j].length * 1.3),
|
|
Math.round(this_height * scale_factor ));
|
|
if (font_size > 20) { font_size = 20; }
|
|
if (font_size >= 3) {
|
|
var rect_label = document.createElementNS(xmlns,"text");
|
|
rect_label.setAttribute("id", "rect-label-" + from + "-" + to + "-" + j);
|
|
rect_label.setAttribute("x", CELL_MARGIN + (offset_x + cum_x + this_width/2) * scale_factor);
|
|
rect_label.setAttribute("y", CELL_MARGIN + (offset_y + cum_y + this_height/2) * scale_factor + font_size/2 -2);
|
|
rect_label.setAttribute("style", "font-size: " + font_size + "; font-family: Verdana, Arial; font-weight:900;");
|
|
rect_label.setAttribute("fill", "#00f");
|
|
rect_label.setAttribute("opacity", .3);
|
|
rect_label.setAttribute("text-anchor", "middle");
|
|
rect_label.setAttribute("pointer-events", "none");
|
|
var content = document.createTextNode( label[j] );
|
|
rect_label.appendChild( content );
|
|
cell.appendChild( rect_label );
|
|
}
|
|
if (adding_on_left) { cum_y += this_height; }
|
|
else { cum_x += this_width; }
|
|
}
|
|
if (adding_on_left) { offset_x += this_width; }
|
|
else { offset_y += this_height; }
|
|
|
|
// move to next sequence
|
|
if (i != label.length) {
|
|
start = i;
|
|
extend = Math.min( width-offset_x, height-offset_y );
|
|
current_worst = squarify_worst( label, count, i, i, extend );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function squarify_worst( label, count, start, end, extend ) {
|
|
var sum = 0;
|
|
for(var i=start; i<=end; i++) {
|
|
sum += count[label[i]];
|
|
}
|
|
var max_ratio = 0;
|
|
for(var i=start; i<=end; i++) {
|
|
var ratio = count[label[i]] * extend*extend /sum/sum;
|
|
if (ratio < 1) { ratio = 1/ratio; }
|
|
max_ratio = Math.max( ratio, max_ratio );
|
|
}
|
|
return max_ratio;
|
|
}
|
|
|
|
// HIGHLIGHT BEST DERIVATION
|
|
|
|
function best_derivation( on_off ) {
|
|
var best_score = -9e9;
|
|
var best_id = -1;
|
|
for (var i=0;i<cell_hyps[0][length-1].length;i++) {
|
|
id = cell_hyps[0][length-1][i];
|
|
if (edge[id][HYP_SCORE] > best_score) {
|
|
best_score = edge[id][HYP_SCORE];
|
|
best_id = id;
|
|
}
|
|
}
|
|
best_derivation_recurse( best_id, on_off, -1, -1, 0 );
|
|
}
|
|
|
|
function best_derivation_recurse( id, on_off, parent_from, parent_to, child_pos ) {
|
|
var from = edge[id][FROM];
|
|
var to = edge[id][TO];
|
|
|
|
// highlight cell and annotate with rule
|
|
highlight_cell( from, to, on_off );
|
|
if (on_off) {
|
|
var annotation = "";
|
|
if (show_id) { annotation += id + "<br>"; }
|
|
annotation += edge[id][LHS] + "\u2192";
|
|
annotation += edge[id][OUTPUT];
|
|
if (show_scores) { annotation += "<br>" + edge[id][HYP_SCORE]; }
|
|
annotate_cell( from, to, annotation, 10 );
|
|
}
|
|
else {
|
|
unannotate_cell( from, to );
|
|
}
|
|
|
|
// highlight hyp
|
|
highlight_hyp( id, on_off );
|
|
|
|
// arrow to parent
|
|
if (parent_from >= 0) {
|
|
if (on_off) {
|
|
make_arrow( id, parent_from, parent_to, from, to, 0, child_pos );
|
|
}
|
|
else {
|
|
var arrow = document.getElementById("arrow-" + id);
|
|
chart.removeChild(arrow);
|
|
}
|
|
}
|
|
|
|
var child_order = Array();
|
|
if (edge[id][ALIGNMENT] != "") {
|
|
var alignment = edge[id][ALIGNMENT].split(" ");
|
|
// sorting: array position is source nonterminal pos
|
|
alignment.sort();
|
|
// alignment target sympol pos -> source nonterminal pos
|
|
var reversed_alignment = Array();
|
|
for(var i=0; i<alignment.length; i++) {
|
|
var source_target = alignment[i].split("-");
|
|
reversed_alignment.push(source_target[1]+"-"+i);
|
|
}
|
|
// sorting by symbols pos: array position is nonterminal pos
|
|
reversed_alignment.sort();
|
|
// mapping child -> target nonterminal pos
|
|
for(var i=0; i<reversed_alignment.length; i++) {
|
|
var target_source = reversed_alignment[i].split("-");
|
|
child_order[target_source[1]] = i;
|
|
}
|
|
}
|
|
|
|
// recurse
|
|
var covered = new Array;
|
|
var children = get_children( id );
|
|
for(var c=0;c<children.length;c++) {
|
|
var child = children[c];
|
|
for( var i=edge[child][FROM]; i<=edge[child][TO]; i++ ) {
|
|
covered[i] = 1;
|
|
}
|
|
best_derivation_recurse( child, on_off, from, to, children.length == 1 ? 0.5 : child_order[c]/(children.length-1.0) );
|
|
}
|
|
|
|
// arrows to words
|
|
for( var i=from; i<=to; i++ ) {
|
|
if (covered[i] === undefined) {
|
|
if (on_off) {
|
|
make_arrow( "word-" + i, from, to, i, i, 1, 0.5 );
|
|
}
|
|
else {
|
|
var arrow = document.getElementById("arrow-word-" + i);
|
|
chart.removeChild(arrow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function make_arrow( id, parent_from, parent_to, from, to, word_flag, position ) {
|
|
var arrow = document.createElementNS(xmlns,"line");
|
|
arrow.setAttribute("id", "arrow-" + id);
|
|
|
|
var parent = get_cellbox_coordinates( parent_from, parent_to );
|
|
arrow.setAttribute("x1", parent.x+(0.5+position)/2*CELL_WIDTH*parent.scale_x);
|
|
arrow.setAttribute("y1", parent.y+(CELL_HEIGHT-CELL_MARGIN)*parent.scale_y);
|
|
|
|
if (word_flag) {
|
|
arrow.setAttribute("x2", (from+.5)*CELL_WIDTH);
|
|
arrow.setAttribute("y2", CELL_MARGIN+length*CELL_HEIGHT);
|
|
}
|
|
else {
|
|
var child = get_cellbox_coordinates( from, to );
|
|
arrow.setAttribute("x2", child.x+child.scale_x*CELL_WIDTH/2);
|
|
arrow.setAttribute("y2", child.y+child.scale_y*CELL_MARGIN+word_flag*(CELL_HEIGHT+5));
|
|
}
|
|
|
|
arrow.setAttribute("stroke", word_flag ? "#808080" : "#008000");
|
|
arrow.setAttribute("stroke-width", "3");
|
|
chart.appendChild( arrow );
|
|
}
|
|
|
|
function get_cellbox_coordinates(from, to) {
|
|
var container = document.getElementById("cell-container-" + from + "-" + to);
|
|
var transform = document.getElementById("cell-" + from + "-" + to);
|
|
var scale = transform.getAttribute("transform").split(/[\(\),]/g);
|
|
var scale_x = scale[1];
|
|
var scale_y = scale[2];
|
|
return { x: Math.round(container.getAttribute("x")),
|
|
y: Math.round(container.getAttribute("y")),
|
|
scale_x: scale[1],
|
|
scale_y: scale[2]
|
|
}
|
|
}
|
|
|
|
function highlight_cell( from, to, on_off ) {
|
|
var cell = document.getElementById("cellbox-" + from + "-" + to);
|
|
cell.setAttribute("fill", on_off ? CELL_HIGHLIGHT_COLOR : get_cell_color(from,to) );
|
|
}
|
|
|
|
function color_cells() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from+width-1;
|
|
highlight_cell(from,to,0);
|
|
}
|
|
}
|
|
}
|
|
|
|
function get_cell_color( from, to ) {
|
|
if (!show_derivation) {
|
|
return CELL_REGULAR_COLOR;
|
|
}
|
|
var score_diff = cell_derivation_score[from][to] - cell_derivation_score[0][length-1];
|
|
var dec = 128 - (score_diff*8);
|
|
if (dec>255) { dec = 255; }
|
|
var color = Math.round(dec).toString(16);
|
|
return "#ffff"+color;
|
|
}
|
|
|
|
function get_children( id ) {
|
|
if (edge[id][CHILDREN] == "") {
|
|
return [];
|
|
}
|
|
return edge[id][CHILDREN].split(" ");
|
|
}
|
|
|
|
// OVERVIEW ALL HYPOTHESES
|
|
function hypothesis_overview() {
|
|
for (var from=0;from<length;from++) {
|
|
for(var width=1; width<=length-from; width++) {
|
|
var to = from + width - 1;
|
|
hypothesis_overview_cell( from, to );
|
|
}
|
|
}
|
|
draw_hypothesis_sort_buttons();
|
|
}
|
|
|
|
function draw_hypothesis_sort_buttons() {
|
|
// draw sort buttons
|
|
draw_sort_button(0,"sort by");
|
|
draw_sort_button(1,"id");
|
|
draw_sort_button(2,"score");
|
|
draw_sort_button(3,"lhs");
|
|
}
|
|
var SORT_BUTTON_COUNT = 4; // how many in total (incl. "sort by")?
|
|
|
|
function hypothesis_overview_cell( from, to ) {
|
|
var width = CELL_WIDTH-2*(CELL_BORDER+CELL_MARGIN+CELL_PADDING);
|
|
var height = CELL_HEIGHT-2*(CELL_BORDER+CELL_MARGIN+CELL_PADDING);
|
|
var cell = document.getElementById("cell-" + from + "-" + to);
|
|
hypothesis_in_rect( width, height, CELL_BORDER+CELL_MARGIN+CELL_PADDING, CELL_BORDER+CELL_MARGIN+CELL_PADDING, cell, cell_hyps[from][to] );
|
|
}
|
|
|
|
function hypothesis_in_rect( width, height, offset_x, offset_y, parent_element, hyp_list ) {
|
|
|
|
// diameter, based on perfect fill
|
|
var diameter = Math.sqrt( width * height / hyp_list.length );
|
|
// if it does not fit the discrete objects, increase
|
|
while( Math.floor( width/diameter ) * Math.floor( height/diameter ) < hyp_list.length ) {
|
|
diameter = Math.max( width / Math.ceil( width/diameter + 0.0001 ), // fitting one more in row
|
|
height / Math.ceil( height/diameter + 0.0001 ) ); // fitting one more in column
|
|
}
|
|
var row_size = Math.floor( width / diameter );
|
|
var column_size = Math.floor( height / diameter );
|
|
|
|
// sort hypotheses
|
|
function sortByScore(a,b) {
|
|
return edge[b][HYP_SCORE] - edge[a][HYP_SCORE];
|
|
}
|
|
function sortById(a,b) {
|
|
return a-b;
|
|
}
|
|
if (SORT_OPTION == 1) {
|
|
hyp_list.sort(sortById);
|
|
}
|
|
else {
|
|
hyp_list.sort(sortByScore);
|
|
}
|
|
|
|
// draw hypothesis
|
|
var x=0
|
|
var y=0;
|
|
var column = 0;
|
|
|
|
for (var i=0; i<hyp_list.length;i++) {
|
|
id = hyp_list[i];
|
|
|
|
//alert("adding circle (" + (x + diameter/2) + "," + (y + diameter/2) + ") - " + (diameter/2) );
|
|
var hyp = document.createElementNS(xmlns,"circle");
|
|
hyp.setAttribute("id", "hyp-" + id);
|
|
hyp.setAttribute("cx", x + diameter/2 + offset_x);
|
|
hyp.setAttribute("cy", y + diameter/2 + offset_y);
|
|
hyp.setAttribute("r", diameter/2);
|
|
hyp.setAttribute("fill", hyp_color(id, 0));
|
|
hyp.setAttribute("onmouseover","hover_hyp(" + id + ");")
|
|
hyp.setAttribute("onmouseout","unhover_hyp(" + id + ");")
|
|
parent_element.appendChild( hyp );
|
|
|
|
x += diameter;
|
|
if (++column >= row_size) {
|
|
column = 0;
|
|
y += diameter;
|
|
x = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
function remove_hypothesis_overview() {
|
|
for (var id in edge) {
|
|
var cell = document.getElementById("cell-" + edge[id][FROM] + "-" + edge[id][TO]);
|
|
var hyp = document.getElementById("hyp-" + id);
|
|
cell.removeChild(hyp);
|
|
}
|
|
// remove sort buttons
|
|
for(var i=0; i<4; i++) {
|
|
var old = document.getElementById("sort-" + i);
|
|
chart.removeChild( old );
|
|
var old = document.getElementById("sort-label-" + i);
|
|
chart.removeChild( old );
|
|
}
|
|
}
|
|
|
|
function hover_hyp( id ) {
|
|
best_derivation_recurse( id, 1, -1, -1 );
|
|
}
|
|
|
|
function unhover_hyp( id ) {
|
|
best_derivation_recurse( id, 0, -1, -1 );
|
|
}
|
|
|
|
function hover_rule_hyp( id ) {
|
|
highlight_rule_hyp( id, 1 );
|
|
if (current_menu_selection == 1) {
|
|
best_derivation( 0 );
|
|
}
|
|
if (current_menu_selection <= 2) {
|
|
best_derivation_recurse( id, 1, -1, -1 );
|
|
}
|
|
}
|
|
|
|
function unhover_rule_hyp( id ) {
|
|
highlight_rule_hyp( id, 0 );
|
|
if (current_menu_selection <= 2) {
|
|
best_derivation_recurse( id, 0, -1, -1 );
|
|
}
|
|
if (current_menu_selection == 1) {
|
|
best_derivation( 1 );
|
|
}
|
|
}
|
|
|
|
function highlight_hyp( id, on_off ) {
|
|
var hyp = document.getElementById("hyp-" + id);
|
|
if (hyp == null) { return; }
|
|
hyp.setAttribute("fill", hyp_color(id, on_off));
|
|
}
|
|
|
|
function highlight_rule_hyp( id, on_off ) {
|
|
var hyp = document.getElementById("rule-hyp-" + id);
|
|
if (hyp == null) { return; }
|
|
hyp.setAttribute("fill", rule_hyp_color(id, on_off));
|
|
}
|
|
|
|
function hyp_color( id, on_off ) {
|
|
if (on_off) {
|
|
var color = "#ff0000";
|
|
if (edge[id][RECOMBINED]>0) { color = "#808080"; }
|
|
else if (id in reachable) { color = "#00c000"; }
|
|
return color;
|
|
}
|
|
var color = "#ffc0c0";
|
|
if (edge[id][RECOMBINED]>0) { color = "#c0c0c0"; }
|
|
else if (id in reachable) { color = "#80ff80"; }
|
|
return color;
|
|
}
|
|
|
|
// RULES
|
|
|
|
function get_rule( id ) {
|
|
// get non-terminal labels
|
|
if (edge[id] === undefined) { alert("unknown edge "+id); return ""; }
|
|
var output = edge[id][OUTPUT].split(" ");
|
|
var alignment = edge[id][ALIGNMENT].split(" ");
|
|
alignment.sort();
|
|
var nt_label = Array();
|
|
for(var i=0;i<alignment.length;i++) {
|
|
var source_target = alignment[i].split("-");
|
|
nt_label.push(output[source_target[1]]);
|
|
}
|
|
|
|
var rule = edge[id][LHS]+"\u2192";
|
|
var children = get_children(id);
|
|
var pos = edge[id][FROM];
|
|
for (var i=0; i<children.length; i++) {
|
|
if (pos != edge[id][FROM]) { rule += " "; }
|
|
var child = children[i];
|
|
for(;pos<edge[child][FROM];pos++) {
|
|
rule += (input[pos].length <= 10) ? input[pos] : input[pos].substr(0,8) + ".";
|
|
rule += " ";
|
|
}
|
|
rule += nt_label[i];
|
|
rule += (edge[child][FROM] == edge[child][TO]) ?
|
|
"[" + edge[child][FROM] + "]" :
|
|
"[" + edge[child][FROM] + "-" + edge[child][TO] + "]";
|
|
pos = edge[child][TO]+1;
|
|
}
|
|
for(;pos<=edge[id][TO];pos++) {
|
|
if (pos != edge[id][FROM]) { rule += " "; }
|
|
rule += (input[pos].length <= 10) ? input[pos] : input[pos].substr(0,8) + ".";
|
|
}
|
|
|
|
return rule;
|
|
}
|
|
|
|
var rule_list;
|
|
var edge2rule;
|
|
var current_rule_from = -1;
|
|
var current_rule_to;
|
|
var RULE_HEIGHT;
|
|
var RULE_FONT_SIZE;
|
|
var best_hyp_score;
|
|
var best_derivation_score;
|
|
function show_rules( from, to ) {
|
|
unshow_rules();
|
|
var cell = document.getElementById("cellbox-" + from + "-" + to);
|
|
cell.setAttribute("stroke", "#800000");
|
|
cell.setAttribute("stroke-width", "3");
|
|
current_rule_from = from;
|
|
current_rule_to = to;
|
|
|
|
best_hyp_score = -9e9;
|
|
best_derivation_score = cell_derivation_score[from][to];
|
|
|
|
var rule_hash = Array();
|
|
var rule_count = Array();
|
|
rule_list = Array();
|
|
edge2rule = Array();
|
|
for (var i=0;i<cell_hyps[from][to].length;i++) {
|
|
var id = cell_hyps[from][to][i];
|
|
var rule = get_rule( id );
|
|
if (rule_hash[rule] === undefined) {
|
|
rule_hash[rule] = rule_list.length;
|
|
rule_count[rule_list.length] = 1;
|
|
rule_list.push(rule);
|
|
}
|
|
else {
|
|
rule_count[rule_hash[rule]]++;
|
|
}
|
|
edge2rule[id] = rule_hash[rule];
|
|
|
|
if (edge[id][HYP_SCORE] > best_hyp_score) {
|
|
best_hyp_score = edge[id][HYP_SCORE];
|
|
}
|
|
}
|
|
function sortByRuleCount( a, b ) {
|
|
return rule_count[rule_hash[b]] - rule_count[rule_hash[a]];
|
|
}
|
|
rule_list = rule_list.sort(sortByRuleCount);
|
|
|
|
RULE_HEIGHT = 15;
|
|
RULE_FONT_SIZE = 11;
|
|
// squeeze if too many rules
|
|
if (rule_list.length * RULE_HEIGHT > (CHART_HEIGHT-50)) {
|
|
var factor = (CHART_HEIGHT-50)/rule_list.length/RULE_HEIGHT;
|
|
RULE_HEIGHT = Math.floor( RULE_HEIGHT * factor );
|
|
RULE_FONT_SIZE = Math.ceil( RULE_FONT_SIZE * factor );
|
|
}
|
|
|
|
draw_rule_options();
|
|
for(var i=-1; i<rule_list.length; i++) {
|
|
draw_rule(from, to, i);
|
|
}
|
|
if (rule_list.length > 0) {
|
|
click_rule( from, to, 0 );
|
|
}
|
|
}
|
|
|
|
function unshow_rules() {
|
|
if (current_rule_from >= 0) {
|
|
var cell = document.getElementById("cellbox-" + current_rule_from + "-" + current_rule_to);
|
|
cell.setAttribute("stroke", "black");
|
|
cell.setAttribute("stroke-width", "1");
|
|
}
|
|
var finished = 0;
|
|
for(var i=-1; !finished; i++) {
|
|
var old = document.getElementById("rule-" + i);
|
|
if (old != null) { chart.removeChild( old ); }
|
|
else { finished = 1; }
|
|
}
|
|
var old = document.getElementById("rule-message");
|
|
if (old != null) { chart.removeChild( old ); }
|
|
old = document.getElementById("rule-cube");
|
|
if (old != null) { chart.removeChild( old ); }
|
|
finished = 0;
|
|
for(var i=1; !finished; i++) {
|
|
var old = document.getElementById("rule-option-" + i);
|
|
if (old != null) {
|
|
chart.removeChild( old );
|
|
var old = document.getElementById("rule-option-label-" + i);
|
|
chart.removeChild( old );
|
|
}
|
|
else { finished = 1; }
|
|
}
|
|
}
|
|
|
|
function draw_rule( from, to, rule_id ) {
|
|
var rule_label = document.createElementNS(xmlns,"text");
|
|
rule_label.setAttribute("id", "rule-" + rule_id);
|
|
rule_label.setAttribute("x", CHART_WIDTH-120);
|
|
rule_label.setAttribute("y", 10 + RULE_HEIGHT*(rule_id+1));
|
|
rule_label.setAttribute("text-anchor", "middle");
|
|
if (rule_id>-1) {
|
|
rule_label.setAttribute("style", "font-size: "+RULE_FONT_SIZE+"; font-family: Verdana, Arial;");
|
|
rule_label.setAttribute("onclick","click_rule(" + from + "," + to + "," + rule_id + ");");
|
|
var content = document.createTextNode( rule_list[rule_id] );
|
|
rule_label.appendChild( content );
|
|
}
|
|
else {
|
|
rule_label.setAttribute("style", "font-size: "+(RULE_FONT_SIZE-2)+"; font-family: Verdana, Arial; font-weight: bold;");
|
|
var content = document.createTextNode( rule_list.length == 0 ? "NO RULES" : "RULES" );
|
|
rule_label.appendChild( content );
|
|
}
|
|
chart.appendChild( rule_label );
|
|
}
|
|
|
|
function draw_rule_message( message ) {
|
|
var old = document.getElementById("rule-message");
|
|
if (old != null) { chart.removeChild( old ); }
|
|
|
|
var rule_message_group = document.createElementNS(xmlns,"svg");
|
|
rule_message_group.setAttribute("id","rule-message");
|
|
rule_message_group.setAttribute("x", 0);
|
|
rule_message_group.setAttribute("y", 250);
|
|
var line = message.split("<br>");
|
|
for(var i=0;i<line.length;i++) {
|
|
var line_label = document.createElementNS(xmlns,"text");
|
|
line_label.setAttribute("id", "rule-message-line" + id);
|
|
line_label.setAttribute("x", 0);
|
|
line_label.setAttribute("y", RULE_HEIGHT*(i+1));
|
|
line_label.setAttribute("style", "font-size: 9; font-family: Verdana, Arial;");
|
|
var content = document.createTextNode( line[i] );
|
|
line_label.appendChild( content );
|
|
rule_message_group.appendChild( line_label );
|
|
}
|
|
chart.appendChild( rule_message_group );
|
|
}
|
|
|
|
var output_list;
|
|
var children_list;
|
|
var current_edge;
|
|
var current_rule_id = -1;
|
|
var axis;
|
|
var dimension_order;
|
|
var RULE_CUBE_HYP_SIZE;
|
|
var RULE_CUBE_FONT_SIZE;
|
|
function click_rule( from, to, rule_id ) {
|
|
// highlight current rule
|
|
if (current_rule_id>=0) {
|
|
var rule_label = document.getElementById("rule-"+current_rule_id);
|
|
rule_label.setAttribute("style", "font-size: "+RULE_FONT_SIZE+"; font-family: Verdana, Arial;");
|
|
}
|
|
var rule_label = document.getElementById("rule-"+rule_id);
|
|
rule_label.setAttribute("style", "font-size: "+RULE_FONT_SIZE+"; font-family: Verdana, Arial; font-weight: bold;");
|
|
current_rule_id = rule_id;
|
|
|
|
// first get all the data
|
|
output_list = Array();
|
|
var output_hash = Array();
|
|
children_list = Array();
|
|
var children_hash = Array();
|
|
current_edge = Array();
|
|
for (var i=0;i<cell_hyps[from][to].length;i++) {
|
|
var id = cell_hyps[from][to][i];
|
|
var rule = get_rule( id );
|
|
if (rule == rule_list[rule_id]) {
|
|
current_edge.push( id );
|
|
// create index for output (target rhs)
|
|
var output = edge[id][OUTPUT]+"|"+edge[id][HEURISTIC_RULE_SCORE];
|
|
if (output_hash[output] === undefined) {
|
|
output_hash[output] = output_list.length;
|
|
output_list.push(output);
|
|
}
|
|
// create index for children
|
|
var children = get_children( id );
|
|
for(var j=0;j<children.length;j++) {
|
|
// init children indices if needed
|
|
if (j > children_list.length-1) {
|
|
children_hash.push([]);
|
|
children_list.push([]);
|
|
}
|
|
// build index
|
|
var child = ""+children[j];
|
|
if (children_hash[j][child] === undefined) {
|
|
children_hash[j][child] = children_list[j].length;
|
|
children_list[j].push(parseInt(child));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// sort
|
|
function sortBySecond(a,b) {
|
|
asplit = a.split("|");
|
|
bsplit = b.split("|");
|
|
return bsplit[1] - asplit[1];
|
|
}
|
|
output_list = output_list.sort(sortBySecond);
|
|
|
|
function sortHypByScore(a,b) {
|
|
return edge[b][HYP_SCORE] - edge[a][HYP_SCORE];
|
|
}
|
|
for(var i=0;i<children.length;i++) {
|
|
children_list[i].sort(sortHypByScore);
|
|
}
|
|
|
|
// select dimensions of rule cube
|
|
axis = Array();
|
|
axis.push(output_list);
|
|
for(var i=0;i<children_list.length;i++) {
|
|
axis.push(children_list[i]);
|
|
}
|
|
|
|
// determine order
|
|
var dimension_size = Array();
|
|
for(var i=0;i<axis.length;i++) {
|
|
dimension_size.push(i+"|"+(axis[i].length - i/10));
|
|
}
|
|
dimension_size.sort(sortBySecond);
|
|
dimension_order = Array();
|
|
for(var i=0;i<dimension_size.length;i++) {
|
|
id_size = dimension_size[i].split("|");
|
|
dimension_order.push(id_size[0]);
|
|
}
|
|
|
|
var z_pos = Array();
|
|
for(i=2;i<axis.length;i++) { z_pos.push(0); }
|
|
var z_pos_string = z_pos.join(",");
|
|
draw_rule_cube(z_pos.join(","));
|
|
}
|
|
|
|
var current_z_pos_string = "";
|
|
function draw_rule_cube(z_pos_string) {
|
|
current_z_pos_string = z_pos_string;
|
|
var z_pos = Array();
|
|
if (z_pos_string != "") {
|
|
z_pos = z_pos_string.split(",");
|
|
}
|
|
|
|
// draw rube cube
|
|
var old = document.getElementById("rule-cube");
|
|
if (old != null) { chart.removeChild( old ); }
|
|
|
|
// dimensions of the 2x2 view
|
|
var max_length = axis[dimension_order[0]].length;
|
|
//if (axis.length>1 && axis[dimension_order[1]].length > max_length) {
|
|
// max_length = axis[dimension_order[1]].length;
|
|
//}
|
|
|
|
// space for additional dimensions
|
|
var z_dimension_length = 0;
|
|
if (dimension_order.length > 2) {
|
|
z_dimension_length = -2;
|
|
for(var i=2; i<dimension_order.length; i++ ) {
|
|
z_dimension_length += axis[dimension_order[i]].length + 2;
|
|
max_length += axis[dimension_order[i]].length + 2;
|
|
}
|
|
}
|
|
//if (dimension_order.length > 2) {
|
|
// for(var i=2; i<dimension_order.length; i++ ) {
|
|
// if (axis[dimension_order[i]].length > max_z_dimension_length) {
|
|
// max_z_dimension_length = axis[dimension_order[i]].length;
|
|
// }
|
|
// }
|
|
//}
|
|
//if (max_z_dimension_length > 10) {
|
|
// max_z_dimension_length = 10;
|
|
//}
|
|
//var y_length = axis[dimension_order[0]].length;
|
|
//if (max_z_dimension_length > 0) {
|
|
// y_length += max_z_dimension_length + 2;
|
|
// if (y_length > max_length) {
|
|
// max_length = y_length;
|
|
// }
|
|
//}
|
|
|
|
// calculate table cell and font size
|
|
if (max_length+8 <= CHART_HEIGHT/15) {
|
|
RULE_CUBE_HYP_SIZE = 15;
|
|
RULE_CUBE_FONT_SIZE = 11;
|
|
}
|
|
else if (max_length+8 > CHART_HEIGHT/9) {
|
|
RULE_CUBE_HYP_SIZE = 9;
|
|
RULE_CUBE_FONT_SIZE = 7;
|
|
}
|
|
else {
|
|
RULE_CUBE_HYP_SIZE = CHART_HEIGHT/(max_length+8);
|
|
RULE_CUBE_FONT_SIZE = (RULE_CUBE_HYP_SIZE * 12/15).toFixed(0);
|
|
}
|
|
var Z_HEIGHT = 0;
|
|
if (dimension_order.length > 2) {
|
|
Z_HEIGHT = (z_dimension_length + 2) * RULE_CUBE_HYP_SIZE;
|
|
}
|
|
|
|
var rule_cube = document.createElementNS(xmlns,"svg");
|
|
rule_cube.setAttribute("id","rule-cube");
|
|
rule_cube.setAttribute("x", CHART_WIDTH - 30);
|
|
rule_cube.setAttribute("y", 0);
|
|
chart.appendChild( rule_cube );
|
|
|
|
// draw y axis
|
|
var label = get_rule_axis_name(dimension_order[0]);
|
|
draw_rule_row(-1,label);
|
|
for(var y=0; y<axis[dimension_order[0]].length; y++) {
|
|
var label = get_rule_axis_label(dimension_order[0], y);
|
|
draw_rule_row(y,label);
|
|
}
|
|
if (axis[dimension_order[0]].length > (CHART_HEIGHT-Z_HEIGHT)/9-10) {
|
|
draw_rule_row(Math.ceil(CHART_HEIGHT/9-10),"(more, "+axis[dimension_order[0]].length+" total)");
|
|
}
|
|
|
|
// draw x axis
|
|
if (axis.length > 1) {
|
|
var label = get_rule_axis_name(dimension_order[1]);
|
|
draw_rule_column(-1,label);
|
|
for(var x=0; x<axis[dimension_order[1]].length && x<CHART_HEIGHT/9-10; x++) {
|
|
var label = get_rule_axis_label(dimension_order[1], x);
|
|
draw_rule_column(x,label);
|
|
}
|
|
if (axis[dimension_order[1]].length > CHART_HEIGHT/9-10) {
|
|
draw_rule_column(Math.ceil(CHART_HEIGHT/9-10),"(more, "+axis[dimension_order[1]].length+" total)");
|
|
}
|
|
}
|
|
|
|
// draw hyps
|
|
for(var y=0; y<axis[dimension_order[0]].length && y<(CHART_HEIGHT-Z_HEIGHT)/9-10; y++) {
|
|
if (axis.length == 1) {
|
|
var hyp = find_hyp_by_rule([y],dimension_order);
|
|
draw_rule_hyp(0,y,hyp);
|
|
}
|
|
else {
|
|
for(var x=0; x<axis[dimension_order[1]].length && x<CHART_HEIGHT/9-10; x++) {
|
|
var hyp = find_hyp_by_rule([y,x].concat(z_pos),dimension_order);
|
|
draw_rule_hyp(x,y,hyp);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// draw z-axes
|
|
var pos_offset = axis[dimension_order[0]].length+2;
|
|
for(var z=2;z<dimension_order.length;z++) {
|
|
var label = get_rule_axis_name(dimension_order[z]);
|
|
draw_rule_z(z-2,dimension_order.length-2, z_pos, -1, pos_offset, label);
|
|
for(var i=0;i<axis[dimension_order[z]].length && i<z_dimension_length; i++) {
|
|
var label = get_rule_axis_label(dimension_order[z], i);
|
|
draw_rule_z(z-2,dimension_order.length-2, z_pos, i, pos_offset, label);
|
|
}
|
|
pos_offset += axis[dimension_order[z]].length+2;
|
|
}
|
|
|
|
// report summary statistics
|
|
var message = output_list.length + " output phrases";
|
|
message += "<br>DEBUG: " + axis.length;
|
|
message += "<br>" + dimension_order.length;
|
|
for(var i=0;i<children_list.length;i++) {
|
|
message += "<br>" + children_list[i].length + " hyps for NT" + (i+1);
|
|
}
|
|
//draw_rule_message(message);
|
|
}
|
|
|
|
function find_hyp_by_rule(position, dimension_order) {
|
|
for(var e=0;e<current_edge.length;e++) {
|
|
var id = current_edge[e];
|
|
var children = get_children( id );
|
|
var match = 1;
|
|
for(var p=0; p<position.length; p++) {
|
|
if (dimension_order[p] == 0) {
|
|
if (output_list[position[p]] != edge[id][OUTPUT]+"|"+edge[id][HEURISTIC_RULE_SCORE]) {
|
|
match = 0;
|
|
}
|
|
}
|
|
else {
|
|
var nt_number = dimension_order[p]-1;
|
|
if (children_list[nt_number][position[p]] != children[nt_number]) {
|
|
match = 0;
|
|
}
|
|
}
|
|
}
|
|
if (match) { return id; }
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
function get_rule_axis_label( dimension, i ) {
|
|
if (dimension == 0) {
|
|
var output_score = output_list[i].split("|");
|
|
var score = 1 * output_score[1];
|
|
return output_score[0]+" "+score.toFixed(1);
|
|
}
|
|
var id = children_list[dimension-1][i];
|
|
return get_display_output( id ) + " " + edge[id][HYP_SCORE].toFixed(1);
|
|
}
|
|
|
|
function get_rule_axis_name( dimension ) {
|
|
if (dimension == 0) {
|
|
return "TARGET";
|
|
}
|
|
return "NT" + dimension;
|
|
}
|
|
|
|
|
|
function get_display_output( id ) {
|
|
var output_string = get_full_output( id );
|
|
var output = output_string.split(" ");
|
|
if (output.length <= 2) {
|
|
return output_string;
|
|
}
|
|
else {
|
|
return output[0] + "\u203B" + output[output.length-1];
|
|
}
|
|
}
|
|
|
|
function get_full_output( id ) {
|
|
var output = edge[id][OUTPUT].split(" ");
|
|
|
|
var alignment = edge[id][ALIGNMENT].split(" ");
|
|
var children = get_children( id );
|
|
alignment.sort();
|
|
var nonterminal = Array();
|
|
for(var i=0; i<alignment.length; i++) {
|
|
var source_target = alignment[i].split("-");
|
|
nonterminal[source_target[1]] = children[i];
|
|
}
|
|
|
|
var full_output = "";
|
|
for(var i=0;i<output.length;i++) {
|
|
if (nonterminal[i] === undefined) {
|
|
full_output += " " + output[i];
|
|
}
|
|
else {
|
|
full_output += " " + get_full_output( nonterminal[i] );
|
|
}
|
|
}
|
|
return full_output.substr(1);
|
|
}
|
|
|
|
function draw_rule_row( pos, label ) {
|
|
var rule_label = document.createElementNS(xmlns,"text");
|
|
rule_label.setAttribute("id", "rule-row-" + pos);
|
|
rule_label.setAttribute("y", RULE_CUBE_FONT_SIZE*10 + RULE_CUBE_HYP_SIZE*pos);
|
|
if (pos>=0) {
|
|
rule_label.setAttribute("style", "font-size: "+RULE_CUBE_FONT_SIZE+"; font-family: Verdana, Arial;");
|
|
rule_label.setAttribute("x", RULE_CUBE_FONT_SIZE*10+5);
|
|
}
|
|
else {
|
|
rule_label.setAttribute("style", "font-size: "+(RULE_CUBE_FONT_SIZE-2)+"; font-family: Verdana, Arial; font-weight: bold;");
|
|
rule_label.setAttribute("x", RULE_CUBE_FONT_SIZE*10-30);
|
|
}
|
|
rule_label.setAttribute("text-anchor", "end");
|
|
var content = document.createTextNode( label );
|
|
rule_label.appendChild( content );
|
|
var rule_cube = document.getElementById("rule-cube");
|
|
rule_cube.appendChild( rule_label );
|
|
}
|
|
|
|
function draw_rule_column( pos, label ) {
|
|
var rule_label = document.createElementNS(xmlns,"text");
|
|
rule_label.setAttribute("id", "rule-column-" + pos);
|
|
rule_label.setAttribute("x", RULE_CUBE_FONT_SIZE*10 -3 + RULE_CUBE_HYP_SIZE*(1+pos) );
|
|
rule_label.setAttribute("y", RULE_CUBE_FONT_SIZE*10 -12);
|
|
rule_label.setAttribute("transform", "rotate(60 "+ (RULE_CUBE_FONT_SIZE*10-3+RULE_CUBE_HYP_SIZE*(1+pos)) +" "+(RULE_CUBE_FONT_SIZE*10 - 12)+")")
|
|
if (pos>=0) {
|
|
rule_label.setAttribute("style", "font-size: "+RULE_CUBE_FONT_SIZE+"; font-family: Verdana, Arial;");
|
|
}
|
|
else {
|
|
rule_label.setAttribute("style", "font-size: "+(RULE_CUBE_FONT_SIZE-2)+"; font-family: Verdana, Arial; font-weight: bold;");
|
|
}
|
|
rule_label.setAttribute("text-anchor", "end");
|
|
var content = document.createTextNode( label );
|
|
rule_label.appendChild( content );
|
|
var rule_cube = document.getElementById("rule-cube");
|
|
rule_cube.appendChild( rule_label );
|
|
}
|
|
|
|
function draw_rule_z( z,total_z, z_pos, pos,pos_offset, label ) {
|
|
var rule_label = document.createElementNS(xmlns,"text");
|
|
rule_label.setAttribute("id", "rule-z-" + z + "-" + pos);
|
|
//rule_label.setAttribute("x", RULE_CUBE_FONT_SIZE*10+10 + CHART_HEIGHT*z/(total_z+1) );
|
|
rule_label.setAttribute("x", RULE_CUBE_FONT_SIZE*10+10 );
|
|
rule_label.setAttribute("y", RULE_CUBE_FONT_SIZE*10 + RULE_CUBE_HYP_SIZE*(pos+pos_offset));
|
|
if (pos >= 0) {
|
|
rule_label.setAttribute("style", "font-size: "+RULE_CUBE_FONT_SIZE+"; font-family: Verdana, Arial;"
|
|
+((z_pos[z] == pos)?" font-weight: bold;":""));
|
|
z_pos_copy = z_pos.join(",").split(",");
|
|
z_pos_copy[z] = pos;
|
|
rule_label.setAttribute("onclick","draw_rule_cube(\"" + z_pos_copy.join(",") + "\");");
|
|
}
|
|
else {
|
|
rule_label.setAttribute("style", "font-size: "+(RULE_CUBE_FONT_SIZE-2)+"; font-family: Verdana, Arial; font-weight: bold;");
|
|
}
|
|
|
|
var content = document.createTextNode( label );
|
|
rule_label.appendChild( content );
|
|
var rule_cube = document.getElementById("rule-cube");
|
|
rule_cube.appendChild( rule_label );
|
|
}
|
|
|
|
function draw_rule_hyp( xpos, ypos, id ) {
|
|
if (id == -1) { return; }
|
|
var diameter = RULE_CUBE_HYP_SIZE-2;
|
|
var hyp = document.createElementNS(xmlns,"circle");
|
|
hyp.setAttribute("id", "rule-hyp-" + id);
|
|
hyp.setAttribute("cx", RULE_CUBE_FONT_SIZE*10+10 + RULE_CUBE_HYP_SIZE*xpos + diameter/2);
|
|
hyp.setAttribute("cy", RULE_CUBE_FONT_SIZE*10-2 + RULE_CUBE_HYP_SIZE*(ypos-0.5) + diameter/2);
|
|
hyp.setAttribute("r", diameter/2);
|
|
hyp.setAttribute("fill", rule_hyp_color(id, 0));
|
|
//hyp.setAttribute("opacity",.5);
|
|
hyp.setAttribute("onmouseover","hover_rule_hyp(" + id + ");")
|
|
hyp.setAttribute("onmouseout","unhover_rule_hyp(" + id + ");")
|
|
var rule_cube = document.getElementById("rule-cube");
|
|
rule_cube.appendChild( hyp );
|
|
}
|
|
|
|
function rule_hyp_color( id, on_off ) {
|
|
if (!show_hyp_score && !show_derivation_score) {
|
|
return hyp_color( id, on_off );
|
|
}
|
|
var inactive_color = on_off ? "80" : "00";
|
|
var hyp_score_color = inactive_color;
|
|
var derivation_score_color = inactive_color;
|
|
if (show_hyp_score) {
|
|
hyp_score_color = get_score_from_color(best_hyp_score-edge[id][HYP_SCORE]);
|
|
}
|
|
if (show_derivation_score) {
|
|
if (edge[id][DERIVATION_SCORE] == null) {
|
|
derivation_score_color = "00";
|
|
}
|
|
else {
|
|
derivation_score_color = get_score_from_color(best_derivation_score-edge[id][DERIVATION_SCORE]);
|
|
}
|
|
}
|
|
return "#" + inactive_color + derivation_score_color + hyp_score_color;
|
|
}
|
|
|
|
function get_score_from_color( score, on_off ) {
|
|
if (score == null) { return "00"; }
|
|
var dec = 255 - 255 * (score/8);
|
|
if (dec < 0) { dec = 0; }
|
|
if (on_off) { dec = dec/2+128; }
|
|
dec = Math.floor(dec/16)*16+15;
|
|
var color = dec.toString(16);
|
|
if (dec < 16) { color = "0"+color; }
|
|
return color;
|
|
}
|