@ -1,24 +1,40 @@
// t-SNE.js object and other global variables
// t-SNE Visualization and global variables
var k ; var points = [ ] ; var all _fields ; var pointsbeta = [ ] ; var KNNEnabled = true ; var cost = [ ] ; var ParametersSet = [ ] ; var overallCost ;
// form controls
var input ;
// These are the dimensions for the square shape of the main panel\
var dimensions = document . getElementById ( 'modtSNEcanvas' ) . offsetWidth ;
var prevRightClick ; var ColorsCategorical ; var Category ;
// This variable is used when a new file is upload by a user.
var new _file ;
// These are the dimensions for the overview panel
var dim = document . getElementById ( 'tSNEcanvas' ) . offsetWidth ;
// The basic variables in order to execute t-SNE (opt is perplexity and learning rate).
var tsne ; var opt ; var step _counter ; var max _counter ; var runner ;
var format ; var new _file ; var opt ; var step _counter ; var final _dataset ; var max _counter ; var dists ; var dists2d ; var all _labels ; var runner ; var tsne ; var count _canvas = 0 ; var x _position = [ ] ; var y _position = [ ] ; var x _position2 = [ ] ; var y _position2 = [ ] ; var cost _each ; var beta _all = [ ] ;
var points2d = [ ] ; var ArrayContainsDataFeatures = [ ] ; var ArrayContainsDataFeaturesCleared = [ ] ;
var InitialStatePoints = [ ] ;
// These variables are initialized here in order to store the final dataset, the points, the cost, the cost for each iteration, the beta values, the positions, the 2D points positions,
// In addition, there is an array which keeps the initial information of the points (i.e., initial state), the data features (with the label of the category plus the id of the point), the data features without the category (only numbers).
var final _dataset ; var points = [ ] ; var cost = [ ] ; var cost _each ; var beta _all = [ ] ; var x _position = [ ] ; var y _position = [ ] ; var points2d = [ ] ; var ArrayContainsDataFeatures = [ ] ; var ArrayContainsDataFeaturesCleared = [ ] ; var InitialStatePoints = [ ] ;
// The distances in the high dimensional space and in the 2D space. All the labels that were found in the selected data set.
var dists ; var dists2d ; var all _labels ;
// These are the dimensions for the Overview view and the Main view
var dim = document . getElementById ( 'tSNEcanvas' ) . offsetWidth ; var dimensions = document . getElementById ( 'modtSNEcanvas' ) . offsetWidth ;
// Category = the name of the category if it exists. The user has to add an asterisk ("*") mark in order to let the program identify this feature as a label/category name.
// ColorsCategorical = the categorical colors (maximum value = 10).
var Category ; var ColorsCategorical ;
// Schema Investigation
// svgClick = Click a left mouse click in order to add a point.
// prevRightClick = When right click is pressed prevent any other action. Lock the current schema.
// if flagForSchema is false then send a message to the user that he/she has to: "Please, draw a schema first!");
var svgClick ; var prevRightClick ; var flagForSchema = false ;
// Save the parameters for the current analysis, save the overallCost, and store in the "input" variable all the points and points2D.
var ParametersSet = [ ] ; var overallCost ; var input ;
// This function is executed when the factory button is pressed in order to bring the visualization in the initial state.
function FactoryReset ( ) {
lassoEnable ( ) ;
flag = false ;
flagForSchema = false ;
d3 . selectAll ( "#modtSNEcanvas_svg_Schema > *" ) . remove ( ) ;
d3 . selectAll ( "#SvgAnnotator > *" ) . remove ( ) ;
d3 . select ( "#data" ) . select ( "input" ) . remove ( ) ; // Remove the selection field.
Arrayx = [ ] ;
Arrayy = [ ] ;
XYDistId = [ ] ;
@ -95,15 +111,18 @@ function FactoryReset(){
}
// Load a previously executed analysis function.
function loadAnalysis ( ) {
document . getElementById ( 'file-input' ) . click ( ) ;
document . getElementById ( "ExecuteBut" ) . innerHTML = "Execute previous t-SNE analysis" ;
}
// This function is being used when the user selects to upload a new data set.
function getfile ( file ) {
new _file = file ; //uploaded file data
new _file = file ; //uploaded data file
}
// Read the previous analysis, which the user wants to upload.
function fetchVal ( callback ) {
var file , fr ;
file = input . files [ 0 ] ;
@ -115,24 +134,25 @@ function fetchVal(callback) {
fr . readAsText ( file ) ;
}
// Parse data
// Parse the data set
var getData = function ( ) {
let format ;
let value ;
if ( typeof window . FileReader !== 'function' ) {
alert ( "The file API isn't supported on this browser yet." ) ;
}
var value ;
input = document . getElementById ( "file-input" ) ;
if ( ! input ) {
alert ( "Um, couldn't find the fileinput element." ) ;
}
else if ( ! input . files ) {
} else if ( ! input . files ) {
alert ( "This browser doesn't seem to support the `files` property of file inputs." ) ;
}
else if ( ! input . files [ 0 ] ) {
value = document . getElementById ( "param-dataset" ) . value ;
format = document . getElementById ( "param-dataset" ) . value . split ( "." ) ; //get the actual format
} else if ( ! input . files [ 0 ] ) {
value = document . getElementById ( "param-dataset" ) . value ; // get the value of the data set
format = document . getElementById ( "param-dataset" ) . value . split ( "." ) ; //get the format
if ( format [ value . split ( "." ) . length - 1 ] == "csv" ) {
parseData ( "./data/" + value ) ;
} else {
@ -168,8 +188,6 @@ function parseData(url) {
for ( key in el ) {
if ( el . hasOwnProperty ( key ) ) {
var value = el [ key ] ;
if ( key === 'name' ) {
} else {
if ( typeof ( value ) !== 'number' || value === undefined || key === "Version" ) { //add more limitations if needed!
delete el [ key ] ;
} else {
@ -179,7 +197,6 @@ function parseData(url) {
}
}
}
}
return el ;
} ) ;
Papa . parse ( url , { //for csv file!
@ -211,7 +228,7 @@ function setReset(){
d3 . selectAll ( "#correlation > *" ) . remove ( ) ;
d3 . selectAll ( "#modtSNEcanvas_svg > *" ) . remove ( ) ;
lassoEnable ( ) ;
flag = false ;
flagForSchema = false ;
d3 . selectAll ( "#modtSNEcanvas_svg_Schema > *" ) . remove ( ) ;
d3 . selectAll ( "#SvgAnnotator > *" ) . remove ( ) ;
Arrayx = [ ] ;
@ -259,8 +276,10 @@ function setLayerComp(){
d3 . select ( "#modtSNEcanvas_svg" ) . style ( "z-index" , 2 ) ;
d3 . select ( "#modtSNEcanvas_svg_Schema" ) . style ( "z-index" , 1 ) ;
d3 . select ( "#modtSNEcanvas" ) . style ( "z-index" , 1 ) ;
if ( points . length ) {
lassoEnable ( ) ;
}
}
function setLayerSche ( ) {
d3 . select ( "#modtSNEcanvas_svg_Schema" ) . style ( "z-index" , 2 ) ;
@ -355,6 +374,11 @@ function setAnnotator(){
. classed ( "shaded" , function ( d ) { return d . shaded ; } ) ;
}
} else {
// Get the checkbox.
var checkBox = document . getElementById ( "controls" ) ;
// Unchecked!
checkBox . checked = false ;
// Print a message to the user.
alert ( "Cannot hide the annotators' controls because, currently, there are no annotations into the visual representation." )
}
} ) ;
@ -458,7 +482,6 @@ function init(data, results_all, fields) {
var fields ;
fields . push ( "beta" ) ;
fields . push ( "cost" ) ;
all _fields = fields ;
opt . epsilon = document . getElementById ( "param-learningrate-value" ) . value ; // epsilon is learning rate (10 = default)
opt . perplexity = document . getElementById ( "param-perplexity-value" ) . value ; // roughly how many neighbors each point influences (30 = default)
tsne = new tsnejs . tSNE ( opt ) ;
@ -483,19 +506,17 @@ function init(data, results_all, fields) {
for ( let k = 0 ; k < dataFeatures . length ; k ++ ) {
ArrayContainsDataFeatures . push ( Object . values ( dataFeatures [ k ] ) . concat ( k ) ) ;
object = [ ] ;
Object . values ( dataFeatures [ k ] ) . forEach ( function ( dataFeature ) {
if ( typeof ( dataFeature ) == "number" ) {
object . push ( dataFeature ) ;
for ( let j = 0 ; j < Object . keys ( dataFeatures [ k ] ) . length ; j ++ ) {
if ( typeof ( Object . values ( dataFeatures [ k ] ) [ j ] ) == "number" && Object . keys ( dataFeatures [ k ] ) [ j ] != Category ) {
object . push ( Object . values ( dataFeatures [ k ] ) [ j ] ) ;
}
}
} ) ;
ArrayContainsDataFeaturesCleared . push ( object ) ;
}
var valCategExists = 0 ;
for ( var i = 0 ; i < Object . keys ( dataFeatures [ 0 ] ) . length ; i ++ ) {
if ( Object . keys ( dataFeatures [ 0 ] ) [ i ] == Category ) {
valCategExists = valCategExists + 1 ;
}
}
@ -792,7 +813,7 @@ d3.tsv("./modules/heat.tsv").then(function(data) {
var tip = d3 . tip ( )
. attr ( 'class' , 'd3-tip' )
. style ( "visibility" , "visible" )
. offset ( [ - 20 , 0 ] )
. offset ( [ - 10 , 36.5 ] )
. html ( function ( d ) {
return "Value: <span style='color:red'>" + Math . round ( d . value ) ;
} ) ;
@ -1114,7 +1135,6 @@ function redraw(repoints){
function handleLassoEnd ( lassoPolygon ) {
var countLassoFalse = 0 ;
KNNEnabled = true ;
for ( var i = 0 ; i < points . length ; i ++ ) {
x = points [ i ] . x ;
@ -1152,7 +1172,6 @@ function handleLassoEnd(lassoPolygon) {
// reset selected points when starting a new polygon
function handleLassoStart ( lassoPolygon ) {
KNNEnabled = false ;
for ( var i = 0 ; i < points . length ; i ++ ) {
points [ i ] . selected = true ;
points [ i ] . starplot = false ;
@ -1198,9 +1217,6 @@ var svg,
. on ( "touchmove.zoom" , null )
. on ( "touchend.zoom" , null ) ;
var svgClick ;
var flag = false ;
function click ( ) {
svgClick = d3 . select ( '#modtSNEcanvas_svg_Schema' ) ;
@ -1251,7 +1267,7 @@ function click(){
// Prevent the default mouse action. Allow right click to be used for the confirmation of our schema.
d3 . event . preventDefault ( ) ;
flag = true ;
flagForSchema = true ;
CalculateCorrel ( ) ;
}
} ) ;
@ -1259,7 +1275,7 @@ function click(){
function CalculateCorrel ( ) {
if ( flag == false ) {
if ( flagForSchema == false ) {
alert ( "Please, draw a schema first!" ) ;
} else {
var correlLimit = document . getElementById ( "param-corr-value" ) . value ;
@ -1317,7 +1333,7 @@ function CalculateCorrel(){
ArrayLimit = [ ] ;
for ( var i = 0 ; i < arraysCleared . length ; i ++ ) {
if ( arraysCleared [ i ] [ 5 ] < correlLimit ) {
if ( arraysCleared [ i ] [ arraysCleared [ 0 ] . length - 2 ] < correlLimit ) {
ArrayLimit . push ( arraysCleared [ i ] ) ;
}
}
@ -1326,7 +1342,7 @@ function CalculateCorrel(){
var count = new Array ( paths . nodes ( ) . length ) . fill ( 0 ) ;
for ( var m = 0 ; m < paths . nodes ( ) . length ; m ++ ) {
for ( var i = 0 ; i < ArrayLimit . length ; i ++ ) {
if ( ArrayLimit [ i ] [ 2 ] == m ) {
if ( ArrayLimit [ i ] [ ArrayLimit [ 0 ] . length - 5 ] == m ) {
count [ m ] = count [ m ] + 1 ;
temparray . push ( ArrayLimit [ i ] ) ;
}
@ -1361,33 +1377,60 @@ function CalculateCorrel(){
}
var Order = [ ] ;
for ( var temp = 0 ; temp < arraysConnected . length ; temp ++ ) {
Order . push ( arraysConnected [ temp ] [ 6 ] ) ;
Order . push ( arraysConnected [ temp ] [ arraysConnected [ 0 ] . length - 1 ] ) ;
}
for ( var i = 0 ; i < points . length ; i ++ ) {
points [ i ] . selected = false ;
for ( var j = 0 ; j < ArrayLimit . length ; j ++ ) {
if ( ArrayLimit [ j ] [ 6 ] == points [ i ] . id ) {
if ( ArrayLimit [ j ] [ ArrayLimit [ 0 ] . length - 1 ] == points [ i ] . id ) {
points [ i ] . selected = true ;
}
}
}
redraw ( points ) ;
for ( let k = 0 ; k < dataFeatures . length ; k ++ ) {
ArrayContainsDataFeatures . push ( Object . values ( dataFeatures [ k ] ) . concat ( k ) ) ;
ArrayContainsDataFeaturesCleared . push ( ArrayContainsDataFeaturesCleared [ k ] . concat ( k ) ) ;
}
ArrayContainsDataFeatures = mapOrder ( ArrayContainsDataFeatures , Order , 5 ) ;
ArrayContainsDataFeaturesCleared = mapOrder ( ArrayContainsDataFeaturesCleared , Order , arraysConnected [ 0 ] . length - 2 ) ;
ArrayContainsDataFeaturesLimit = [ ] ;
for ( var i = 0 ; i < ArrayContainsDataFeatures . length ; i ++ ) {
for ( var i = 0 ; i < ArrayContainsDataFeaturesCleared . length ; i ++ ) {
for ( var j = 0 ; j < arraysConnected . length ; j ++ ) {
if ( ArrayContainsDataFeatures [ i ] [ 5 ] == arraysConnected [ j ] [ 6 ] ) {
ArrayContainsDataFeaturesLimit . push ( ArrayContainsDataFeatures [ i ] ) ;
if ( ArrayContainsDataFeaturesCleared [ i ] [ ArrayContainsDataFeaturesCleared [ 0 ] . length - 1 ] == arraysConnected [ j ] [ arraysConnected [ 0 ] . length - 1 ] ) {
ArrayContainsDataFeaturesLimit . push ( ArrayContainsDataFeaturesCleared [ i ] ) ;
}
}
}
if ( ArrayContainsDataFeaturesLimit . length == 0 ) {
d3 . selectAll ( "#correlation > *" ) . remove ( ) ;
d3 . selectAll ( "#modtSNEcanvas_svg > *" ) . remove ( ) ;
flagForSchema = false ;
d3 . selectAll ( "#modtSNEcanvas_svg_Schema > *" ) . remove ( ) ;
Arrayx = [ ] ;
Arrayy = [ ] ;
XYDistId = [ ] ;
Arrayxy = [ ] ;
DistanceDrawing1D = [ ] ;
allTransformPoints = [ ] ;
p ;
pFinal = [ ] ;
paths ;
path ;
ArrayLimit = [ ] ;
minimum ;
correlationResults = [ ] ;
ArrayContainsDataFeaturesLimit = [ ] ;
prevRightClick = false ;
for ( var i = 0 ; i < InitialStatePoints . length ; i ++ ) {
InitialStatePoints [ i ] . selected = true ;
InitialStatePoints [ i ] . starplot = false ;
}
alert ( "No points selected! Please, try to increase the correlation threshold." ) ;
redraw ( InitialStatePoints ) ;
} else {
for ( var loop = 0 ; loop < ArrayContainsDataFeaturesLimit . length ; loop ++ ) {
ArrayContainsDataFeaturesLimit [ loop ] . push ( loop ) ;
}
@ -1430,6 +1473,7 @@ function CalculateCorrel(){
drawBarChart ( ) ;
}
}
}
function drawBarChart ( ) {
d3 . selectAll ( "#correlation > *" ) . remove ( ) ;
@ -1960,6 +2004,7 @@ height = Math.min(width, window.innerHeight - margin.top - margin.bottom);
function BetatSNE ( points ) {
if ( points . length ) {
selectedPoints = [ ] ;
var findNearestTable = [ ] ;
for ( let m = 0 ; m < points . length ; m ++ ) {
@ -1968,7 +2013,7 @@ function BetatSNE(points){
}
}
if ( KNNEnabled == true && selectedPoints . length != 0 ) {
if ( selectedPoints . length != 0 ) {
var distsFull = dists ;
var dists2dFull = dists2d ;
@ -2008,7 +2053,7 @@ function BetatSNE(points){
$ ( "#kNNDetails" ) . html ( "Purity of the cluster was checked for k values starting from " + ( 1 ) + " to " + maxKNN + "." ) ;
for ( k = maxKNN ; k > 0 ; k -- ) {
for ( k = maxKNN ; k > 1 ; k -- ) {
findNearest = 0 ;
var indexOrderSliced = [ ] ;
@ -2697,7 +2742,7 @@ function hideTooltip() {
tooltip _state . display = "none" ;
updateTooltip ( ) ;
}
}
}