StackGenVis: Alignment of Data, Algorithms, and Models for Stacking Ensemble Learning Using Performance Metrics
https://doi.org/10.1109/TVCG.2020.3030352
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.
246 lines
6.2 KiB
246 lines
6.2 KiB
4 years ago
|
import * as domUtils from "../utils/domUtils.js";
|
||
|
import * as is from "../utils/is.js";
|
||
|
import raf from "../utils/raf.js";
|
||
|
import { getStringOptionResult } from "../utils/rect.js";
|
||
|
import { getWindow } from "../utils/window.js";
|
||
|
|
||
|
function install(scope) {
|
||
|
const {
|
||
|
defaults,
|
||
|
actions
|
||
|
} = scope;
|
||
|
scope.autoScroll = autoScroll;
|
||
|
|
||
|
autoScroll.now = () => scope.now();
|
||
|
|
||
|
actions.eventTypes.push('autoscroll');
|
||
|
defaults.perAction.autoScroll = autoScroll.defaults;
|
||
|
}
|
||
|
|
||
|
const autoScroll = {
|
||
|
defaults: {
|
||
|
enabled: false,
|
||
|
margin: 60,
|
||
|
// the item that is scrolled (Window or HTMLElement)
|
||
|
container: null,
|
||
|
// the scroll speed in pixels per second
|
||
|
speed: 300
|
||
|
},
|
||
|
now: Date.now,
|
||
|
interaction: null,
|
||
|
i: 0,
|
||
|
// the handle returned by window.setInterval
|
||
|
x: 0,
|
||
|
y: 0,
|
||
|
// Direction each pulse is to scroll in
|
||
|
isScrolling: false,
|
||
|
prevTime: 0,
|
||
|
margin: 0,
|
||
|
speed: 0,
|
||
|
|
||
|
start(interaction) {
|
||
|
autoScroll.isScrolling = true;
|
||
|
raf.cancel(autoScroll.i);
|
||
|
interaction.autoScroll = autoScroll;
|
||
|
autoScroll.interaction = interaction;
|
||
|
autoScroll.prevTime = autoScroll.now();
|
||
|
autoScroll.i = raf.request(autoScroll.scroll);
|
||
|
},
|
||
|
|
||
|
stop() {
|
||
|
autoScroll.isScrolling = false;
|
||
|
|
||
|
if (autoScroll.interaction) {
|
||
|
autoScroll.interaction.autoScroll = null;
|
||
|
}
|
||
|
|
||
|
raf.cancel(autoScroll.i);
|
||
|
},
|
||
|
|
||
|
// scroll the window by the values in scroll.x/y
|
||
|
scroll() {
|
||
|
const {
|
||
|
interaction
|
||
|
} = autoScroll;
|
||
|
const {
|
||
|
interactable,
|
||
|
element
|
||
|
} = interaction;
|
||
|
const actionName = interaction.prepared.name;
|
||
|
const options = interactable.options[actionName].autoScroll;
|
||
|
const container = getContainer(options.container, interactable, element);
|
||
|
const now = autoScroll.now(); // change in time in seconds
|
||
|
|
||
|
const dt = (now - autoScroll.prevTime) / 1000; // displacement
|
||
|
|
||
|
const s = options.speed * dt;
|
||
|
|
||
|
if (s >= 1) {
|
||
|
const scrollBy = {
|
||
|
x: autoScroll.x * s,
|
||
|
y: autoScroll.y * s
|
||
|
};
|
||
|
|
||
|
if (scrollBy.x || scrollBy.y) {
|
||
|
const prevScroll = getScroll(container);
|
||
|
|
||
|
if (is.window(container)) {
|
||
|
container.scrollBy(scrollBy.x, scrollBy.y);
|
||
|
} else if (container) {
|
||
|
container.scrollLeft += scrollBy.x;
|
||
|
container.scrollTop += scrollBy.y;
|
||
|
}
|
||
|
|
||
|
const curScroll = getScroll(container);
|
||
|
const delta = {
|
||
|
x: curScroll.x - prevScroll.x,
|
||
|
y: curScroll.y - prevScroll.y
|
||
|
};
|
||
|
|
||
|
if (delta.x || delta.y) {
|
||
|
interactable.fire({
|
||
|
type: 'autoscroll',
|
||
|
target: element,
|
||
|
interactable,
|
||
|
delta,
|
||
|
interaction,
|
||
|
container
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
autoScroll.prevTime = now;
|
||
|
}
|
||
|
|
||
|
if (autoScroll.isScrolling) {
|
||
|
raf.cancel(autoScroll.i);
|
||
|
autoScroll.i = raf.request(autoScroll.scroll);
|
||
|
}
|
||
|
},
|
||
|
|
||
|
check(interactable, actionName) {
|
||
|
const options = interactable.options;
|
||
|
return options[actionName].autoScroll && options[actionName].autoScroll.enabled;
|
||
|
},
|
||
|
|
||
|
onInteractionMove({
|
||
|
interaction,
|
||
|
pointer
|
||
|
}) {
|
||
|
if (!(interaction.interacting() && autoScroll.check(interaction.interactable, interaction.prepared.name))) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (interaction.simulation) {
|
||
|
autoScroll.x = autoScroll.y = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let top;
|
||
|
let right;
|
||
|
let bottom;
|
||
|
let left;
|
||
|
const {
|
||
|
interactable,
|
||
|
element
|
||
|
} = interaction;
|
||
|
const actionName = interaction.prepared.name;
|
||
|
const options = interactable.options[actionName].autoScroll;
|
||
|
const container = getContainer(options.container, interactable, element);
|
||
|
|
||
|
if (is.window(container)) {
|
||
|
left = pointer.clientX < autoScroll.margin;
|
||
|
top = pointer.clientY < autoScroll.margin;
|
||
|
right = pointer.clientX > container.innerWidth - autoScroll.margin;
|
||
|
bottom = pointer.clientY > container.innerHeight - autoScroll.margin;
|
||
|
} else {
|
||
|
const rect = domUtils.getElementClientRect(container);
|
||
|
left = pointer.clientX < rect.left + autoScroll.margin;
|
||
|
top = pointer.clientY < rect.top + autoScroll.margin;
|
||
|
right = pointer.clientX > rect.right - autoScroll.margin;
|
||
|
bottom = pointer.clientY > rect.bottom - autoScroll.margin;
|
||
|
}
|
||
|
|
||
|
autoScroll.x = right ? 1 : left ? -1 : 0;
|
||
|
autoScroll.y = bottom ? 1 : top ? -1 : 0;
|
||
|
|
||
|
if (!autoScroll.isScrolling) {
|
||
|
// set the autoScroll properties to those of the target
|
||
|
autoScroll.margin = options.margin;
|
||
|
autoScroll.speed = options.speed;
|
||
|
autoScroll.start(interaction);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
};
|
||
|
export function getContainer(value, interactable, element) {
|
||
|
return (is.string(value) ? getStringOptionResult(value, interactable, element) : value) || getWindow(element);
|
||
|
}
|
||
|
export function getScroll(container) {
|
||
|
if (is.window(container)) {
|
||
|
container = window.document.body;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
x: container.scrollLeft,
|
||
|
y: container.scrollTop
|
||
|
};
|
||
|
}
|
||
|
export function getScrollSize(container) {
|
||
|
if (is.window(container)) {
|
||
|
container = window.document.body;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
x: container.scrollWidth,
|
||
|
y: container.scrollHeight
|
||
|
};
|
||
|
}
|
||
|
export function getScrollSizeDelta({
|
||
|
interaction,
|
||
|
element
|
||
|
}, func) {
|
||
|
const scrollOptions = interaction && interaction.interactable.options[interaction.prepared.name].autoScroll;
|
||
|
|
||
|
if (!scrollOptions || !scrollOptions.enabled) {
|
||
|
func();
|
||
|
return {
|
||
|
x: 0,
|
||
|
y: 0
|
||
|
};
|
||
|
}
|
||
|
|
||
|
const scrollContainer = getContainer(scrollOptions.container, interaction.interactable, element);
|
||
|
const prevSize = getScroll(scrollContainer);
|
||
|
func();
|
||
|
const curSize = getScroll(scrollContainer);
|
||
|
return {
|
||
|
x: curSize.x - prevSize.x,
|
||
|
y: curSize.y - prevSize.y
|
||
|
};
|
||
|
}
|
||
|
const autoScrollPlugin = {
|
||
|
id: 'auto-scroll',
|
||
|
install,
|
||
|
listeners: {
|
||
|
'interactions:new': ({
|
||
|
interaction
|
||
|
}) => {
|
||
|
interaction.autoScroll = null;
|
||
|
},
|
||
|
'interactions:destroy': ({
|
||
|
interaction
|
||
|
}) => {
|
||
|
interaction.autoScroll = null;
|
||
|
autoScroll.stop();
|
||
|
|
||
|
if (autoScroll.interaction) {
|
||
|
autoScroll.interaction = null;
|
||
|
}
|
||
|
},
|
||
|
'interactions:stop': autoScroll.stop,
|
||
|
'interactions:action-move': arg => autoScroll.onInteractionMove(arg)
|
||
|
}
|
||
|
};
|
||
|
export default autoScrollPlugin;
|
||
|
//# sourceMappingURL=index.js.map
|