").text("Other frames:"))
.append($("
")
.addClass("btn-group flex-wrap")
.attr({ "role": "group" }).append(otherFrameButtons)
)
)
)
)
);
}
function processDocument(eventId, docId) {
$framesOut.empty();
$.get("analyze", { "event": eventId, "document": docId, "model": activeLomeModel }).done(function (data) {
data.forEach((element, index) => processSentence(element, index));
});
}
function processSamples(frame, construction, dependency, role) {
$framesOut.empty();
$framesOut.append($("").text("Loading..."));
$.get("sample_frame", {
"model": activeLomeModel,
"frame": frame,
"construction": construction,
"dependency": dependency,
"role": role,
"event_filters": activeEventFilters.join("+"),
"doc_filters": activeDocumentFilters.join("+")
}).done((data) => {
$framesOut.empty();
if (data.length === 0) {
$framesOut.append($("").text("No samples were found"))
} else {
data.forEach((element, index) => processSentence(element, index));
}
});
}
/* === COMPUTE & DISPLAY STATISTICS ===*/
// count and display frame frequency graphs
function showFrameFrequencies($button, frameFilter, constrFilter, groupByTgt, groupByCat, groupByConstr, groupByRoot, groupByRoleExpr) {
const oldText = $button.text();
$button.text("Loading...");
const useRelativeFreqs = $("#stats-relative").prop("checked");
const plotOverDaysPost = groupByRoleExpr ? false : $("#plot-over-days-post").prop("checked");
const plotByYear = groupByRoleExpr ? false : $("#plot-by-year").prop("checked");
const countOnlyHeadlines = $("#count-only-headlines").prop("checked");
if (frameFilter === "FROM_FORM") {
const frameToAnalyze = $("#frame-freq-select").val();
console.log(frameToAnalyze);
frameFilter = [frameToAnalyze];
}
if (constrFilter === "FROM_FORM") {
const formValue = $("#construction-freq-select").val();
constrFilter = formValue === "*" ? [] : [formValue];
} else if (constrFilter === "*") {
constrFilter = [];
}
const params = {
"model": activeLomeModel,
"frames": frameFilter.join("+"),
"constructions": constrFilter.join("+"),
"event_filters": activeEventFilters.join("+"),
"doc_filters": activeDocumentFilters.join("+"),
"group_by_cat": groupByCat ? "y" : "n",
"group_by_tgt": groupByTgt ? "y" : "n",
"group_by_constr": groupByConstr ? "y" : "n",
"group_by_root": groupByRoot ? "y" : "n",
"group_by_role_expr": groupByRoleExpr,
"relative": useRelativeFreqs ? "y" : "n",
"plot_over_days_post": plotOverDaysPost ? "y" : "n",
"headlines": countOnlyHeadlines ? "y" : "n",
"plot_by_year": plotByYear ? "y" : "n",
"days_time_window": $("#time-window").val()
};
$.get("frame_freq", params).done((data) => {
console.log(data);
$button.text(oldText);
const plotlyLayout = {
autosize: true,
// width: 800,
// height: 450,
showlegend: true,
legend: {"orientation": "v", "x": 1.0, "y": 0},
font: {"size": 20}
};
let relevantFramesPlotData = [];
let allFramesPlotData = [];
let deepFramesPlotData = [];
// let frameCountParts = ["relevant_frame_counts", "all_frame_counts", "deep_frame_counts"];
let frameCountParts = ["relevant_frame_counts"];
if (plotOverDaysPost || plotByYear) {
plotlyLayout["xaxis"] = {
"automargin": true,
"title": {
"text": plotOverDaysPost ? "days post event" : "years"
}
}
plotlyLayout["yaxis"] = {
"title": {
"text": "frame frequency"
}
}
frameCountParts.forEach((series) => {
Object.entries(data[series]).forEach((entry) => {
const [key, value] = entry;
let targetArray;
if (series === "relevant_frame_counts") {
targetArray = relevantFramesPlotData;
} else if (series === "all_frame_counts") {
targetArray = allFramesPlotData;
} else {
targetArray = deepFramesPlotData;
}
targetArray.push({
"x": value["x"],
"y": value["y"],
"stackgroup": "one",
"name": key,
});
})
})
} else {
const relevant = data["relevant_frame_counts"];
let numLabelParts = 2;
if (groupByRoleExpr === 1) {
numLabelParts = 1;
plotlyLayout["showlegend"] = false;
} else if (groupByRoleExpr > 1) {
numLabelParts = 3
}
plotlyLayout["barmode"] = "stack";
plotlyLayout["xaxis"] = {
"automargin": true,
"tickangle": 30,
"categoryorder": "total descending",
"title": {
"text": groupByRoleExpr > 0 ? "role" : "frame"
}
}
plotlyLayout["yaxis"] = {
// "range": [0, 1]
"title": {
"text": "frequency"
}
}
// filter by role sub-label
const roleSubLabels = new Set(relevant["x"].map((x) => x.split("::")[numLabelParts-1]));
const roleDepLabelArr = Array.from(roleSubLabels);
roleDepLabelArr.sort().reverse();
relevantFramesPlotData = roleDepLabelArr.map((label) => {
const xs = [];
const ys = [];
relevant["x"].forEach((x, idx) => {
if (numLabelParts > 1 && x.split("::")[numLabelParts-1] === label) {
xs.push(x.split("::").splice(0, numLabelParts-1).join("::"));
ys.push(relevant["y"][idx]);
} else if (numLabelParts == 1) {
xs.push(x.split("::")[1]);
ys.push(relevant["y"][idx]);
}
})
return {
x: xs,
y: ys,
name: label,
type: "bar"
}
});
// } else {
// relevantFramesPlotData = [{
// x: relevant["x"],
// y: relevant["y"],
// type: "bar"
// }];
// }
// const all = data["all_frame_counts"];
// allFramesPlotData = [{
// x: all["x"],
// y: all["y"],
// type: "bar"
// }];
// const deep = data["deep_frame_counts"];
// deepFramesPlotData = [{
// x: deep["x"],
// y: deep["y"],
// type: "bar"
// }];
// }
}
let plotlyRelevantFrames = "frame-freq-relevant-plotly";
// let plotlyDeepFrames = "deep-frame-freq-plotly";
// let plotlyAllFrames = "frame-freq-all-plotly";
Plotly.newPlot(plotlyRelevantFrames, relevantFramesPlotData, plotlyLayout);
// Plotly.newPlot(plotlyDeepFrames, deepFramesPlotData);
// Plotly.newPlot(plotlyAllFrames, allFramesPlotData);
$("#frame-freq-modal").modal().on("shown.bs.modal", () => {
Plotly.relayout(plotlyRelevantFrames, { autosize: true })
// Plotly.relayout(plotlyDeepFrames, { autosize: true })
// Plotly.relayout(plotlyAllFrames, { autosize: true })
});
});
}
// show statistics table for specific frame
function showStatsTable(frame) {
if (frame === "FROM_FORM") {
frame = $("#frame-freq-select").val();
}
if (frame === "*") {
frame = "";
}
const $tableModal = $("#table-modal");
function roundToDecimals(num, decimals) {
const multiplier = Math.pow(10, decimals)
// from https://stackoverflow.com/questions/11832914/how-to-round-to-at-most-2-decimal-places-if-necessary
return Math.round((num + Number.EPSILON) * multiplier) / multiplier;
}
// build a string representing all currently active filters
const allFilters = activeEventFilters.concat(activeDocumentFilters);
allFilters.sort();
const filterString = (
frame + "__"
+ (allFilters.length > 0 ? allFilters.join("+") : "no filters")
+ "__" + activeLomeModel
);
// make sure the entry is not already in the table
if (tableFilters.has(filterString)) {
$tableModal.modal();
return;
}
const $tableModalButton = $("#constr-table-btn");
const oldText = $tableModalButton.text();
$tableModalButton.text("Loading...");
// add to filter set
tableFilters.add(filterString);
const rowID = tableFilters.size;
let options = {
"model": activeLomeModel,
"frames": frame,
"constructions": "",
"event_filters": activeEventFilters.join("+"),
"doc_filters": activeDocumentFilters.join("+"),
"group_by_cat": "n",
"group_by_constr": "y",
"group_by_role_expr": 0,
"plot_over_days_post": "n",
"relative": "y"
};
console.log(options);
$.get("frame_freq", options).done((data) => {
$tableModalButton.text(oldText);
let countMapping = {};
data["relevant_frame_counts"]["x"].forEach((construction, idx) => {
countMapping[construction] = roundToDecimals(data["relevant_frame_counts"]["y"][idx], 3);
});
$tableModal.modal()
const filterStringDisplay = filterString.split("__")[1].replace("+", "
")
const $tableRows = $("")
.append($(`${rowID} | `))
.append($(`${activeLomeModel} | `))
.append($(`${frame} | `))
.append($(`${filterStringDisplay} | `));
const countKeys = [
`${frame}::nonverbal`,
`${frame}::verbal:active`,
`${frame}::verbal:passive_unaccusative`,
`${frame}::verbal:reflexive`,
`${frame}::other`
]
countKeys.forEach((key) => {
const countValue = key in countMapping ? countMapping[key] : 0.0;
$tableRows.append(`${countValue} | `);
})
$tableModalRows.append($tableRows);
})
}
function switchInitializeDataset() {
// temporally disable the switching buttons
const $switchButtons = $("#dataset-switch a");
$switchButtons.addClass("disabled");
// add dataset information
$("#dataset-info").text(datasetInfo[activeDataset]);
$("#dataset-frame-info").text(datasetFrameInfo[activeDataset]);
$.get("switch_dataset", { "dataset": activeDataset }).done(() => {
console.log(`SERVER: switched dataset to ${activeDataset}`);
// if (activeDataset === "migration/pavia") $("#lome-model-combined").click();
// // switch to the 0shot model
// else
$("#lome-model-0shot").click();
// disable/enable EVALITA option
$("#lome-model-switch a").addClass("disabled");
if (activeDataset === "femicides/rai") {
$("#lome-model-0shot").removeClass("disabled");
$("#lome-model-evalita").removeClass("disabled");
}
if (activeDataset === "migration/pavia") {
$("#lome-model-0shot").removeClass("disabled");
}
else {
$("#lome-model-0shot").removeClass("disabled");
}
// clear stats table
tableFilters.clear();
$tableModalRows.empty();
// clear filters
$("#doc-filter-list button, #ev-filter-list-button").click();
// retrieve dataset-specific info
getRelevantFrames();
getPossibleConstructions();
getPossibleDependencies();
getEventFilters();
getDocumentFilters(() => {
// enable the switching buttons again once filters are loaded
$switchButtons.removeClass("disabled");
});
getDocumentList();
})
}
/* === MAIN === */
/* --- on page load --- */
$(function () {
hideOrShowFilterOptions();
switchInitializeDataset();
});
$(".pwd-prompt").hide();
/* --- event handlers --- */
$("#dataset-switch a").click((event) => {
console.log("Switching datasets...");
relevantFrameCluster = "ALL";
const datasetKeys = [
"femicides/olv",
"femicides/rai",
"crashes/thecrashes",
"migration/pavia"
];
const $datasetOptions = [
$("#femicides-olv"),
$("#femicides-rai"),
$("#crashes-thecrashes"),
$("#migration-pavia")
];
const protectedDatasets = [
// "femicides/rai"
];
$datasetOptions.forEach(($option, idx) => {
if ($(event.target).is($option)) {
activeDataset = datasetKeys[idx];
$("#dataset-switch a").removeClass("active");
$option.addClass("active");
}
})
if (protectedDatasets.includes(activeDataset)) {
console.log("hiding protected elements");
$(".pwd-protected").hide();
$(".pwd-prompt").show();
} else {
$(".pwd-protected").show();
$(".pwd-prompt").hide();
}
// hide or show filter options depending on the selected dataset
hideOrShowFilterOptions();
switchInitializeDataset();
});
$("#pwd-submit").click(() => {
let pwd = $("#password-input").val();
$.post("/check_password", {"password": pwd}).done((result) => {
if (result["success"]) {
$(".pwd-protected").show();
$(".pwd-prompt").hide();
hideOrShowFilterOptions();
switchInitializeDataset();
}
})
});
$("#lome-model-switch a").click((event) => {
console.log("Switching LOME models...");
const modelKeys = [
"lome_0shot",
"lome_evalita_plus_fn",
"lome_zs-tgt_ev-frm"
]
const $modelOptions = [
$("#lome-model-0shot"),
$("#lome-model-evalita"),
$("#lome-model-combined"),
]
$modelOptions.forEach(($option, idx) => {
if ($(event.target).is($option)) {
activeLomeModel = modelKeys[idx];
$("#lome-model-switch a").removeClass("active");
$option.addClass("active");
}
})
})
$("#add-frame-button").click(() => {
let $addFrameInput = $("#add-frame-input");
let newFrame = $addFrameInput.val();
if (!relevantFrames[relevantFrameCluster].includes(newFrame)) {
relevantFrames[relevantFrameCluster].push(newFrame);
}
if (!relevantFrames["ALL"].includes(newFrame)) {
relevantFrames["ALL"].push(newFrame);
}
console.log(relevantFrames);
updateFrameSelectors();
$addFrameInput.val("");
$frameList.append(addFrameButton(newFrame));
});
$("#frame-clusters").change((event) => {
relevantFrameCluster = $(event.target).val();
$frameList.empty();
relevantFrames[relevantFrameCluster].forEach(function (frame) {
$frameList.append(addFrameButton(frame))
});
});
$("#filter-options button").click((event) => {
const $select = ($(event.target).parent().siblings("select"));
const value = $select.val();
activateFilter(value);
});
$("#analyze-doc-button").click(() => {
const docVal = $documentList.val();
const eventId = docVal.split(":")[0];
const docId = docVal.split(":")[1];
processDocument(eventId, docId);
});
$("#frame-sample-list").change((event) => {
const newFrame = $(event.target).val();
$.get("role_labels", { "frame": newFrame }).done((data) => {
updateRoleSampleList(data);
});
});
$("#sample-frame-button").click(() => {
const frameVal = $("#frame-sample-list").val();
const constructionVal = $("#construction-sample-list").val();
const dependencyVal = $("#dep-sample-list").val();
const roleVal = $("#role-sample-list").val();
processSamples(frameVal, constructionVal, dependencyVal, roleVal);
});
const $frameFrequencies = $("#frame-frequencies");
const $frameTgtFrequencies = $("#frame-tgt-frequencies");
const $frameCatFrequencies = $("#frame-syncat-frequencies");
const $frameConstrFrequencies = $("#frame-cx-frequencies");
const $frameRootFrequencies = $("#frame-root-frequencies");
const $frameConstrRootFrequencies = $("#frame-cx-root-frequencies");
$frameFrequencies.click(() => showFrameFrequencies($frameFrequencies, relevantFrames[relevantFrameCluster], "*", false, false, false, false, 0));
$frameTgtFrequencies.click(() => showFrameFrequencies($frameTgtFrequencies, relevantFrames[relevantFrameCluster], "*", true, false, false, false, 0));
$frameCatFrequencies.click(() => showFrameFrequencies($frameCatFrequencies, relevantFrames[relevantFrameCluster], "*", false, true, false, false, 0));
$frameConstrFrequencies.click(() => showFrameFrequencies($frameConstrFrequencies, relevantFrames[relevantFrameCluster], "*", false, false, true, false, 0));
$frameRootFrequencies.click(() => showFrameFrequencies($frameRootFrequencies, relevantFrames[relevantFrameCluster], "*", false, false, false, true, 0));
$frameConstrRootFrequencies.click(() => showFrameFrequencies($frameConstrRootFrequencies, relevantFrames[relevantFrameCluster], "*", false, false, true, true, 0));
const $roleFrequencies = $("#role-frequencies");
const $roleExpFrequencies = $("#role-exp-frequencies");
const $rolePlExpFrequencies = $("#role-pl-exp-frequencies");
const $roleExpDepthFrequencies = $("#role-exp-depth-frequencies");
const $killingStatsTable = $("#constr-table-btn");
$roleFrequencies.click(() => showFrameFrequencies($roleFrequencies, "FROM_FORM", "FROM_FORM", false, false, false, false, 1));
$roleExpFrequencies.click(() => showFrameFrequencies($roleExpFrequencies, "FROM_FORM", "FROM_FORM", false, false, false, false, 2));
$rolePlExpFrequencies.click(() => showFrameFrequencies($rolePlExpFrequencies, "FROM_FORM", "FROM_FORM", false, false, false, false, 3));
$roleExpDepthFrequencies.click(() => showFrameFrequencies($roleExpDepthFrequencies, "FROM_FORM", "FROM_FORM", false, false, false, false, 4));
$killingStatsTable.click(() => showStatsTable("FROM_FORM"));
})
(jQuery);