Transcriptic Node Graph
How do I make an transcriptic node graph?
What is a transcriptic node graph? How do you make a transcriptic node graph? This script and codes were developed by Alexander Hadik on 30 December 2022, Friday.
Transcriptic Node Graph - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Transcriptic Node Graph</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="wrapper"> <div class="controls wrapper__controls"> <button class="controls__button" onClick="reset()">Reset</button> </div> <svg id="logo_outline" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 218.8 195.3"> <defs> <linearGradient id="transcripticOrange"> <stop offset="0%" stop-color="#ed9a42"/> <stop offset="100%" stop-color="#f8c64b"/> </linearGradient> </defs> <style type="text/css"> .st0{fill-rule:evenodd;clip-rule:evenodd;fill:none;stroke:none;stroke-width:0.25;stroke-miterlimit:10;} </style> <rect id="overlay-linear" width="100%" height="100%" clip-path="url(#graphMask)" fill="url(#transcripticOrange)" /> <path class="st0" id="divide_outer" d="M137.2,12.7c-3.8,1.9-7.8,3.8-12.3,5.2c-4.3,1.4-9.1,2.3-14.7,2.4c-5.3,0.2-10.9-0.8-15.9-2.3 c-4.7-1.4-8.8-3.4-12.7-5.4C64.9,3.4,46.9-4.5,27.9,3.4C10.8,10.6-0.8,28.3,0,46.9c0.8,18.4,12.5,33.9,28.7,40.2 c18.8,7.4,36.4-0.4,52.8-9.7c3.9-1.9,8-3.9,12.7-5.3c5.1-1.6,10.6-2.6,15.9-2.3c5.6,0.1,10.4,1.1,14.7,2.4c4.5,1.4,8.5,3.3,12.3,5.2 c16.4,9.2,34,17,52.8,9.7c16.2-6.4,27.9-21.8,28.7-40.2c0.8-18.6-10.6-36.3-27.8-43.4c-5.5-2.3-10.9-3.3-16.3-3.3 C161.6,0.2,149.1,6.1,137.2,12.7"/> <path class="st0" id="divide_inner" d="M158.3,45.2c0-8.7,7.1-15.7,15.7-15.7c8.7,0,15.7,7,15.7,15.7c0,8.7-7,15.7-15.7,15.7 C165.4,60.9,158.3,53.9,158.3,45.2"/> <path id="single" class="st0" d="M70,155.9c0,21.7,17.6,39.4,39.4,39.4c21.7,0,39.4-17.6,39.4-39.4c0-21.7-17.6-39.4-39.4-39.4 C87.6,116.6,70,134.2,70,155.9"/> </svg>
</div> <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
Transcriptic Node Graph - Script Codes CSS Codes
.wrapper { position: relative; width: 700px; margin-left: auto; margin-right: auto;
}
.wrapper__controls { margin-bottom: 1em;
}
.controls { width: 100%; padding: 10px; background: #515a67;
}
.controls__button { height: 30px; background: #c1c7cd; color: #515a67; font-weight: 600; font-size: 1em; outline: none; border: none;
}
body { background-color: #0E202E;
}
Transcriptic Node Graph - Script Codes JS Codes
'use strict';
var svg = d3.select("#logo_outline");
var clipPath = svg.insert('clipPath', ':first-child').attr('id', 'graphMask');
var divide_outer = d3.select('#divide_outer');
var divide_inner = d3.select('#divide_inner');
var single = d3.select('#single');
// ----- PARAMETERS -----
var searchRadius = 17;
var maxLength = 32;
var minLength = 15;
var multiplier = 4;
var upperCircleBound = [109.5, -30];
var lowerCircleBound = [109.5, 120];
var circleBoundRadius = 50;
var nucleus = [174, 45.25];
var singleCell = [109.5, 156];
var singleCellRadius = 39.5;
var nucleusRadius = 15.5;
var bigBlobWidth = divide_outer.node().getBBox().width;
var bigBlobHeight = divide_outer.node().getBBox().height;
var pathAnimationScalar = .15;
// ----- GLOBAL STORES -----
var nodeLibrary = [];
var terminalNodes = [];
// ----- DRAWING -----
function drawLine(root, dest) { var angle = getEdgeAngle(root, dest); var angleStart = angle + (Math.random() - .5) * (Math.PI / 4); var length = euclideanDist(root, dest); var path = clipPath.append('rect').attr('x', root[0]).attr('y', root[1]).attr('width', 1).attr('height', .5).attr('transform', 'rotate(' + angleStart * (180 / Math.PI) + ', ' + root[0] + ', ' + root[1] + ')'); return new Promise(function (resolve) { path.transition().duration(length / pathAnimationScalar).attr('width', length).attr('transform', 'rotate(' + angle * (180 / Math.PI) + ', ' + root[0] + ', ' + root[1] + ')').on('end', resolve); });
}
function drawNode(coordinate) { return new Promise(function (resolve) { clipPath.append('circle').attr('cx', coordinate[0]).attr('cy', coordinate[1]).attr('r', .1).attr('fill', 'black').transition().duration(100).attr('r', 1).on('end', resolve); });
}
function extendInDirection(coord, angle, immediateCallback) { var length = (maxLength - minLength) * Math.random() + minLength; var yLength = Math.sin(angle) * length; var xLength = Math.cos(angle) * length; var x2 = coord[0] + xLength; var y2 = coord[1] + yLength; if (isPathWithinBounds(coord, [x2, y2])) { immediateCallback([x2, y2]); return drawLine(coord, [x2, y2]).then(function () { return [x2, y2]; }); } return false;
}
// ----- DRAWING UTILITIES -----
function getRandomPointOnPath(path, maxLength, minLength) { var length = path.node().getTotalLength(); var randomLength = Math.random() * length; maxLength = maxLength || length; minLength = minLength == undefined ? 0 : minLength; while (!(randomLength < maxLength) || !(randomLength > minLength)) { randomLength = Math.random() * length; } return path.node().getPointAtLength(randomLength);
}
//START HERE MAKING SURE THIS WORKS THE WAY YOU THINK IT DOES
function getTopAngle(coords, center) { var angles = []; for (var _iterator = coords, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref; if (_isArray) { if (_i >= _iterator.length) break; _ref = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref = _i.value; } var coord = _ref; var edgeAngle = getEdgeAngle(center, coord); if (edgeAngle < 0) { edgeAngle = edgeAngle + Math.PI; } angles.push(edgeAngle); } angles.sort(); var prevAngle = angles.pop(); var topAngle = undefined; if (angles.length === 0) { return undefined; } if (angles.length === 1) { if (angles[0] - prevAngle > Math.PI) { return { innerAngle: angles[0] - prevAngle, baseAngle: prevAngle }; } return { innerAngle: 2 * Math.PI - (angles[0] - prevAngle), baseAngle: angles[0] }; } for (var _iterator2 = angles, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) { var _ref2; if (_isArray2) { if (_i2 >= _iterator2.length) break; _ref2 = _iterator2[_i2++]; } else { _i2 = _iterator2.next(); if (_i2.done) break; _ref2 = _i2.value; } var angle = _ref2; var angleDiff = angle - prevAngle; if (!topAngle || angleDiff > topAngle.innerAngle) { topAngle = { innerAngle: angleDiff, baseAngle: prevAngle }; } prevAngle = angle; } return topAngle;
}
// ----- MATHEMATICAL UTILITIES -----
function euclideanDist(coordA, coordB) { var x1 = coordA[0]; var y1 = coordA[1]; var x2 = coordB[0]; var y2 = coordB[1]; return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
function getEdgeAngle(coordA, coordB) { var angle = Math.atan2(coordB[1] - coordA[1], coordB[0] - coordA[0]); return angle;
}
// ----- BOUNDARY TESTING -----
function lineIsWithinCircle(startCoord, endCoord, centerCoord, radius) { var startToCenterDist = euclideanDist(startCoord, centerCoord); var endToCenterDist = euclideanDist(endCoord, centerCoord); if (startToCenterDist < radius && endToCenterDist < radius) { return true; } return false;
}
function lineIntersectsCircle(startCoord, endCoord, centerCoord, radius) { // if the distance from the end of the vector to the center is less than the radius, there is a collision if (euclideanDist(endCoord, centerCoord) < radius) { return true; } //normalize all to 0,0 var startPrime = [0, 0]; var endPrime = [endCoord[0] - startCoord[0], endCoord[1] - startCoord[1]]; var centerPrime = [centerCoord[0] - startCoord[0], centerCoord[1] - startCoord[1]]; //Calculate the distance of the adjusted circle from 0,0 var circleDist = euclideanDist([0, 0], centerPrime); //calculate the angle between the angent and the vector from 0,0 to circle center var tangentAngle = Math.sinh(radius / circleDist); var tangentLength = Math.sqrt(Math.pow(circleDist, 2) - Math.pow(radius, 2)); var vectorAngle = getEdgeAngle([0, 0], endPrime); var vectorLength = euclideanDist(startCoord, endCoord); var circleAngle = getEdgeAngle([0, 0], centerPrime); var angleDiff = Math.abs(tangentAngle - vectorAngle); if (angleDiff < tangentAngle) { if (tangentLength > vectorLength) { return true; } } return false;
}
function testIfInCircle(center, radius, coord) { if (euclideanDist(coord, center) < radius) { return true; } return false;
}
function isCoordWithinBBox(coord, minX, minY, maxX, maxY) { if (coord[0] > minX && coord[0] < maxX && coord[1] > minY && coord[1] < maxY) { return true; } return false;
}
function isPathWithinBounds(startCoord, endCoord) { if (lineIsWithinCircle(startCoord, endCoord, singleCell, singleCellRadius)) { return true; } if (lineIntersectsCircle(startCoord, endCoord, upperCircleBound, circleBoundRadius) || lineIntersectsCircle(startCoord, endCoord, lowerCircleBound, circleBoundRadius)) { return false; } if (lineIntersectsCircle(startCoord, endCoord, nucleus, nucleusRadius)) { return false; } if (!isCoordWithinBBox(endCoord, 0, 0, bigBlobWidth, bigBlobHeight)) { return false; } return true;
}
// ---- SETUP -----
function setOuterPoints(numPoints, path) { for (var i = 0; i < numPoints; i++) { var point = getRandomPointOnPath(path); var coord = [point.x, point.y]; terminalNodes.push(coord); }
}
svg.on('click', function () { recursiveGrow(d3.mouse(this), multiplier);
});
// ---- RENDERER ----
function recursiveGrow(coord, multiplier) { drawNode(coord); nodeLibrary.push(coord); var count = 0; var localNodeLibrary = []; //For every node that's already been plotted, check if it's nearby this coord for (var _iterator3 = nodeLibrary, _isArray3 = Array.isArray(_iterator3), _i3 = 0, _iterator3 = _isArray3 ? _iterator3 : _iterator3[Symbol.iterator]();;) { var _ref3; if (_isArray3) { if (_i3 >= _iterator3.length) break; _ref3 = _iterator3[_i3++]; } else { _i3 = _iterator3.next(); if (_i3.done) break; _ref3 = _i3.value; } var coordPrime = _ref3; if (count > multiplier) { break; } //If it is, draw a line to it. if (testIfInCircle(coord, searchRadius, coordPrime)) { if (coord[0] !== coordPrime[0] || coord[1] !== coordPrime[1]) { drawLine(coord, coordPrime); localNodeLibrary.push(coordPrime); count++; } } } var _loop = function _loop() { if (_isArray4) { if (_i4 >= _iterator4.length) return 'break'; _ref4 = _iterator4[_i4++]; } else { _i4 = _iterator4.next(); if (_i4.done) return 'break'; _ref4 = _i4.value; } var terminalCoordPrime = _ref4; if (testIfInCircle(coord, searchRadius, terminalCoordPrime)) { drawLine(coord, terminalCoordPrime).then(function () { localNodeLibrary.push(terminalCoordPrime); drawNode(terminalCoordPrime); }); } }; for (var _iterator4 = terminalNodes, _isArray4 = Array.isArray(_iterator4), _i4 = 0, _iterator4 = _isArray4 ? _iterator4 : _iterator4[Symbol.iterator]();;) { var _ref4; var _ret = _loop(); if (_ret === 'break') break; } var createChildren = function createChildren() { debugger; var topAngle = getTopAngle(localNodeLibrary, coord); var extendAngle = undefined; if (topAngle) { if (topAngle.baseAngle === topAngle.innerAngle) { extendAngle = topAngle.baseAngle + Math.PI; } else { extendAngle = topAngle.baseAngle + topAngle.innerAngle / 2; } } else { extendAngle = Math.random() * Math.PI * 2; } var incrementCount = function incrementCount(newCoord) { count++; localNodeLibrary.push(newCoord); if (count < multiplier) { createChildren(); } }; var extendPromise = extendInDirection(coord, extendAngle, incrementCount); if (extendPromise) { extendPromise.then(function (newCoord) { if (newCoord) { recursiveGrow(newCoord, multiplier); } }); } }; createChildren();
}
function setup() { setOuterPoints(300, divide_outer); setOuterPoints(30, divide_inner); setOuterPoints(100, single);
}
function reset() { clipPath.selectAll("*").remove(); nodeLibrary = []; terminalNodes = []; setup();
}
setup();
Developer | Alexander Hadik |
Username | ahadik |
Uploaded | December 30, 2022 |
Rating | 3 |
Size | 8,502 Kb |
Views | 6,072 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Workcell | 5,864 Kb |
Table Action | 7,906 Kb |
Pricing Table | 4,023 Kb |
Transcriptic Pricing Cards | 11,150 Kb |
Geometric Header | 4,345 Kb |
Protocol Card | 3,149 Kb |
Ops Implementation | 8,026 Kb |
IOPS Selector | 3,779 Kb |
D3 Learnings | 1,618 Kb |
Basil Tree | 5,064 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Blank Starter | Mhartington | 2,171 Kb |
Fluid Responsive Typography | Jonmilner | 4,205 Kb |
A Pen by Oliver Schafeld | Schafeld | 1,720 Kb |
SVG Playground | Roygwells | 1,834 Kb |
Virtual vinyl | Davidpanik | 3,474 Kb |
Responsive Table-less Shopping Cart | Alex_rodrigues | 6,637 Kb |
Multi-step GSAP animation | Acacheung | 2,668 Kb |
A Pen by Mike Otis | Mikeotis | 3,185 Kb |
Highbrow Basic HTML Lesson 8 | Kimlarocca | 2,094 Kb |
TheCalendar.js | The-teacher | 6,330 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!