t-viSNE: Interactive Assessment and Interpretation of t-SNE Projections
https://doi.org/10.1109/TVCG.2020.2986996
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
5.0 KiB
107 lines
5.0 KiB
/*
|
|
* Copyright (C) 2015 Jose F. Maldonado
|
|
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
|
|
* If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
// Verify if the namespace is not already defined.
|
|
if(typeof SaVaGe !== 'object') SaVaGe = {};
|
|
|
|
/**
|
|
* Creates a SVG element representing a toggle switch.
|
|
*
|
|
* The parameter must be an object with the following attributes:
|
|
* 'container' (a selector of the element where the element must be appended),
|
|
* 'value' (a boolean indicating the initial value of the switch, by default 'false'),
|
|
* 'height' (a number indicating the height, in pixels, of the element, by default 50),
|
|
* 'width' (a number indicating the width, in pixels, of the element, by default 80),
|
|
* 'radius' (a number indicating the radius of the lever),
|
|
* 'border' (a number indicating the width, in pixels, the distance between the element background and the switch's button, by default 5),
|
|
* 'duration' (a number indicating the number of milliseconds that the toggle animation must last, by default 250),
|
|
* 'colors' (an object with the attributes 'backLeft', 'foreLeft', 'backRight' and 'foreRight' indicating the colors of the element in each state) and
|
|
* 'onChange' (a callback function which is invoked every time that the element is clicked).
|
|
*
|
|
* The object returned by this function contains the methods:
|
|
* 'svg', and instance of the SVG object created with D3.js,
|
|
* 'getValue()', for get the current state of the switch,
|
|
* 'serValue(newVal)', for change the state of the switch and
|
|
* 'remove()', for remove the element from the document.
|
|
*
|
|
* @param {object} params An collection of values for customize the element.
|
|
* @returns {object} An object with methods for manipulate the element.
|
|
*/
|
|
SaVaGe.ToggleSwitch = function(params) {
|
|
// Verify parameters.
|
|
if(typeof params !== 'object') params = {};
|
|
if(typeof params.container !== 'string') params.container = "body";
|
|
if(typeof params.value !== 'boolean') params.value = false;
|
|
if(typeof params.height !== 'number') params.height = 50;
|
|
if(typeof params.width !== 'number' || params.width < params.height) params.width = parseInt(params.height*1.6, 10);
|
|
if(typeof params.radius !== 'number') params.radius = params.height/2 - 4;
|
|
if(typeof params.duration !== 'number') params.duration = 250;
|
|
if(typeof params.colors !== 'object') params.colors = {};
|
|
if(params.colors.backLeft === undefined) params.colors.backLeft = "lightgray";
|
|
if(params.colors.foreLeft === undefined) params.colors.foreLeft = "white";
|
|
if(params.colors.backRight === undefined) params.colors.backRight = "#88f";
|
|
if(params.colors.foreRight === undefined) params.colors.foreRight = "white";
|
|
|
|
// Define internal variables.
|
|
var atRight = params.value;
|
|
|
|
// Calculate SVG dimensions and position offset.
|
|
var svgHeight = params.height;
|
|
var svgWidth = params.width;
|
|
var offsetX = 0;
|
|
var offsetY = 0;
|
|
if(params.radius*2 > params.height) {
|
|
svgHeight = params.radius*2;
|
|
svgWidth = parseInt(params.width + (params.radius*2 - params.height), 10);
|
|
offsetX = parseInt((svgWidth - params.width)/2, 10);
|
|
offsetY = parseInt((svgWidth - params.width)/2, 10);
|
|
}
|
|
|
|
// Create widget.
|
|
var svg = d3.select(params.container).append("svg")
|
|
.attr("width", svgWidth)
|
|
.attr("height", svgHeight)
|
|
.style("cursor", "pointer");
|
|
var rect = svg.append("rect")
|
|
.attr("x", offsetX)
|
|
.attr("y", offsetY)
|
|
.attr("rx", params.height/2)
|
|
.attr("ry", params.height/2)
|
|
.style("fill", atRight? params.colors.backRight : params.colors.backLeft)
|
|
.attr("width", params.width)
|
|
.attr("height", params.height);
|
|
var circle = svg.append("circle")
|
|
.attr("cx", (atRight? (params.width-params.height/2) : (params.height/2)) + offsetX)
|
|
.attr("cy", params.height/2 + offsetY)
|
|
.attr("r", params.radius)
|
|
.style("fill", atRight? params.colors.foreRight : params.colors.foreLeft);
|
|
|
|
// Define internal functions.
|
|
var setAtRight = function(newValue) {
|
|
atRight = newValue;
|
|
circle.transition().duration(params.duration)
|
|
.attr("cx", (atRight? (params.width-params.height/2) : (params.height/2)) + offsetX)
|
|
.style("fill", atRight? params.colors.foreRight : params.colors.foreLeft);
|
|
rect.transition().duration(params.duration).style("fill", atRight? params.colors.backRight : params.colors.backLeft);
|
|
|
|
};
|
|
|
|
// Define result's object.
|
|
var res = {
|
|
'svg' : svg,
|
|
'getValue': function() { return atRight; },
|
|
'setValue': setAtRight,
|
|
'remove': function() { svg.remove(); }
|
|
};
|
|
|
|
// Define click listener.
|
|
svg.on('click', function(data, index){
|
|
setAtRight(!atRight);
|
|
if(typeof params.onChange === 'function') params.onChange(res);
|
|
});
|
|
|
|
return res;
|
|
};
|
|
|