Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions dist/bundle.js

Large diffs are not rendered by default.

4,350 changes: 4,350 additions & 0 deletions global_embedding_plot.tsv

Large diffs are not rendered by default.

29 changes: 27 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,33 @@
<!-- Example based on http://bl.ocks.org/mbostock/3887118 -->
<!-- Tooltip example from http://www.d3noob.org/2013/01/adding-tooltips-to-d3js-graph.html -->
<body>
<p class="p12" id="predicted_words"></p>
<p class="p13" id="frequent_words"></p>

<!-- SARAH EDITING THE BELOW HTML -->

<div id="local-upload-container" class="file-upload-container">
<h3>Upload your course data</h3>

<p>
Upload a TSV or CSV file containing numeric <b>x</b> and <b>y</b>
columns and at least one additional course-information column.
</p>

<input
type="file"
id="data-file-input"
accept=".tsv,.txt,.csv,text/tab-separated-values,text/csv"
>

<p id="file-upload-status">
No file selected.
</p>
</div>

<p class="p12" id="predicted_words"></p>

<p class="p13" id="frequent_words"></p>

<!-- SARAH EDITING HTML DONE -->
<div class="plot-area">
<div class="plot-container">
</div>
Expand Down
331 changes: 327 additions & 4 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ import { ZoomService } from './modules/zoom_service.js';
// Begin Script
// *******************************************

export const dataset = queryParams.get("dataset") || "joined_data.csv";

