-
-
-
-
Shepard Heatmap
-
-
+
-
-
+
+
+
+
Visual Mapping Parameters
+
+
+
+
+
+
Neighborhood Preservation
+
+ Color
+ Size
+
+
+
Final Cost (Kullback-Leibler)
+
Vice versa
+
+
+ Correlation threshold
+
+ 150
+
+ Visualization annotating form:
+
+
+
+
+
Continue with the analysis
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
t-SNE Parameters
-
-
-
-
-
Data sets
-
- Red Wine - Quality
- Iris
- Mnist
- Frogs
- Add New File
-
+
-
- Perplexity
-
- 30
-
-
- Learning rate
-
- 10
-
-
- Max iterations
-
- 10
-
-
- Distance metric
-
- Euclidean distance
- Jaccard dissimilarity
-
-
-
-
- Data transform
-
- No transform
- Log10
- asinh
- Binarize
-
-
-
-
Run New tSNE
-
-
-
-
-
-
-
-
+
-
+
-
-
+
+
+
diff --git a/js/tsne_vis.js b/js/tsne_vis.js
index 7dc74c3..75cdfac 100755
--- a/js/tsne_vis.js
+++ b/js/tsne_vis.js
@@ -9,6 +9,7 @@ var dim = document.getElementById('tSNEcanvas').offsetWidth;
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 = [];
function getfile(file){
new_file = file; //uploaded file data
@@ -69,20 +70,51 @@ function parseData(url) {
});
}
-function setToggle(toggleVal){
- toggleValue = toggleVal;
-}
-
function setContinue(){
d3v3.select("#SvgAnnotator").style("z-index", 2);
}
+var ringNotes = [];
+var gAnnotationsAll = [];
+var AnnotationsAll = [];
+var draggable = [];
+
+function setReset(){
+ d3.selectAll("#SvgAnnotator > *").remove();
+ d3.selectAll("#OverviewtSNE > *").remove();
+ d3.selectAll("#correlation > *").remove();
+ d3.selectAll("#modtSNEcanvas_svg > *").remove();
+ d3.selectAll("#kNNBar > *").remove();
+ for (var i=0; i < InitialStatePoints.length; i++){
+ InitialStatePoints[i].selected = true;
+ }
+ redraw(InitialStatePoints);
+}
+
+function setLayerProj(){
+ d3.select("#modtSNEcanvas").style("z-index", 2);
+ d3.select("#modtSNEcanvas_svg").style("z-index", 1);
+}
+
+function setLayerComp(){
+ d3.select("#modtSNEcanvas_svg").style("z-index", 3);
+}
+
+function setLayerSche(){
+ d3.select("#modtSNEcanvas_svg").style("z-index", 3);
+ toggleValue = true;
+}
+
+
+
+
function setAnnotator(){
var viewport2 = getViewport();
var vw2 = viewport2[0];
var vh2 = viewport2[1];
var textarea = document.getElementById("comment").value;
+
var annotations = [
{
"cx": 232,
@@ -101,7 +133,7 @@ function setAnnotator(){
var svgAnnotator = d3v3.select("#SvgAnnotator")
.attr("width", vw2 * 0.5)
- .attr("height", vh2 * 0.872)
+ .attr("height", vh2 * 0.888)
.style("z-index", 3);
@@ -113,20 +145,66 @@ function setAnnotator(){
gAnnotations.selectAll(".annotation circle")
.classed("shaded", function(d) { return d.shaded; });
+
+ ringNotes.push(ringNote);
+ gAnnotationsAll.push(gAnnotations);
+ AnnotationsAll.push(annotations);
+ draggable.push(true);
+}
+
+
// Hide or show the controls
- var draggable = true;
- d3.select("input")
+ d3.select("#controls")
.on("change", function() {
- ringNote.draggable(draggable = !draggable);
- gAnnotations
- .call(ringNote, annotations)
- .selectAll(".annotation circle")
- .classed("shaded", function(d) { return d.shaded; });
+ if(ringNotes[0]){
+ for (var i = 0; i < ringNotes.length; i++){
+ ringNotes[i].draggable(draggable[i] = !draggable[i]);
+ gAnnotationsAll[i]
+ .call(ringNotes[i], AnnotationsAll[i])
+ .selectAll(".annotation circle")
+ .classed("shaded", function(d) { return d.shaded; });
+ }
+ } else{
+ alert("Cannot hide the annotators' controls because, currently, there are no annotations into the visual representation.")
+ }
});
-}
+
+ // Three.js render loop
+ function animate() {
+ requestAnimationFrame(animate);
+ renderer.render(scene, camera);
+ }
+
+ var MainCanvas;
+ var Child;
+ var renderer;
+ var fov = 21;
+ var near = 10;
+ var far = 7000;
+ var camera;
+ var scene;
// function that executes after data is successfully loaded
function init(data, results_all, fields) {
+
+ MainCanvas = document.getElementById('modtSNEcanvas');
+ Child = document.getElementById('modtSNEDiv');
+
+ // Add canvas
+ renderer = new THREE.WebGLRenderer({ canvas: MainCanvas});
+ renderer.setSize(dimensions, dimensions);
+ Child.append(renderer.domElement);
+ scene = new THREE.Scene();
+ scene.background = new THREE.Color(0xffffff);
+
+ // Set up camera and scene
+ camera = new THREE.PerspectiveCamera(
+ fov,
+ dimensions / dimensions,
+ near,
+ far
+ );
+ animate();
step_counter = 0;
max_counter = document.getElementById("param-maxiter-value").value;
opt = {};
@@ -150,7 +228,8 @@ function init(data, results_all, fields) {
});
ArrayContainsDataFeaturesCleared.push(object);
}
- $("#datasetDetails").html("Number of Dimensions: " + ArrayContainsDataFeaturesCleared[0].length + ", Number of Samples: " + final_dataset.length);
+
+ $("#datasetDetails").html("Number of Dimensions: " + (ArrayContainsDataFeatures[0].length - 1) + ", Number of Samples: " + final_dataset.length);
dists = computeDistances(data, document.getElementById("param-distance").value, document.getElementById("param-transform").value);
tsne.initDataDist(dists);
all_labels = [];
@@ -300,11 +379,12 @@ function updateEmbedding() {
for(var i = 0; i < final_dataset.length; i++) {
x_position[i] = x(Y[i][0]);
y_position[i] = y(Y[i][1]);
- points[i] = {id: i, x: x_position[i], y: y_position[i], beta: final_dataset[i].beta, cost: final_dataset[i].cost, selected: true, DimON: null};
+ points[i] = {id: i, x: x_position[i], y: y_position[i], beta: final_dataset[i].beta, cost: final_dataset[i].cost, selected: true, DimON: null, starplot: false};
points2d[i] = {id: i, x: x_position[i], y: y_position[i], selected: true};
points[i] = extend(points[i], ArrayContainsDataFeaturesCleared[i]);
points[i] = extend(points[i], dataFeatures[i]);
}
+ InitialStatePoints = points;
function extend(obj, src) {
for (var key in src) {
if (src.hasOwnProperty(key)) obj[key] = src[key];
@@ -751,8 +831,9 @@ function OverviewtSNE(points){
gl.drawArrays(gl.POINTS, 0, points.length);
}
+
function redraw(repoints){
- OverviewtSNE(repoints);
+ //OverviewtSNE(repoints);
BetatSNE(repoints);
//CosttSNE(repoints);
}
@@ -779,6 +860,17 @@ function handleLassoEnd(lassoPolygon) {
points2d[i].selected = true;
}
}
+ if (points.length - countLassoFalse <= 10 && points.length - countLassoFalse != 0){
+ for (var i = 0 ; i < points.length ; i ++) {
+ if (points[i].selected == true){
+ points[i].starplot = true;
+ }
+ }
+ } else{
+ for (var i = 0 ; i < points.length ; i ++) {
+ points[i].starplot = false;
+ }
+ }
redraw(points);
} else{
click();
@@ -793,6 +885,7 @@ function handleLassoStart(lassoPolygon) {
KNNEnabled = false;
for (var i = 0 ; i < points.length ; i ++) {
points[i].selected = true;
+ points[i].starplot = false;
points2d[i].selected = true;
}
@@ -814,6 +907,28 @@ var svg,
mini_width,
textScale;
+ //Added only for the mouse wheel
+ var zoomer = d3v3.behavior.zoom()
+ .on("zoom", null);
+
+ var main_margin = {top: 8, right: 10, bottom: 30, left: 100},
+ main_width = 500 - main_margin.left - main_margin.right,
+ main_height = 320 - main_margin.top - main_margin.bottom;
+
+ var mini_margin = {top: 8, right: 10, bottom: 30, left: 10},
+ mini_height = 320 - mini_margin.top - mini_margin.bottom;
+ mini_width = 100 - mini_margin.left - mini_margin.right;
+
+ svg = d3v3.select("#correlation").attr("class", "svgWrapper")
+ .attr("width", main_width + main_margin.left + main_margin.right + mini_width + mini_margin.left + mini_margin.right)
+ .attr("height", main_height + main_margin.top + main_margin.bottom)
+ .call(zoomer)
+ .on("wheel.zoom", scroll)
+ .on("mousedown.zoom", null)
+ .on("touchstart.zoom", null)
+ .on("touchmove.zoom", null)
+ .on("touchend.zoom", null);
+
function click(){
let svgClick = d3.select('#modtSNEcanvas_svg');
@@ -909,7 +1024,6 @@ function click(){
}
}
- //console.log("ArrayLimit"+ArrayLimit);
var temparray = [];
var count = new Array(paths.nodes().length).fill(0);
for (var m=0; m < paths.nodes().length; m++) {
@@ -1024,28 +1138,7 @@ function click(){
/////////////////////////////////////////////////////////////
///////////////// Set-up SVG and wrappers ///////////////////
/////////////////////////////////////////////////////////////
-
- //Added only for the mouse wheel
- var zoomer = d3v3.behavior.zoom()
- .on("zoom", null);
-
- var main_margin = {top: 0, right: 10, bottom: 30, left: 100},
- main_width = 500 - main_margin.left - main_margin.right,
- main_height = 320 - main_margin.top - main_margin.bottom;
-
- var mini_margin = {top: 0, right: 10, bottom: 30, left: 10},
- mini_height = 320 - mini_margin.top - mini_margin.bottom;
- mini_width = 100 - mini_margin.left - mini_margin.right;
-
- svg = d3v3.select("#correlation").attr("class", "svgWrapper")
- .attr("width", main_width + main_margin.left + main_margin.right + mini_width + mini_margin.left + mini_margin.right)
- .attr("height", main_height + main_margin.top + main_margin.bottom)
- .call(zoomer)
- .on("wheel.zoom", scroll)
- .on("mousedown.zoom", null)
- .on("touchstart.zoom", null)
- .on("touchmove.zoom", null)
- .on("touchend.zoom", null);
+
var mainGroup = svg.append("g")
.attr("class","mainGroupWrapper")
@@ -1126,17 +1219,15 @@ function click(){
/////////////////////////////////////////////////////////////
///////////////////////// Create brush //////////////////////
/////////////////////////////////////////////////////////////
+
+ //What should the first extent of the brush become - a bit arbitrary this
var brushExtent = parseInt(Math.max( 1, Math.min( 20, Math.round(correlationResults.length * 0.75) ) ));
- //What should the first extent of the brush become - a bit arbitrary this
- //var brushExtent = Math.max( 1, Math.min( 20, Math.round(correlationResults.length*0.2) ) );
- // console.log(brushExtent);
brush = d3v3.svg.brush()
.y(mini_yScale)
.extent([mini_yScale(correlationResults[0][0]), mini_yScale(correlationResults[brushExtent][0])])
.on("brush", brushmove)
- //Set up the visual part of the brush
//Set up the visual part of the brush
gBrush = d3v3.select(".brushGroup").append("g")
.attr("class", "brush")
@@ -1534,504 +1625,108 @@ function abbreviateNumber(value) {
return newValue;
}
-function BetatSNE(points){
-
- if(step_counter == max_counter || step_counter == 1){
- if (step_counter == 1){
- d3.select("#modtSNEcanvas_svg").select("g").remove();
- }else{
- if (toggleValue == false){
- interactionSvg = d3.select("#modtSNEcanvas_svg")
- .attr("width", dimensions)
- .attr("height", dimensions)
- .style('position', 'absolute')
- .style('top', 0)
- .style('left', 0);
- var lassoInstance = lasso()
- .on('end', handleLassoEnd)
- .on('start', handleLassoStart);
-
- interactionSvg.call(lassoInstance);
- }
- }
- }
-
- var canvas = document.getElementById('modtSNEcanvas');
- var gl = canvas.getContext('webgl');
- // If we don't have a GL context, give up now
-
- if (!gl) {
- alert('Unable to initialize WebGL. Your browser or machine may not support it.');
- return;
+function clearThree(obj){
+ while(obj.children.length > 0){
+ clearThree(obj.children[0])
+ obj.remove(obj.children[0]);
}
+ if(obj.geometry) obj.geometry.dispose()
+ if(obj.material) obj.material.dispose()
+ if(obj.texture) obj.texture.dispose()
+}
- var ColSizeSelector = document.getElementById("param-neighborHood").value;
-
- if (ColSizeSelector == "color") {
- var max = (d3.max(final_dataset,function(d){ return d.beta; }));
- var min = (d3.min(final_dataset,function(d){ return d.beta; }));
- // colors
- var colorbrewer = ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"];
- var calcStep = (max-min)/7;
- var colorScale = d3.scaleLinear()
- .domain(d3.range(0, max+calcStep, calcStep))
- .range(colorbrewer);
-
- var maxSize1 = (d3.max(final_dataset,function(d){ return d.cost; }));
- var minSize1 = (d3.min(final_dataset,function(d){ return d.cost; }));
- var rscale1 = d3.scaleLinear()
- .domain([minSize1, maxSize1])
- .range([5,10]);
+var viewport3 = getViewport();
+var vw3 = viewport3[0] * 0.2;
+var margin = {top: 40, right: 100, bottom: 40, left: 190},
+width = Math.min(vw3, window.innerWidth - 10) - margin.left - margin.right,
+height = Math.min(width, window.innerHeight - margin.top - margin.bottom);
- var colorScale = d3.scaleLinear()
- .domain(d3.range(0, max+calcStep, calcStep))
- .range(colorbrewer);
+ var wrapData = [];
- points = points.sort(function(a, b) {
- return a.beta - b.beta;
- })
- var labels_beta = [];
- var abbr_labels_beta = [];
- labels_beta = d3.range(0, max+calcStep, calcStep);
- for (var i=0; i<9; i++){
- labels_beta[i] = parseInt(labels_beta[i]);
- abbr_labels_beta[i] = abbreviateNumber(labels_beta[i]);
- }
- var svg = d3.select("#legend1");
+ //////////////////////////////////////////////////////////////
+ //////////////////// Draw the Chart //////////////////////////
+ //////////////////////////////////////////////////////////////
- svg.append("g")
- .attr("class", "legendLinear")
- .attr("transform", "translate(10,15)");
- var legend = d3.legendColor()
- .labelFormat(d3.format(",.0f"))
- .cells(9)
- .labels([abbr_labels_beta[0],abbr_labels_beta[1],abbr_labels_beta[2],abbr_labels_beta[3],abbr_labels_beta[4],abbr_labels_beta[5],abbr_labels_beta[6],abbr_labels_beta[7],abbr_labels_beta[8]])
- .title("1 / sigma")
- .scale(colorScale);
-
- svg.select(".legendLinear")
- .call(legend);
- } else {
- var max = (d3.max(final_dataset,function(d){ return d.cost; }));
- var min = (d3.min(final_dataset,function(d){ return d.cost; }));
-
- var maxSize2 = (d3.max(final_dataset,function(d){ return d.beta; }));
- var minSize2 = (d3.min(final_dataset,function(d){ return d.beta; }));
-
- var rscale2 = d3.scaleLinear()
- .domain([minSize2, maxSize2])
- .range([5,10]);
+ var radarChartOptions = {
+ w: width,
+ h: height,
+ margin: margin,
+ maxValue: 100,
+ roundStrokes: true
+ };
+ var colors;
+ var IDS = [];
+ //Call function to draw the Radar chart
+ RadarChart("#starPlot", wrapData, colors, IDS, radarChartOptions);
- var colorbrewer = ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"];
- var calcStep = (max-min)/9;
- var colorScale = d3.scaleLinear()
- .domain(d3.range(min, max, calcStep))
- .range(colorbrewer);
-
- points = points.sort(function(a, b) {
- return a.cost - b.cost;
- })
+function BetatSNE(points){
+
+ selectedPoints = [];
+ var findNearestTable = [];
+ for (let m=0; m
0; k--){
- for (var i=0; i1 to 0->2
- let zeroToTwo = zeroToOne * 2.0;
- let zeroToTwo2 = zeroToOne2 * 2.0;
+ for (var i=0; i2 to -1->+1 (clipspace)
- let clipSpace = zeroToTwo - 1.0;
- let clipSpace2 = zeroToTwo2 - 1.0;
- singleObj = clipSpace;
- vertices.push(singleObj);
- singleObj = clipSpace2 * -1;
- vertices.push(singleObj);
- singleObj = 0.0;
- vertices.push(singleObj);
- }
+ temp[i] = 0;
+ temp2[i] = 0;
- for (var i=0; i1; k--){
-
- findNearest = 0;
- var indexOrderSliced = [];
- var indexOrderSliced2d = [];
- var count1 = new Array(selectedPoints.length).fill(0);
- var count2 = new Array(selectedPoints.length).fill(0);
- counter1 = 0;
- counter2 = 0;
-
- for (var i=0; i {
+ dimensions = window.innerWidth;
+ viz_width = dimensions;
+ dimensions = window.innerHeight;
+
+ renderer.setSize(dimensions, dimensions);
+ camera.aspect = dimensions / dimensions;
+ camera.updateProjectionMatrix();
+})
+
+let zoom = d3.zoom()
+ .scaleExtent([getScaleFromZ(far), getScaleFromZ(near)])
+ .on('zoom', () => {
+ let d3_transform = d3.event.transform;
+ zoomHandler(d3_transform);
+ });
+
+view = d3.select(renderer.domElement);
+function setUpZoom() {
+ view.call(zoom);
+ let initial_scale = getScaleFromZ(far);
+ var initial_transform = d3.zoomIdentity.translate(viz_width/2, dimensions/2).scale(initial_scale);
+ zoom.transform(view, initial_transform);
+ camera.position.set(0, 0, far);
+}
+setUpZoom();
+
+var circle_sprite= new THREE.TextureLoader().load(
+ "./textures/circle-sprite.png"
+)
+
+let pointsGeometry = new THREE.Geometry();
+
+clearThree(scene);
+
+// Increase/reduce size factor selected by the user
+var limitdist = document.getElementById("param-lim-value").value;
+limitdist = parseFloat(limitdist).toFixed(1);
+
+let pointsMaterial = [];
+let factorPlusSize = [];
+for (var i=0; i {
+ let [mouseX, mouseY] = d3.mouse(view.node());
+ let mouse_position = [mouseX, mouseY];
+checkIntersects(mouse_position);
+});
+
+function mouseToThree(mouseX, mouseY) {
+ return new THREE.Vector3(
+ mouseX / viz_width * 2 - 1,
+ -(mouseY / dimensions) * 2 + 1,
+ 1
+ );
+}
+function checkIntersects(mouse_position) {
+ let mouse_vector = mouseToThree(...mouse_position);
+ raycaster.setFromCamera(mouse_vector, camera);
+ let intersects = raycaster.intersectObject(particles);
+ if (intersects[0]) {
+ let sorted_intersects = sortIntersectsByDistanceToRay(intersects);
+ let intersect = sorted_intersects[0];
+ let index = intersect.index;
+ let datum = points[index];
+ highlightPoint(datum);
+ showTooltip(mouse_position, datum);
+ } else {
+ removeHighlights();
+ hideTooltip();
+ }
+}
+
+function sortIntersectsByDistanceToRay(intersects) {
+ return _.sortBy(intersects, "distanceToRay");
+}
+
+hoverContainer = new THREE.Object3D()
+scene.add(hoverContainer);
+
+function highlightPoint(datum) {
+ removeHighlights();
+
+ let geometry = new THREE.Geometry();
+ geometry.vertices.push(
+ new THREE.Vector3(
+ (((datum.x/dimensions)*2) - 1)*dimensions,
+ (((datum.y/dimensions)*2) - 1)*dimensions*-1,
+ 0
+ )
+ );
+
+ if (all_labels[0] == undefined){
+ var colorScaleCat = d3.scaleOrdinal(d3.schemeCategory10).domain(["No Category"]).range(["#0000ff"]);
+ }
+ else{
+ var colorScaleCat = d3.scaleOrdinal(d3.schemeCategory10).domain(all_labels);
+ }
+
+ geometry.colors = [ new THREE.Color(colorScaleCat(datum.name)) ];
+
+ let material = new THREE.PointsMaterial({
+ size: 26,
+ sizeAttenuation: false,
+ vertexColors: THREE.VertexColors,
+ map: circle_sprite,
+ transparent: true
+ });
+
+ let point = new THREE.Points(geometry, material);
+ hoverContainer.add(point);
+}
+
+function removeHighlights() {
+ hoverContainer.remove(...hoverContainer.children);
+}
+
+view.on("mouseleave", () => {
+ removeHighlights()
+});
+
+// Initial tooltip state
+let tooltip_state = { display: "none" }
+let tooltip_dimensions;
+let tooltip_template = document.createRange().createContextualFragment(``);
+document.body.append(tooltip_template);
+
+let $tooltip = document.querySelector('#tooltip');
+let $point_tip = document.querySelector('#point_tip');
+let $group_tip = document.querySelector('#group_tip');
+
+function updateTooltip() {
+ if (all_labels[0] == undefined){
+ var colorScaleCat = d3.scaleOrdinal(d3.schemeCategory10).domain(["No Category"]).range(["#0000ff"]);
+ }
+ else{
+ var colorScaleCat = d3.scaleOrdinal(d3.schemeCategory10).domain(all_labels);
+ }
+ $tooltip.style.display = tooltip_state.display;
+ $tooltip.style.left = tooltip_state.left + 'px';
+ $tooltip.style.top = tooltip_state.top + 'px';
+ $point_tip.innerText = tooltip_state.name;
+ $point_tip.style.background = colorScaleCat(tooltip_state.color);
+ $group_tip.innerText = `Data set's features: ${tooltip_dimensions}`;
+}
+
+function showTooltip(mouse_position, datum) {
+ let tooltip_width = 240;
+ let x_offset = tooltip_width + tooltip_width;
+ let y_offset = 30;
+ tooltip_state.display = "block";
+ tooltip_state.left = mouse_position[0] + x_offset;
+ tooltip_state.top = mouse_position[1] + y_offset;
+ if (all_labels[0] == undefined){
+ tooltip_state.name = datum.id;
+ tooltip_state.color = datum.id;
+ } else{
+ tooltip_state.name = datum.name + " (" + datum.id + ")";
+ tooltip_state.color = datum.name;
+ }
+ tooltip_dimensions = [];
+ for (var i=0; i < ArrayContainsDataFeaturesCleared.length; i++){
+ if (datum.id == i){
+ for (var j=0; j < ArrayContainsDataFeaturesCleared[i].length; j++){
+ tooltip_dimensions.push(ArrayContainsDataFeaturesCleared[i][j]);
+ }
+ }
}
+ updateTooltip();
+}
+
+function hideTooltip() {
+ tooltip_state.display = "none";
+ updateTooltip();
+}
+
+
}
function getViewport() {
@@ -2227,48 +2395,130 @@ function BetatSNE(points){
}
return [viewPortWidth, viewPortHeight];
}
+
-/*
-function CosttSNE(points){
- var canvas = document.getElementById('pointCostcanvas');
- var gl = canvas.getContext('experimental-webgl');
- // If we don't have a GL context, give up now
+ /*
+ var canvas = document.getElementById('modtSNEcanvas');
+ var gl = canvas.getContext('webgl');
+ // If we don't have a GL context, give up now
+
+ if (!gl) {
+ alert('Unable to initialize WebGL. Your browser or machine may not support it.');
+ return;
+ }
+
+ var ColSizeSelector = document.getElementById("param-neighborHood").value;
+
+ if (ColSizeSelector == "color") {
+ var max = (d3.max(final_dataset,function(d){ return d.beta; }));
+ var min = (d3.min(final_dataset,function(d){ return d.beta; }));
+ // colors
+ var colorbrewer = ["#ffffcc","#ffeda0","#fed976","#feb24c","#fd8d3c","#fc4e2a","#e31a1c","#bd0026","#800026"];
+ var calcStep = (max-min)/7;
+ var colorScale = d3.scaleLinear()
+ .domain(d3.range(0, max+calcStep, calcStep))
+ .range(colorbrewer);
+
+ var maxSize1 = (d3.max(final_dataset,function(d){ return d.cost; }));
+ var minSize1 = (d3.min(final_dataset,function(d){ return d.cost; }));
+
+ var rscale1 = d3.scaleLinear()
+ .domain([minSize1, maxSize1])
+ .range([5,10]);
+
+ var colorScale = d3.scaleLinear()
+ .domain(d3.range(0, max+calcStep, calcStep))
+ .range(colorbrewer);
+
+ points = points.sort(function(a, b) {
+ return a.beta - b.beta;
+ })
+ var labels_beta = [];
+ var abbr_labels_beta = [];
+ labels_beta = d3.range(0, max+calcStep, calcStep);
+ for (var i=0; i<9; i++){
+ labels_beta[i] = parseInt(labels_beta[i]);
+ abbr_labels_beta[i] = abbreviateNumber(labels_beta[i]);
+ }
+ var svg = d3.select("#legend1");
+
+ svg.append("g")
+ .attr("class", "legendLinear")
+ .attr("transform", "translate(10,15)");
+
+ var legend = d3.legendColor()
+ .labelFormat(d3.format(",.0f"))
+ .cells(9)
+ .labels([abbr_labels_beta[0],abbr_labels_beta[1],abbr_labels_beta[2],abbr_labels_beta[3],abbr_labels_beta[4],abbr_labels_beta[5],abbr_labels_beta[6],abbr_labels_beta[7],abbr_labels_beta[8]])
+ .title("1 / sigma")
+ .scale(colorScale);
+
+ svg.select(".legendLinear")
+ .call(legend);
+ } else {
+ var max = (d3.max(final_dataset,function(d){ return d.cost; }));
+ var min = (d3.min(final_dataset,function(d){ return d.cost; }));
- if (!gl) {
- alert('Unable to initialize WebGL. Your browser or machine may not support it.');
- return;
- }
+ var maxSize2 = (d3.max(final_dataset,function(d){ return d.beta; }));
+ var minSize2 = (d3.min(final_dataset,function(d){ return d.beta; }));
- max = (d3.max(final_dataset,function(d){ return d.cost; }));
- min = (d3.min(final_dataset,function(d){ return d.cost; }));
- // colors
- let colorbrewer = ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"];
- let calcStep = (max-min)/9;
- let colorScale = d3.scaleLinear()
- .domain(d3.range(min, max, calcStep))
- .range(colorbrewer);
+ var rscale2 = d3.scaleLinear()
+ .domain([minSize2, maxSize2])
+ .range([5,10]);
- points = points.sort(function(a, b) {
- return a.cost - b.cost;
- })
- var svg = d3.select("#legend2");
+ var colorbrewer = ["#ffffe5","#f7fcb9","#d9f0a3","#addd8e","#78c679","#41ab5d","#238443","#006837","#004529"];
+ var calcStep = (max-min)/9;
+ var colorScale = d3.scaleLinear()
+ .domain(d3.range(min, max, calcStep))
+ .range(colorbrewer);
+
+ points = points.sort(function(a, b) {
+ return a.cost - b.cost;
+ })
- svg.append("g")
- .attr("class", "legendLinear")
- .attr("transform", "translate(197,20)");
+ var labels_cost = [];
+ var abbr_labels_cost = [];
+ labels_cost = d3.range(min, max, calcStep);
+ for (var i=0; i<9; i++){
+ labels_cost[i] = labels_cost[i].toFixed(5);
+ abbr_labels_cost[i] = abbreviateNumber(labels_cost[i]);
+ }
- var legend = d3.legendColor()
- .labelFormat(d3.format(".4f"))
- .cells(9)
- .title("KLD(P||Q)")
- .scale(colorScale);
+ var svg = d3.select("#legend1");
- svg.select(".legendLinear")
- .call(legend);
+ svg.append("g")
+ .attr("class", "legendLinear")
+ .attr("transform", "translate(10,15)");
+
+ var legend = d3.legendColor()
+ .labelFormat(d3.format(",.5f"))
+ .cells(9)
+ .labels([abbr_labels_cost[0],abbr_labels_cost[1],abbr_labels_cost[2],abbr_labels_cost[3],abbr_labels_cost[4],abbr_labels_cost[5],abbr_labels_cost[6],abbr_labels_cost[7],abbr_labels_cost[8]])
+ .title("KLD(P||Q)")
+ .scale(colorScale);
+ svg.select(".legendLinear")
+ .call(legend);
+ }
+
let vertices = [];
let colors = [];
+ let sizes = new Float32Array(points.length);
+ let tempSort = -1;
+
+ for (var i=0; i1 to 0->2
let zeroToTwo = zeroToOne * 2.0;
let zeroToTwo2 = zeroToOne2 * 2.0;
@@ -2291,8 +2540,18 @@ function CosttSNE(points){
singleObj = 0.0;
vertices.push(singleObj);
}
+
for (var i=0; i2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-m