I am building an interactive graph app where the user would upload a data file. The app would then build the graph from the input file.
I am having problems with making the input work with the cytoscape . More specifically, the file dialog window does not pop up when I include the div. That is, the input button is not responsive unless I comment out the cytoscape .
Please see the code below. I guess, this is not cytoscape specific. However, I could not get to the bottom of this, so I am posting the complete instance of the problem.
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Test</title>
<script src="cytoscape.js"></script>
</head>
<style>
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<body>
<form name="uploadForm">
<div>
<input id="uploadInput" type="file" name="myFiles" multiple>
selected files: <span id="fileNum">0</span>;
total size: <span id="fileSize">0</span>
</div>
<div><input type="submit" value="Send file"></div>
</form>
<div>
<h1>This!</h1>
</div>
<div id="cy"></div>
<script>
function updateSize() {
let nBytes = 0,
oFiles = this.files,
nFiles = oFiles.length;
for (let nFileId = 0; nFileId < nFiles; nFileId++) {
nBytes += oFiles[nFileId].size;
}
let sOutput = nBytes + " bytes";
// optional code for multiples approximation
const aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
for (nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)";
}
// end of optional code
document.getElementById("fileNum").innerHTML = nFiles;
document.getElementById("fileSize").innerHTML = sOutput;
console.log("AAAA!")
}
document.getElementById("uploadInput").addEventListener("change", updateSize, false);
</script>
<script>
// https://blog.js.cytoscape.org/2016/05/24/getting-started/
var cy = cytoscape({
container: document.getElementById('cy'),
// ~~~~~~~~~~~~~~~~~~~
elements: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{
data: {
id: 'ab',
source: 'a',
target: 'b'
}
}],
// ~~~~~~~~~~~~~~~~~~~
style: [
{
selector: 'node',
style: {
shape: 'hexagon',
'background-color': 'red',
label: 'data(id)'
}
}]
});
cy.layout({
name: 'circle'
}).run();
</script>
</body>
</html>
It's related with the z-index of the divs. In your case, because you don't assign z-indexes to the divs and add cy div at the end, it is rendered on top, so you cannot interact with the buttons.
You can assign a z-index to cy div such as -1 to send it to the background:
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
z-index: -1;
}
But in this case you won't be able to interact with the top part of the cy canvas. A better solution is to change the top attribute to some value such as 250px so that cy canvas is started to be rendered below the buttons and texts:
#cy {
width: 100%;
height: 100%;
position: absolute;
top: 250px;
left: 0px;
}
Related
I'm trying to do a carousal like in this CodePen using React Hooks.
My present result is in this Sandbox: Click..!
The problems I'm facing are:
I don't know how to make that CSS animation effect of the letters coming and forming the text and scattering back as in the CodePen example.
I want to include the description part also which is in the description={data.desc}. Do I have to make the split again or any easy method to split both title and description together. I lag knowledge here.
My code is as below:
import React from "react";
export default function SlideCard(props) {
const { id, idx, title } = props;
function mainText() {
return (
<div style={{ border: "2px solid gold" }}>
<h1>{title}</h1>
</div>
);
}
//console.log(id);
function scatter() {
return (
<div>
{title.split("").map((item, index) => {
const style = {
position: "absolute",
top: Math.floor(Math.random() * 200) + "px",
left: Math.floor(Math.random() * 400) + "px",
zIndex: "initial",
color: "#AAA",
overflow: "hidden",
transition: "left 2s, top 2s, color 2s"
};
return (
<div key={index}>
<div className="scatter" style={style}>
{item}
</div>
</div>
);
})}
</div>
);
}
return (
<div>
<div>{idx === id && mainText()}</div>
{idx !== id && scatter()}
</div>
);
}
He's maintaining two same copies of each page data. One with class .position-data and one with .mutable. .position-data is hidden and only used for getting coordinates to bring back .mutable letters together.
Here is the simplified version of the CodePen example:
$(document).ready(function() {
assemble();
});
function scatter() {
for (var i = 0; i < 3; i++) {
var randLeft = Math.floor(Math.random() * $(window).width());
var randTop = Math.floor(Math.random() * $(window).height());
//randomly position .mutable elements
$(".mutable > span:eq(" + i + ")").animate({
left: randLeft,
top: randTop,
color: "#0005"
}, 2000, "easeInBack");
}
}
function assemble() {
for (var i = 0; i < 3; i++) {
$(".mutable > span:eq(" + i + ")").animate({
//get center position from .position data marked elements
left: $(".position-data > span:eq(" + i + ")").offset().left + "px",
top: $(".position-data > span:eq(" + i + ")").offset().top + "px",
color: "#000"
}, 2000, 'easeOutBounce');
}
}
span {
font-size: 30px;
}
.position-data {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
opacity: 0.4;
color: green;
}
.mutable span {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div class="position-data">
<span>a</span>
<span>b</span>
<span>c</span>
</div>
<div class="mutable shadowed">
<span>a</span>
<span>b</span>
<span>c</span>
</div>
<button onclick="scatter()">Scatter</button>
<button onclick="assemble()">Assemble</button>
I want to position the actively displaying Text container to the centre of the carousal.
The actively displaying text container is marked with .mutable class which has following css:
.mutable {
position: absolute;
overflow: hidden;
display: inline-block;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
So they all have full size of the document body. Using javascript function arrangeCurrentPage() in codepen they are set with coordinates such that they look centered.
I don't know how to make that transition effect of the letters coming and forming the text and scattering back as in the CodePen example.
Refer to above simplified code. Use the buttons to see the effects separately. All letter elements are put in a div with class .mutable. All letters are position: absolute; so they are free to move anywhere. In javascript function scatter() I am simply assigning top and left properties to random coordinates. With animation effect they scatter smoothly. In codepen he is achieving the animation effect using css transition transition: left 2s, top 2s, color 2s;
To bring them back simply us css selector nth-child .position-data > span:eq(n) to get corresponding coordinates of the character. Refer javascript function assemble().
I want to include the description part also which is in the description={data.desc}. Do I have to make the split again or any easy method to split both title and description together. I lag knowledge here.
As title and description will be displayed separately with separate presentation styles. Code will be cleaner if you keep split versions of them separately. You can create utility methods like split(text), scramble(array), arrange(array)and use it for both like cramble(titleArray)and scramble(descArray).
If we use 'position:relative' on letters we don't have to maintain two copies of same data:
<!DOCTYPE html>
<head>
<title>Document</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$(document).ready(function() {
assemble();
});
function randomX() {
return Math.floor(Math.random() * $(window).width() * 0.7) - $(window).width() * 0.25;
}
function randomY() {
return Math.floor(Math.random() * $(window).height() * 0.7) - $(window).height() * 0.25;
}
function scatter() {
for (var i = 0; i < 3; i++) {
$(".mutable > span:eq(" + i + ")").animate({
left: randomX(),
top: randomY(),
color: "#f118"
}, 2000, "easeInBack");
}
}
function assemble() {
for (var i = 0; i < 3; i++) {
$(".mutable > span:eq(" + i + ")").animate({
left: '0px',
top: '0px',
color: "#000"
}, 2000, 'easeOutBounce');
}
}
</script>
<style>
span {
font-size: 30px;
}
.mutable {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.mutable span {
position: relative; /* <--- */
}
</style>
</head>
<body>
<div class="mutable">
<span>a</span>
<span>b</span>
<span>c</span>
</div>
<button onclick="scatter()">Scatter</button>
<button onclick="assemble()">Assemble</button>
</body>
</html>
The sandbox demo you want to emulate is using an animation they call Alphabet Soup. After a quick google search, I found an npm package that can help you implement this in your react component: https://github.com/OrigenStudio/react-alphabet-soup.
Why reinvent the wheel?
So I'm trying to make a prototype for a little project I'm trying to work on, were a div moves 10 pixels to right every second. I've tried to look up how to do similar things like I want to do, but I can't make it work.
I want to make it with JavaScript, but when JavaScript is executed, the squareStyleTop value just add "100px", so it just increases and after a few seconds the value looks like this:
This is what I've been able to do so far:
//setTimeout(function(){ alert("Hello"); }, 3000);
var squareStyle = document.getElementById("sjuku").style;
var squareStyleTop = squareStyle.top
function TingLing() {
squareStyleTop += "10px";
console.log("squareStylTop is ", squareStyleTop)
}
setInterval(TingLing, 1000);
#denneYes {
position: absolute;
left: 1300px;
}
#sjuku {
height: 2em;
width: 2em;
background-color: #00ffff;
position: absolute;
}
Go bak
<div id="sjuku"></div>
let squareStyleTop = 10;
function TingLing (){
squareStyleTop += 10;
document.getElementById("sjuku").style.top = squareStyleTop + "px";
console.log("squareStylTop is ", squareStyleTop)
}
setInterval(TingLing, 1000);
#denneYes { position: absolute;
left: 1300px;
}
#sjuku {
height: 2em;
width: 2em;
background-color: #00ffff;
position: absolute;
}
<html>
<head>
<title>Indax</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
Go bak
<div id="sjuku"></div>
<script src="main.js"></script>
</body>
</html>
Try changing following:
function TingLing (){
squareStyleTop += "10px";
console.log("squareStylTop is ", squareStyleTop)
}
to
function TingLing (){
squareStyleTop = ( parseInt( squareStyleTop == null ? 0 : squareStyleTop ) + 10 ) + 'px';
console.log("squareStylTop is ", squareStyleTop)
}
Essentially I am converting '10px' to 10 so I can add 10 to it and afterwards I am concatenating it 'px'
Make sure to set an initial top value in your html file. This would be my approach of doing it.
const square = document.getElementById("sjuku");
const increment = 10;
setInterval(() => {
square.style.top = parseInt(square.style.top, 10) + increment + "px";
console.log("squareStylTop is", square.style.top);
}, 1000);
#denneYes {
position: absolute;
left: 1300px;
}
#sjuku {
height: 2em;
width: 2em;
background-color: #00ffff;
position: absolute;
}
<html>
<head>
<title>Indax</title>
<link rel="stylesheet" href="index.css" />
</head>
<body>
<a
href="C:\Users\05bawmud\Documents\Mappe for organisering\Nettside2\Index\index.html"
id="denneYes"
>Go bak</a
>
<div id="sjuku" style="top: 0"></div>
<script src="main.js"></script>
</body>
</html>
I want to display a loading spinner while a huge graph is loaded and layouted in Cytoscape JS. But the loading spinner disappears even though the layout is not finished. I am wondering if there is a way to listen to a layout finish and show the spinner until the final layout is reached ?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/2.7.14/cytoscape.js"></script>
<title></title>
<style media="screen">
#cy {
position: absolute;
width:100%;
height:100%;
/*height:500px;*/
z-index: 0;
margin-left: auto;
margin-right: auto;
}
#loading {
position: absolute;
background: #ffffff;
display: block;
left: 0;
top: 50%;
width: 100%;
text-align: center;
margin-top: -0.5em;
font-size: 2em;
color: #000;
}
#loading.loaded {
display: none;
}
</style>
</head>
<body>
<div id="cy">
</div>
<div id="loading">
<span class="fa fa-refresh fa-spin"></span>
</div>
<script type="text/javascript">
$(document).ready(function(){
// Create random JSON object
var maximum = 500;
var minimum = 1;
function getRandNumber(){
var min = 1;
var max = 1000;
var randNumber = Math.floor(Math.random() * (max - min + 1)) + min;
return randNumber;
}
nodes = [];
geneIds = [];
edges = [];
for(var i = 0; i < 2000; i++){
var source = getRandNumber();
var target = getRandNumber();
edges.push({"data": {"id":i.toString(),"source":source.toString(),"target":target.toString()}});
if ($.inArray(source, geneIds) === -1) {
nodes.push({"data": {"id":source.toString(),"name":source.toString()}});
geneIds.push(source);
}
if ($.inArray(target, geneIds) === -1) {
nodes.push({"data":{"id":target.toString(),"name":target.toString()}});
geneIds.push(target);
}
}
var networkData = {"nodes":nodes,"edges":edges};
// console.log(networkData);
///////////////// Create the network
var coseLayoutParams = {
name: 'cose',
// padding: 10,
randomize: false,
};
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
// elements: networkData,
minZoom: 0.1,
// maxZoom: 10,
wheelSensitivity: 0.2,
style: [
{
selector: 'node',
style: {
'content': 'data(name)',
'text-valign': 'center',
'text-halign': 'center',
'font-size': 8
}
}],
layout: coseLayoutParams
});
cy.add(networkData);
var layout = cy.makeLayout(coseLayoutParams);
layout.run();
$("#loading").addClass("loaded");
});
</script>
</body>
</html>
You can add a listener to your layout object that waits for 'layoutstop' event to be fired:
layout.on('layoutstop', function() {
//... unload spinner here
});
see here: http://js.cytoscape.org/#layout.on
and here: https://github.com/cytoscape/cytoscape.js/blob/master/documentation/md/events.md
or, you can specify a callback function in layout options, such as
var coseLayoutParams = {
name: 'cose',
// padding: 10,
randomize: false,
// Called on `layoutstop`
stop: function() {
//... unload spinner here
},
};
see here: http://js.cytoscape.org/#layouts/cose
Good morning everyone,
I seem to be having a slight problem. I want a div to overlay another div(i.e. be on top) but zIndex is not working. I suspect the cause is the display: inline-block but I need to keep it so that the webpage is displayed properly. How do I make the div overlay the other one?
Here is the jsfiddle explaining the problem:
http://jsfiddle.net/Yf7zD/
Or the code right here:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.9/jquery-ui.min.js"></script>
<script type="text/javascript" src="javascript/cookies.js"></script>
<style>
#gameTable {
font-size: 0;
width: 840px;
height: 240px;
margin-top: 20px;
margin-left: 78px;
position: relative;
}
.iamdroppable {
display: inline-block;
margin: 0;
padding: 0;
border: 3px solid #FFF;
}
</style>
</head>
<body style="background-color: black;">
<div id="container" style="position:relative; border: solid 3px red;">
<div id="gameTable"><p>GameTable</p>
</div>
</div>
</body>
<script>
$(document).ready(function(e) {
var myId;
for(vertical = 0; vertical < 3; vertical++) {
for(horizontal = 1; horizontal <= 12; horizontal++) { //Outer Numbers
if(vertical == 0)
myId = horizontal * 3;
else if(vertical == 1)
myId = horizontal * 3 - 1;
else
myId = horizontal * 3 - 2;
$('<div>', {//Normal numbers
class: 'iamdroppable',
id: '' + myId,
width: '62px',
height: '78px',
}).appendTo('#gameTable');
}
}
$('<div>', {//Quads
class: 'iamdroppable',
id: '1000',
top: '-100px',
width: '100px',
height: '200px',
zIndex: '1000',
position: 'absolute',
}).appendTo('#container');
});
</script>
</html>
Thanks!
var div = $('<div>', {//Quads
class: 'iamdroppable',
id: '1000',
top: '-100px',
width: '100px',
height: '200px',
zIndex: '1000',
position: 'absolute',
}).appendTo('#container');
});
$('body').append(div);
You were adding the CSS styles as attributes, they should all be within the style property:
$(document).ready(function (e) {
var myId;
for (vertical = 0; vertical < 3; vertical++) {
for (horizontal = 1; horizontal <= 12; horizontal++) { //Outer Numbers
if (vertical === 0) myId = horizontal * 3;
else if (vertical == 1) myId = horizontal * 3 - 1;
else myId = horizontal * 3 - 2;
$('<div>', { //Normal numbers
class: 'iamdroppable',
id: '' + myId,
style: 'width:62px;height:78px;'
}).appendTo('#gameTable');
}
}
$('<div>', { //Quads
class: 'iamdroppable',
id: '1000',
style: 'top:-100px;width:100px;height:200px;z-index:1000;position:absolute;'
}).appendTo('#container');
});
On another note, where you're doing this comparison: if (vertical == 0) you should use three === like this: if (vertical === 0)
I am attempting to use Javascript to position some of my elements on the screen/window. I am doing this to make sure that what ever the dimensions of the users screen, my elements will always be in the centre.
I know that padding & margin can also achieve this, but I am using a custom movement script called raphael.js, & in order to move my elements I need to set out my elements absolutely (its a custom home page, where you click blocks(that are links) & they fly off the screen).
My javascript function to move my elements fails to move my elements. Any suggestions on how to position my elements using javascript would be really helpful.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="dropDownMenu.js"></script>
<title></title>
<script src="javascript/raphael.js"></script> <!-- I am using a custom drawing/moving script which is why I cant put the img(id=bkImg) inside the div element -->
<script LANGUAGE="JavaScript" type = "text/javascript">
<!--
function getScreenSize()
{
var res = {"width": 630, "height": 460};
if (document.body)
{
if (document.body.offsetWidth) res["width"] = document.body.offsetWidth;
if (document.body.offsetHeight) res["height"] = document.body.offsetHeight;
}
if (window.innerWidth) res["width"] = window.innerWidth;
if (window.innerHeight) res["height"] = window.innerHeight;
alert( res["width"] );
alert( res["height"] );
return res;
}
function positionBlocksAccordingToScreenSize()
{
// The problem is that the blocks position does not change but they should?
var scrDim = getScreenSize();
var BK_WIDTH = 800;
var BK_HEIGHT = 600;
var X_OFFSET = (scrDim["width"]-BK_WIDTH) / 2; // variable that changes according to the width of the screen
var BLOCK_POS_X = [160, 80, 280, 20, 200, 400];
var BLOCK_POS_Y = [26, 203, 203, 380, 380, 380];
for ( var i=1; i<=5; i++ )
{
//document.getElementById("block"+i).setAttribute( "offsetLeft", X_OFFSET + BLOCK_POS_X[i] ); // doesn't work
//document.getElementById("block"+i).setAttribute( "offsetTop", BLOCK_POS_Y[i] ); // doesn't work
document.getElementById("block"+i).style.left = X_OFFSET + BLOCK_POS_X[i]; // doesn't work
document.getElementById("block"+i).style.top = BLOCK_POS_Y[i]; // doesn't work
}
}
-->
</script>
<style type="text/css" media="all">
<!--
#import url("styles.css");
#blockMenu { z-index: -5; padding: 0; position: absolute; width: 800px;
height: 600px; /*background-image: url("images/menuBk.png");*/ }
#bkImg { z-index: -5; position: relative; }
#block1 { z-index: 60; position: absolute; top: 26px; left: 160px; margin: 0; padding: 0; }
#block2 { z-index: 50; position: absolute; top: 203px; left: 80px; margin: 0; padding: 0; }
#block3 { z-index: 40; position: absolute; top: 203px; left: 280px; margin: 0; padding: 0; }
#block4 { z-index: 30; position: absolute; top: 380px; left: 20px; margin: 0; padding: 0; }
#block5 { z-index: 20; position: absolute; top: 380px; left: 200px; margin: 0; padding: 0; }
#block6 { z-index: 10; position: absolute; top: 380px; left: 400px; margin: 0; padding: 0; }
-->
</style>
</head>
<body onload="positionBlocksAccordingToScreenSize()" style="margin-top: 10%; text-align: center; margin-bottom: 10%; position: relative;">
<img id="bkImg" src="images/menuBk.png" width="800px;" height="600px" alt=""/>
<!-- The above image should be displayed behind the below div. I am using the raphael.js movement script, so I cannot place
this image inside the div, because it will get erased when I call raphael.clear(); -->
<div id="blockMenu">
<div id="block1"><img src="images/block1.png" width="200" height="200"/></div>
<div id="block2"><img src="images/block2.png" width="200" height="200"/></div>
<div id="block3"><img src="images/block3.png" width="200" height="200"/></div>
<div id="block4"><img src="images/block4.png" width="200" height="200"/></div>
<div id="block5"><img src="images/block5.png" width="200" height="200"/></div>
<div id="block6"><img src="images/block6.png" width="200" height="200"/></div>
</div>
</body>
</html>
You're not setting the left and top properties correctly, you need to add the unit e.g 'px' for pixels.
document.getElementById("block"+i).style.left = X_OFFSET + BLOCK_POS_X[i] + 'px';
document.getElementById("block"+i).style.top = BLOCK_POS_Y[i] + 'px';
"Would you be able to suggest a line of jQuery code that could place my elements correctly?"
The following code uses jQuery and will center an absolutely positioned element on load and on window resize.
http://jsfiddle.net/Fu3L6/
HTML...
<div id="element">Test</div>
CSS...
#element {
position: absolute;
background-color: red;
width: 200px;
}
jQuery...
$(document).ready(function () {
centerInViewport('#element');
$(window).resize(function () {
centerInViewport('#element');
});
});
function centerInViewport(e) {
$docWidth = $(document).width();
$elWidth = $(e).width();
$offset = ($docWidth - $elWidth) / 2;
$(e).css("marginLeft", $offset + "px");
}