mirror of
https://github.com/hsokolowski/iTree.git
synced 2026-05-19 11:04:30 -04:00
new layout
This commit is contained in:
@@ -3,6 +3,6 @@
|
||||
"checkJs": true,
|
||||
"jsx": "react",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"lib": ["webworker"]
|
||||
"lib": ["es2019"]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,40 +33,32 @@ function buildDecisionTreeTSP(
|
||||
maxTreeDepth,
|
||||
ignoredAttributes,
|
||||
} = builder;
|
||||
//console.log("########## NOWY WEZEL ########", trainingSet.length);
|
||||
|
||||
/** @type {string | number} */
|
||||
var _quality = 0;
|
||||
|
||||
// LEAF
|
||||
if (maxTreeDepth === 0 || trainingSet.length <= minItemsCount) {
|
||||
console.log('LISC BO MAX TREE DEPTH', maxTreeDepth, 'LISC ILOSC', trainingSet.length);
|
||||
//gger;
|
||||
console.log('Liść bo maxTreeDepth:', maxTreeDepth, ' Ilość elementów:', trainingSet.length);
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach(element => {
|
||||
for (let element of trainingSet) {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
}
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
//ugger;
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
quality: _quality.toFixed(2),
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet,
|
||||
};
|
||||
}
|
||||
var attributes = builder.allAttributes.filter(function (el) {
|
||||
return ![...ignoredAttributes, categoryAttr].includes(el);
|
||||
});
|
||||
//console.log(builder.minItemsCount, builder.trainingSet.length);
|
||||
var attributes = builder.allAttributes.filter(el => el !== categoryAttr && !ignoredAttributes.includes(el));
|
||||
|
||||
// tu juz musi byc przekazana cm wyzerowana
|
||||
|
||||
var podzial = [];
|
||||
//console.log(attributes);
|
||||
var right = 0,
|
||||
left = 0;
|
||||
var maxDif = 100;
|
||||
@@ -83,31 +75,25 @@ function buildDecisionTreeTSP(
|
||||
notMatch = [];
|
||||
|
||||
//#########################
|
||||
//# tu gdy zmieniamy #
|
||||
//# force changes #
|
||||
//#########################
|
||||
if (isChanged) {
|
||||
right = left = 0;
|
||||
leftList = [];
|
||||
rightList = [];
|
||||
classMatrix = [
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
];
|
||||
|
||||
for (let index = 0; index < trainingSet.length; index++) {
|
||||
const element = trainingSet[index];
|
||||
// division
|
||||
for (let element of trainingSet) {
|
||||
const attribute = element[categoryAttr];
|
||||
|
||||
if (element[changedAttribute1] < element[changedAttribute2]) {
|
||||
left++;
|
||||
leftList.push(element);
|
||||
classMatrix[0][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
classMatrix[0][builder.allClasses.indexOf(attribute)]++;
|
||||
} else {
|
||||
right++;
|
||||
rightList.push(element);
|
||||
classMatrix[1][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
classMatrix[1][builder.allClasses.indexOf(attribute)]++;
|
||||
}
|
||||
}
|
||||
//console.log(classMatrix);
|
||||
|
||||
// probability
|
||||
var probR = 0,
|
||||
probL = 0,
|
||||
rankL = 0,
|
||||
@@ -119,28 +105,22 @@ function buildDecisionTreeTSP(
|
||||
rankL += probL * probL;
|
||||
rankR += probR * probR;
|
||||
}
|
||||
//console.log("Rank Lewy",rankL,"Rank Prawy",rankR);
|
||||
|
||||
// setting new values
|
||||
var currentDif = (right / trainingSet.length) * (1 - rankR) + (left / trainingSet.length) * (1 - rankL);
|
||||
if (currentDif < maxDif) {
|
||||
//console.log("------Zapisanie maxDif-------");
|
||||
//console.log(attr1,attr2);
|
||||
//console.log("R/L ", right + ":" + left);
|
||||
//console.log("cur/mD",currentDif + ":" + maxDif);
|
||||
maxDif = currentDif;
|
||||
attribute1 = changedAttribute1;
|
||||
attribute2 = changedAttribute2;
|
||||
match = leftList;
|
||||
notMatch = rightList;
|
||||
podzial = classMatrix;
|
||||
//console.log("-----------------------------");
|
||||
//podzial = classMatrix;
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < attributes.length; i++) {
|
||||
let attr1 = attributes[i];
|
||||
for (let j = 0; j < attributes.length; j++) {
|
||||
let attr2 = attributes[j];
|
||||
for (let attr1 of attributes) {
|
||||
for (let attr2 of attributes) {
|
||||
if (attr1 !== attr2) {
|
||||
console.log(attr1, attr2);
|
||||
right = left = 0;
|
||||
leftList = [];
|
||||
rightList = [];
|
||||
@@ -149,20 +129,22 @@ function buildDecisionTreeTSP(
|
||||
new Array(builder.allClasses.length).fill(0),
|
||||
];
|
||||
|
||||
for (let index = 0; index < trainingSet.length; index++) {
|
||||
const element = trainingSet[index];
|
||||
// division
|
||||
for (let element of trainingSet) {
|
||||
const attribute = element[categoryAttr];
|
||||
|
||||
if (element[attr1] < element[attr2]) {
|
||||
left++;
|
||||
leftList.push(element);
|
||||
classMatrix[0][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
classMatrix[0][builder.allClasses.indexOf(attribute)]++;
|
||||
} else {
|
||||
right++;
|
||||
rightList.push(element);
|
||||
classMatrix[1][builder.allClasses.indexOf(element[categoryAttr])]++;
|
||||
classMatrix[1][builder.allClasses.indexOf(attribute)]++;
|
||||
}
|
||||
}
|
||||
//console.log(classMatrix);
|
||||
|
||||
// probability
|
||||
var probR = 0,
|
||||
probL = 0,
|
||||
rankL = 0,
|
||||
@@ -174,74 +156,60 @@ function buildDecisionTreeTSP(
|
||||
rankL += probL * probL;
|
||||
rankR += probR * probR;
|
||||
}
|
||||
//console.log("Rank Lewy",rankL,"Rank Prawy",rankR);
|
||||
|
||||
// setting new values
|
||||
var currentDif =
|
||||
(right / trainingSet.length) * (1 - rankR) + (left / trainingSet.length) * (1 - rankL);
|
||||
console.log('left', left, 'right', right, 'currentDiff', currentDif);
|
||||
if (currentDif < maxDif) {
|
||||
//console.log("------Zapisanie maxDif-------");
|
||||
//console.log(attr1,attr2);
|
||||
//console.log("R/L ", right + ":" + left);
|
||||
//console.log("cur/mD",currentDif + ":" + maxDif);
|
||||
maxDif = currentDif;
|
||||
attribute1 = attr1;
|
||||
attribute2 = attr2;
|
||||
match = leftList;
|
||||
notMatch = rightList;
|
||||
podzial = classMatrix;
|
||||
//console.log("-----------------------------");
|
||||
//podzial = classMatrix;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//console.log("PO WYLICZENIU NAJLEPSZEGO");
|
||||
//console.log(attribute1, attribute2);
|
||||
//console.log("L/R ", match.length + ":" + notMatch.length);
|
||||
//console.log(podzial);
|
||||
console.log('MaxDifference:', maxDif);
|
||||
// LEAF
|
||||
if (!maxDif) {
|
||||
//console.log("LISC BO MAX DIF ZERO", trainingSet.length);
|
||||
console.log('Liść bo maxDif:', maxDif);
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log("KATEGORIA JAKO:", _category);
|
||||
trainingSet.forEach(element => {
|
||||
for (let element of trainingSet) {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
}
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
quality: _quality.toFixed(2),
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet,
|
||||
};
|
||||
}
|
||||
// sprawdzic
|
||||
// wssytskies stringi do ignored
|
||||
|
||||
//LEAF
|
||||
if (match.length === 0 || notMatch.length === 0) {
|
||||
console.log('LISC BO JEDNA ZE STRON MA 0');
|
||||
console.log('Liść bo Lewa/Prawa wynosi 0');
|
||||
let _category = mostFrequentValue(trainingSet, categoryAttr);
|
||||
let _positiveCounter = 0;
|
||||
//console.log(_category);
|
||||
trainingSet.forEach(element => {
|
||||
for (let element of trainingSet) {
|
||||
if (element[categoryAttr] == _category) _positiveCounter++;
|
||||
});
|
||||
}
|
||||
let _negativeCounter = trainingSet.length - _positiveCounter;
|
||||
_quality = _positiveCounter / trainingSet.length;
|
||||
_quality = _quality * 100;
|
||||
_quality = _quality.toFixed(2);
|
||||
// restriction by maximal depth of tree
|
||||
// or size of training set is to small
|
||||
// so we have to terminate process of building tree
|
||||
|
||||
return {
|
||||
category: _category,
|
||||
quality: _quality,
|
||||
quality: _quality.toFixed(2),
|
||||
matchedCount: _positiveCounter,
|
||||
notMatchedCount: _negativeCounter,
|
||||
trainingSet2: trainingSet,
|
||||
@@ -254,6 +222,7 @@ function buildDecisionTreeTSP(
|
||||
|
||||
builder.trainingSet = notMatch;
|
||||
var notMatchSubTree = buildDecisionTreeTSP(builder);
|
||||
|
||||
console.log('TUTAJ');
|
||||
return {
|
||||
attr2: attribute2,
|
||||
@@ -265,17 +234,17 @@ function buildDecisionTreeTSP(
|
||||
notMatchedCount: notMatch.length,
|
||||
nodeSet: match.concat(notMatch),
|
||||
};
|
||||
//console.log(attributes);
|
||||
}
|
||||
|
||||
function countUniqueValues(items, attr) {
|
||||
var counter = {};
|
||||
////var counter = {};
|
||||
|
||||
// detecting different values of attribute
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
// items[i][attr] - value of attribute
|
||||
counter[items[i][attr]] = 0;
|
||||
}
|
||||
//// for (var i = items.length - 1; i >= 0; i--) {
|
||||
//// // items[i][attr] - value of attribute
|
||||
//// counter[items[i][attr]] = 0;
|
||||
//// }
|
||||
var counter = Object.fromEntries(items.map(item => [item[attr], 0]));
|
||||
|
||||
// counting number of occurrences of each of values
|
||||
// of attribute
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
import { Input, Stack } from '@chakra-ui/react';
|
||||
import { ChevronLeftIcon } from '@chakra-ui/icons';
|
||||
import { ChevronRightIcon } from '@chakra-ui/icons';
|
||||
import { CgMathEqual } from 'react-icons/cg';
|
||||
import { IconContext } from 'react-icons';
|
||||
import { Search as SearchBar } from '../../SearchBar';
|
||||
import './alg-style.scss';
|
||||
import { useAttributesContext } from '../../../contexts/AttributesContext';
|
||||
@@ -22,7 +24,13 @@ export default function TabC45({ attribute, value, changeValues }) {
|
||||
closeOnSelect={true}
|
||||
/>
|
||||
{/* </div> */}
|
||||
<ChevronLeftIcon w={10} h={10} />
|
||||
|
||||
<IconContext.Provider value={{ style: { height: 10 } }}>
|
||||
<Stack direction="row" spacing={0}>
|
||||
<ChevronRightIcon w={10} h={10} />
|
||||
</Stack>
|
||||
</IconContext.Provider>
|
||||
|
||||
<Input value={value} size="md" name="c45-value" onChange={onPivotChange} />
|
||||
</Stack>
|
||||
);
|
||||
|
||||
66
src/components/Node/DataViewer/index.jsx
Normal file
66
src/components/Node/DataViewer/index.jsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
useDisclosure,
|
||||
} from '@chakra-ui/react';
|
||||
import { CgDatabase } from 'react-icons/cg';
|
||||
|
||||
function DataViewer({ node, side }) {
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const finalRef = React.useRef();
|
||||
const scrollBehavior = 'inside';
|
||||
const sideSubTitle = side ? 'Matched' : 'Not Matched';
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Button
|
||||
mt={1}
|
||||
px={2}
|
||||
py={3}
|
||||
onClick={onOpen}
|
||||
leftIcon={<CgDatabase />}
|
||||
colorScheme="teal"
|
||||
variant="solid"
|
||||
size="sm"
|
||||
fontSize="14px"
|
||||
fontWeight="semibold"
|
||||
>
|
||||
{/* View Data */}
|
||||
{/* <CgDatabase /> */}
|
||||
{sideSubTitle}
|
||||
</Button>
|
||||
<Modal
|
||||
finalFocusRef={finalRef}
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
size="xl"
|
||||
scrollBehavior={scrollBehavior}
|
||||
blockScrollOnMount={false}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>Data Viewer [ {sideSubTitle} ]</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody></ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button colorScheme="blue" mr={3} onClick={onClose}>
|
||||
Close
|
||||
</Button>
|
||||
<Button variant="ghost">Secondary Action</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DataViewer;
|
||||
@@ -2,6 +2,7 @@ import {
|
||||
Badge,
|
||||
Box,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
@@ -31,21 +32,31 @@ function Joint({ children, attr2, predicateName, pivot, weight, requestFoldToLea
|
||||
const foldToLeaf = () => requestFoldToLeaf();
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Badge
|
||||
borderRadius="full"
|
||||
px="2"
|
||||
py="1"
|
||||
colorScheme="teal"
|
||||
<Box mt={1}>
|
||||
<ButtonGroup size="md" isAttached variant="solid" className="tree-branch">
|
||||
<Button size="xs" colorScheme="green" onClick={handleOpenModalClick}>
|
||||
{attr2} <b>{predicateName}</b> {weight} {pivot}
|
||||
</Button>
|
||||
<Button size="xs" borderRadius="0.375rem" rightIcon={<CloseIcon />} onClick={foldToLeaf}>
|
||||
Fold
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
{/* <Badge
|
||||
borderRadius="0.375rem"
|
||||
px="3"
|
||||
py="2"
|
||||
variant="subtle"
|
||||
colorScheme="green"
|
||||
onClick={handleOpenModalClick}
|
||||
className={'badge'}
|
||||
marginRight={3}
|
||||
fontSize={16}
|
||||
>
|
||||
{attr2} <b>{predicateName}</b> {weight} {pivot}
|
||||
</Badge>
|
||||
<Button size="xs" rightIcon={<CloseIcon />} onClick={foldToLeaf}>
|
||||
</Badge> */}
|
||||
{/* <Button size="xs" borderRadius="0.375rem" rightIcon={<CloseIcon />} onClick={foldToLeaf}>
|
||||
Fold
|
||||
</Button>
|
||||
</Button> */}
|
||||
<ModalPopup
|
||||
isOpen={isOpen}
|
||||
nodeSet={nodeSet}
|
||||
@@ -57,35 +68,6 @@ function Joint({ children, attr2, predicateName, pivot, weight, requestFoldToLea
|
||||
onOpen={onOpen}
|
||||
weight={weight}
|
||||
/>
|
||||
{/* <Modal onClose={onClose} size={size} isOpen={isOpen}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>
|
||||
{attr2} <b>{predicateName}</b> {pivot}
|
||||
</ModalHeader>
|
||||
<ModalCloseButton />
|
||||
<ModalBody>
|
||||
Text ( kolejny komponent z konfiguratorem){' '}
|
||||
{nodeSet.map(x => (
|
||||
<div>
|
||||
{x.attr1001} {x[attr2]}-{x[pivot]} {x[attr2] < x[pivot] ? 'Match' : 'NotMatch'}
|
||||
</div>
|
||||
))}
|
||||
<Configurator />
|
||||
</ModalBody>
|
||||
<ModalFooter>
|
||||
<Button onClick={onClose}>Close</Button>
|
||||
</ModalFooter>
|
||||
</ModalContent>
|
||||
</Modal> */}
|
||||
{/* <div>
|
||||
Match
|
||||
{JSON.stringify(match)}
|
||||
</div>
|
||||
<div>
|
||||
notMatch
|
||||
{JSON.stringify(notMatch)}
|
||||
</div> */}
|
||||
{children}
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -7,12 +7,14 @@ function Leaf({ category, matchedCount, notMatchedCount, quality, requestLeafUnf
|
||||
<Box
|
||||
d="flex"
|
||||
alignItems="baseline"
|
||||
borderWidth="1px"
|
||||
borderWidth="2px"
|
||||
borderRadius="lg"
|
||||
flexDirection="column"
|
||||
maxW="sm"
|
||||
maxW="xs"
|
||||
p="1"
|
||||
my="2"
|
||||
boxShadow="md"
|
||||
className={'tree-branch'}
|
||||
>
|
||||
<Box
|
||||
color="gray.500"
|
||||
|
||||
@@ -18,7 +18,7 @@ function ModalPopup({ attr2, predicateName, pivot, weight, isOpen, nodeSet, onOp
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal onClose={onClose} size="lg" isOpen={isOpen}>
|
||||
<Modal onClose={onClose} size="lg" isOpen={isOpen} blockScrollOnMount={false}>
|
||||
<ModalOverlay />
|
||||
<ModalContent>
|
||||
<ModalHeader>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Spinner } from '@chakra-ui/react';
|
||||
import { Box, Spinner, useDisclosure } from '@chakra-ui/react';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useBuilderConfigContext } from '../../contexts/BuilderConfigContext';
|
||||
import { executeAlgorithm, mostFrequentValue } from '../../utils/algorithm-executor';
|
||||
import DataViewer from './DataViewer';
|
||||
//import { addNode } from "./utils";
|
||||
|
||||
import Joint from './Joint';
|
||||
@@ -12,6 +13,7 @@ const Node = props => {
|
||||
const { builderConfig } = useBuilderConfigContext();
|
||||
const [highlighted, setHighlighted] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [side, setSide] = useState(props.side);
|
||||
const [node, setNode] = useState(props.node || {});
|
||||
useEffect(() => setNode(props.node || {}), [props.node, setNode]);
|
||||
const {
|
||||
@@ -118,30 +120,43 @@ const Node = props => {
|
||||
|
||||
return (
|
||||
<div className={`node ${highlighted ? 'highlight' : ''}`} onClick={onNodeClicked}>
|
||||
{category ? (
|
||||
<Leaf
|
||||
category={category}
|
||||
matchedCount={matchedCount}
|
||||
notMatchedCount={notMatchedCount}
|
||||
quality={quality}
|
||||
requestLeafUnfold={unfoldLeaf}
|
||||
/>
|
||||
) : (
|
||||
<Joint
|
||||
attr2={attr2}
|
||||
predicateName={predicateName}
|
||||
pivot={pivot}
|
||||
match={match}
|
||||
notMatch={notMatch}
|
||||
onChange={onChange}
|
||||
requestFoldToLeaf={foldJointToLeaf}
|
||||
nodeSet={nodeSet}
|
||||
weight={weight}
|
||||
>
|
||||
<Node node={match} onChange={onChange} requestChildChange={requestChildChangeIfMatchIs(true)} />
|
||||
<Node node={notMatch} onChange={onChange} requestChildChange={requestChildChangeIfMatchIs(false)} />
|
||||
</Joint>
|
||||
)}
|
||||
<Box d="flex" flexDirection="column" p="1" paddingLeft={3}>
|
||||
<DataViewer node={node} side={side} />
|
||||
{category ? (
|
||||
<Leaf
|
||||
category={category}
|
||||
matchedCount={matchedCount}
|
||||
notMatchedCount={notMatchedCount}
|
||||
quality={quality}
|
||||
requestLeafUnfold={unfoldLeaf}
|
||||
/>
|
||||
) : (
|
||||
<Joint
|
||||
attr2={attr2}
|
||||
predicateName={predicateName}
|
||||
pivot={pivot}
|
||||
match={match}
|
||||
notMatch={notMatch}
|
||||
onChange={onChange}
|
||||
requestFoldToLeaf={foldJointToLeaf}
|
||||
nodeSet={nodeSet}
|
||||
weight={weight}
|
||||
>
|
||||
<Node
|
||||
node={match}
|
||||
onChange={onChange}
|
||||
requestChildChange={requestChildChangeIfMatchIs(true)}
|
||||
side={side}
|
||||
/>
|
||||
<Node
|
||||
node={notMatch}
|
||||
onChange={onChange}
|
||||
requestChildChange={requestChildChangeIfMatchIs(false)}
|
||||
side={!side}
|
||||
/>
|
||||
</Joint>
|
||||
)}
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -69,7 +69,7 @@ const Tree = ({ options }) => {
|
||||
{!root ? (
|
||||
<p>No tree to show</p>
|
||||
) : (
|
||||
<Node node={root} onChange={() => {}} requestChildChange={requestChildChange} />
|
||||
<Node node={root} onChange={() => {}} requestChildChange={requestChildChange} side={true} />
|
||||
)}
|
||||
</Box>
|
||||
</div>
|
||||
|
||||
@@ -39,12 +39,24 @@ $gradient-radial: radial-gradient(#d8dbe2ff, #a9bcd0ff, #58a4b0ff, #373f51ff, #1
|
||||
transition: all 0.5s;
|
||||
background: white;
|
||||
color: #333;
|
||||
border-left: 1px dashed black;
|
||||
// width: 50%;
|
||||
}
|
||||
.node:first-of-type {
|
||||
border-left: 1px solid transparent;
|
||||
}
|
||||
.node.highlight {
|
||||
background: #09f;
|
||||
color: white;
|
||||
}
|
||||
.tree-branch {
|
||||
position: relative;
|
||||
&::before {
|
||||
content: '--';
|
||||
position: absolute;
|
||||
left: -14px;
|
||||
}
|
||||
}
|
||||
|
||||
#tree {
|
||||
text-align: left;
|
||||
|
||||
@@ -7,6 +7,7 @@ const workersMap = {
|
||||
export function executeAlgorithm(options, changeOptions = {}) {
|
||||
console.log(options);
|
||||
return new Promise((resolve, reject) => {
|
||||
console.time(options.algorithm);
|
||||
const worker = new Worker(`algorithms/${workersMap[options.algorithm]}-tree.js`);
|
||||
worker.onmessage = ({ data }) => {
|
||||
console.log('got a result', data);
|
||||
@@ -15,6 +16,9 @@ export function executeAlgorithm(options, changeOptions = {}) {
|
||||
};
|
||||
worker.onerror = reject;
|
||||
worker.postMessage({ _builder: { ...options }, ...changeOptions });
|
||||
}).then(data => {
|
||||
console.timeEnd(options.algorithm);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user