export const dataset = queryParams.get("dataset") || "global_embedding_plot.tsv";
var weights_2darray = [], biases_1darray = [], vocab_1darray = [], vectorspace_2darray = [], bow_2darray = [];
// Semantic model option set up
if (queryParams.get("semantic_model") === "true") {
Expand Down Expand Up @@ -107,7 +108,9 @@ let mainData;
let dataManager;
let filterScrubber;

function loadMainData(data) {
// SARAH EDITED CODE START //
function loadMainData(data, applyUrlDefaults = true) {
// SARAH EDITED CODE DONE //
console.log('Loading main data');
let categoryHeaders = data.columns.filter(cat => cat !== 'x' && cat !== 'y');
categoryHeaders.forEach((categoryHeader) => {
Expand All @@ -130,8 +133,13 @@ function loadMainData(data) {
dropdownBuilder.build(categorySearchData, categories);
dropdownBuilder.setDropdownEventHandlers(redrawPlotWithoutZoom);

preSelectCheckboxValues();
preSelectDropdownValues(categories, categorySearchData);
// SARAH EDITED CODE START //

if (applyUrlDefaults) {
preSelectCheckboxValues();
preSelectDropdownValues(categories, categorySearchData);
}
// SARAH EDITED CODE DONE //

// Initial plot draw happens here:
let needZoom = false;
Expand All @@ -143,6 +151,321 @@ console.log('initiating dataset load;');
let fetchPromise = d3.tsv(dataset);
fetchPromise.then(loadMainData).catch(e => console.log(e));

///SARAH ADDED CODE START///
// *******************************************
// User-uploaded dataset functionality
// *******************************************

function setUploadStatus(message, isError = false) {
let status = document.getElementById("file-upload-status");

if (status) {
status.textContent = message;
status.style.color = isError ? "red" : "";
}
}


// Make sure an uploaded dataset has the fields
// required by the scatterplot.
function validateUploadedData(data) {

if (!data || data.length === 0) {
throw new Error(
"The uploaded file does not contain any data rows."
);
}

if (!data.columns) {
throw new Error(
"Could not determine the column names in this file."
);
}

if (
!data.columns.includes("x") ||
!data.columns.includes("y")
) {
throw new Error(
'The file must contain columns named "x" and "y".'
);
}

let descriptiveColumns = data.columns.filter(
column => column !== "x" && column !== "y"
);

if (descriptiveColumns.length === 0) {
throw new Error(
'The file must contain at least one column besides "x" and "y".'
);
}


let invalidCoordinates = data.some((row) => {

let xMissing =
row.x === undefined ||
row.x === null ||
String(row.x).trim() === "";

let yMissing =
row.y === undefined ||
row.y === null ||
String(row.y).trim() === "";

return (
xMissing ||
yMissing ||
!Number.isFinite(+row.x) ||
!Number.isFinite(+row.y)
);
});


if (invalidCoordinates) {
throw new Error(
'Every row must contain numeric values in the "x" and "y" columns.'
);
}
}


// Clear the pieces of the interface that depend
// on the old dataset before loading a new one.
function resetForUploadedData() {

// Remove existing visualization and table
d3.select("svg").remove();
d3.select(".summary-data").remove();


// Clear existing feature dropdowns
d3.select(".click-on-feature").remove();
d3.select(".color-by-feature").remove();
d3.select(".search-by-feature").remove();
d3.select(".shape-by-feature").remove();
d3.select(".transparency-by-feature").remove();
d3.select(".scrubber-dropdown").remove();


// Destroy the existing numeric slider
let slider = document.querySelector(".sliders");

if (slider && slider.noUiSlider) {
slider.noUiSlider.destroy();
}

if (slider) {
slider.innerHTML = "";
}


// Clear the side summary
let sideTable = document.querySelector(".side-table");

if (sideTable) {
sideTable.innerHTML = "";
}


// Clear search text
let searchText = document.getElementById("searchText");

if (searchText) {
searchText.value = "";
}


// Clear transparency search
let transparencyText =
document.getElementById("transpText");

if (transparencyText) {
transparencyText.value = "";
}


// Reset checkboxes
document.querySelectorAll(".check").forEach((checkbox) => {
checkbox.checked = false;
});


// Reset data-dependent arrays
categories.length = 0;
categories.push(defaultValue);

categorySearchData.length = 0;

columns.length = 0;


// Uploaded data should not inherit a search
// column from the original URL.
categorySearch = null;


// Reset zoom coordinates
coordinatesx.length = 0;
coordinatesy.length = 0;


// Reset main data objects
mainData = null;
dataManager = null;
filterScrubber = null;
}


// Read and visualize a file selected by the user.
function loadUploadedFile(file) {

setUploadStatus(
"Reading " + file.name + "..."
);


let reader = new FileReader();


reader.onload = function(event) {

try {

let fileText = event.target.result;
let fileName = file.name.toLowerCase();

let uploadedData;


if (fileName.endsWith(".csv")) {

uploadedData = d3.csvParse(fileText);

}

else if (
fileName.endsWith(".tsv") ||
fileName.endsWith(".txt")
) {

uploadedData = d3.tsvParse(fileText);

}

else {

throw new Error(
"Please upload a CSV or TSV file."
);

}


validateUploadedData(uploadedData);


console.log(
"Uploaded file:",
file.name
);

console.log(
"Uploaded rows:",
uploadedData.length
);

console.log(
"Uploaded columns:",
uploadedData.columns
);


// Remove controls associated with old data
resetForUploadedData();


// Load uploaded data through the normal
// scatterplot pipeline.
//
// false = don't apply URL-specific defaults
loadMainData(uploadedData, false);


setUploadStatus(
"Showing " +
file.name +
" (" +
uploadedData.length +
" rows)"
);

}

catch (error) {

console.error(
"Could not load uploaded file:",
error
);

setUploadStatus(
error.message,
true
);

}

};


reader.onerror = function() {

setUploadStatus(
"The selected file could not be read.",
true
);

};


reader.readAsText(file);
}


// Connect the upload input in index.html
let dataFileInput =
document.getElementById("data-file-input");


if (dataFileInput) {

dataFileInput.addEventListener(
"change",
function(event) {

let file = event.target.files[0];

if (!file) {
return;
}

loadUploadedFile(file);

}
);

}


// Initial message shown while the default data is displayed
setUploadStatus(
"Showing the default dataset. Upload a CSV or TSV file to replace it."
);

// SARAH ADDED CODE DONE ///


function searchExactMatchEventHandler(event) {
if (document.getElementById("searchText").value) redrawPlotWithoutZoom();
Expand Down
Loading