From f23125e67af652d28dee80bc152fb84ebc26f9bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Soko=C5=82owski?= Date: Tue, 27 Apr 2021 00:37:53 +0200 Subject: [PATCH] new layout drawer and new btns --- src/components/Main.jsx | 3 +- src/components/Navigation/DrawerRoll.jsx | 20 ++++- src/components/Navigation/index.jsx | 7 +- src/components/Node/DataViewer/ReactTable.jsx | 4 +- src/components/Node/DataViewer/index.jsx | 2 +- src/components/Node/Hide.jsx | 36 ++++++++ src/components/Node/index.jsx | 82 +++++++++++-------- src/components/TestSetFileReader.jsx | 49 +++++++++++ src/components/Tree.jsx | 43 ++++++++-- src/contexts/IgnoredContext.jsx | 19 +++++ src/services/playground2.js | 24 ++++++ 11 files changed, 237 insertions(+), 52 deletions(-) create mode 100644 src/components/Node/Hide.jsx create mode 100644 src/components/TestSetFileReader.jsx create mode 100644 src/contexts/IgnoredContext.jsx diff --git a/src/components/Main.jsx b/src/components/Main.jsx index 97e2eb8..5e7ae58 100644 --- a/src/components/Main.jsx +++ b/src/components/Main.jsx @@ -4,6 +4,7 @@ import Tree from './Tree'; import Navigation from './Navigation'; import { builder as _builder_ } from '../services/Playground'; import { AttributesProvider } from '../contexts/AttributesContext'; +import { IgnoredProviders } from '../contexts/IgnoredContext'; import { BuilderConfigProvider } from '../contexts/BuilderConfigContext'; function Main() { @@ -27,7 +28,7 @@ function Main() { {/* */}

-
{isReady ? :
czekam na ciebie
}
+
{isReady ? :
Deploy your set
}
diff --git a/src/components/Navigation/DrawerRoll.jsx b/src/components/Navigation/DrawerRoll.jsx index 9f91b3c..5d6b79e 100644 --- a/src/components/Navigation/DrawerRoll.jsx +++ b/src/components/Navigation/DrawerRoll.jsx @@ -7,22 +7,33 @@ import { DrawerBody, DrawerOverlay, DrawerContent, + OrderedList, + ListItem, } from '@chakra-ui/react'; -function DrawerRoll() { +function DrawerRoll({ ignoredAttributes }) { const { isOpen, onOpen, onClose } = useDisclosure(); + var collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); + return ( <> - Basic Drawer + Your all ignored attributes: + + {ignoredAttributes.sort(collator.compare).map(item => ( + +

{item}

+
+ ))} +
+ {/*

Some contents...

Some contents...

-

Some contents...

-

Some contents...

+

Some contents...

*/}
@@ -31,3 +42,4 @@ function DrawerRoll() { } export default DrawerRoll; +export const DrawerMemo = React.memo(DrawerRoll); diff --git a/src/components/Navigation/index.jsx b/src/components/Navigation/index.jsx index 37d6d0f..1693419 100644 --- a/src/components/Navigation/index.jsx +++ b/src/components/Navigation/index.jsx @@ -24,10 +24,11 @@ import { builder } from '../../services/Playground'; import IgnoredAttributes from './IgnoredAttributes'; import Builder from './Builder'; import FormControlNumberInput from './FormControlNumberInput'; -import DrawerRoll from './DrawerRoll'; +import DrawerRoll, { DrawerMemo } from './DrawerRoll'; import { useLoadingContext } from '../../contexts/LoadingContext'; import { useAttributesContext } from '../../contexts/AttributesContext'; import { useBuilderConfigContext } from '../../contexts/BuilderConfigContext'; +import { useIgnoredContext } from '../../contexts/IgnoredContext'; /** * @typedef {import('../../utils/decision-tree.js').DecisionTreeBuilder} DecisionTreeBuilder @@ -47,6 +48,7 @@ function Navigation({ onPrepareConfig }) { const [allClazz, setAllClasses] = useState([]); const [config, setConfig] = useState({}); const { attributes: options, onAttributesChange } = useAttributesContext(); + //const { attributes: ignoredAttributes, onIgnoredChange } = useIgnoredContext(); const { isLoading } = useLoadingContext(); function handleSelectDecision(value) { @@ -57,6 +59,7 @@ function Navigation({ onPrepareConfig }) { function handleSelectIgnore(value) { console.log(value); setIgnoredAttributes(value); + //onIgnoredChange(value) } function handleSetMinItems(value) { //console.log(value); @@ -229,7 +232,7 @@ function Navigation({ onPrepareConfig }) { - + ); diff --git a/src/components/Node/DataViewer/ReactTable.jsx b/src/components/Node/DataViewer/ReactTable.jsx index 56aa96f..8ad6d45 100644 --- a/src/components/Node/DataViewer/ReactTable.jsx +++ b/src/components/Node/DataViewer/ReactTable.jsx @@ -23,9 +23,11 @@ function ReactTable({ set, cols }) { console.log(set, cols); const data = React.useMemo(() => set, []); + var collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' }); + function prepareHeaders(cols) { let tmp = []; - for (let item of cols.sort()) { + for (let item of cols.sort(collator.compare)) { tmp.push({ Header: item, accessor: item, diff --git a/src/components/Node/DataViewer/index.jsx b/src/components/Node/DataViewer/index.jsx index fe68983..b6cca30 100644 --- a/src/components/Node/DataViewer/index.jsx +++ b/src/components/Node/DataViewer/index.jsx @@ -36,7 +36,7 @@ function DataViewer({ node, side }) { fontSize="14px" fontWeight="semibold" > - {sideSubTitle} + {sideSubTitle} - {node.nodeSet ? node.nodeSet.length : node.trainingSet2.length} elements. onChange(!hide)} + colorScheme="teal" + variant="outline" + size="sm" + fontSize="14px" + //color="white" + mr={1} + > + {hide ? : } + + ); +} + +export default DataViewer; diff --git a/src/components/Node/index.jsx b/src/components/Node/index.jsx index 3be86b5..5530ac2 100644 --- a/src/components/Node/index.jsx +++ b/src/components/Node/index.jsx @@ -1,9 +1,9 @@ -import { Box, Spinner, useDisclosure } from '@chakra-ui/react'; +import { Box, Button, ButtonGroup, Hide, Spinner, Tooltip, 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 Hider from './Hide'; import Joint from './Joint'; import Leaf from './Leaf'; @@ -12,6 +12,7 @@ const Node = props => { //console.log(props.node); const { builderConfig } = useBuilderConfigContext(); const [highlighted, setHighlighted] = useState(false); + const [hide, setHide] = useState(false); const [loading, setLoading] = useState(false); const [node, setNode] = useState(props.node || {}); useEffect(() => setNode(props.node || {}), [props.node, setNode]); @@ -115,6 +116,10 @@ const Node = props => { }); }; + const handleHide = value => { + setHide(value); + }; + if (loading) { return ; } @@ -122,41 +127,48 @@ const Node = props => { return (
- - {category ? ( - - ) : ( - - + + + + + +
+ {category ? ( + - - - )} + requestFoldToLeaf={foldJointToLeaf} + nodeSet={nodeSet} + weight={weight} + > + + + + )} +
); diff --git a/src/components/TestSetFileReader.jsx b/src/components/TestSetFileReader.jsx new file mode 100644 index 0000000..27f3346 --- /dev/null +++ b/src/components/TestSetFileReader.jsx @@ -0,0 +1,49 @@ +import React, { useState } from 'react'; +import ReactFileReader from 'react-file-reader'; +import { Button } from '@chakra-ui/react'; +import { GrDocumentUpload } from 'react-icons/gr'; + +import { readLocalFile } from '../utils/file-reader'; +import parseCsv from 'csv-parse/lib/sync'; + +function TestSetFileReader(props) { + const handleFiles = async files => { + const file = await readLocalFile(files[0]); + //console.log(file); + const clean = file + .split('\n') + .map(line => { + return line.replace(/(^"|"$)|(")/g, ''); + //return line.replace(/(^"|"$)/g, ''); + }) + .join('\n'); + + //console.log(clean); + const data = parseCsv(clean, { + columns: h => { + // let header = h.map((v, i) => v || `attr${i}`); + // allAttributes.push(header); + // return header; + if (props.isHeaders) return h.map((v, i) => v); + else return h.map((v, i) => `attr${i}`); + }, + comment: '#', + skipEmptyLines: true, + delimiter: [',', '\t'], + }); + //const data = parseCsv(file,{columns: true, comment: "#",skipEmptyLines: true,}) + console.log(data); + + props.onChange({ data }); + }; + + return ( +
+ + + +
+ ); +} + +export default TestSetFileReader; diff --git a/src/components/Tree.jsx b/src/components/Tree.jsx index 66da8e8..497c62f 100644 --- a/src/components/Tree.jsx +++ b/src/components/Tree.jsx @@ -1,10 +1,11 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import { Box, Spinner } from '@chakra-ui/react'; -// import { start } from '../services/Playground'; -// import { dt } from '../services/TSP'; +import { Box, Button, HStack, Spinner } from '@chakra-ui/react'; +import { GrTechnology, GrDocumentUpload } from 'react-icons/gr'; +import { GiWaterDivinerStick } from 'react-icons/gi'; import Node from './Node'; import { useLoadingContext } from '../contexts/LoadingContext'; import { executeAlgorithm } from '../utils/algorithm-executor'; +import TestSetFileReader from './TestSetFileReader'; /** * @typedef {import('../utils/decision-tree.js').DecisionTreeBuilder} DecisionTreeBuilder @@ -27,6 +28,7 @@ const Tree = ({ options }) => { // }, [options]); const [root, setRoot] = useState(null); + const [testSet, setTestSet] = useState([]); const { isLoading, setIsLoading } = useLoadingContext(); useEffect(() => { @@ -57,14 +59,39 @@ const Tree = ({ options }) => { const requestChildChange = newRoot => setRoot(newRoot); + function handleGetTestSet({ data }) { + setTestSet(data); + console.log(data); + } + function predict(root) { + console.log('predict'); + } + return (
-

Tree

-

- -

+ + +

+ +

+
+ +

+ +

+
+ +

+ +

+
+
{isLoading && } -

Nodes:

+

Tree nodes:

{!root ? (

No tree to show

diff --git a/src/contexts/IgnoredContext.jsx b/src/contexts/IgnoredContext.jsx new file mode 100644 index 0000000..d91cafa --- /dev/null +++ b/src/contexts/IgnoredContext.jsx @@ -0,0 +1,19 @@ +import React, { useContext, useState } from 'react'; + +// @ts-ignore +const IgnoredContext = React.createContext(); + +export const IgnoredProviders = ({ children }) => { + const [attributes, setAttributes] = useState([]); + + const onIgnoredChange = input => setAttributes(input.map(element => ({ value: element, name: element }))); + + return ( + {children} + ); +}; + +export const useIgnoredContext = () => { + const { attributes, onIgnoredChange } = useContext(IgnoredContext); + return { attributes, onIgnoredChange }; +}; diff --git a/src/services/playground2.js b/src/services/playground2.js index ad56039..f3f3c22 100644 --- a/src/services/playground2.js +++ b/src/services/playground2.js @@ -1,3 +1,27 @@ +function predict(tree, item) { + var attr, value, predicate, pivot; + + // Traversing tree from the root to leaf + while (true) { + if (tree.category) { + // only leafs contains predicted category + return tree.category; + } + + attr = tree.attribute; + value = item[attr]; + + predicate = predicates[tree.predicate]; + pivot = tree.pivot; + + // move to one of subtrees + if (predicate(value, pivot)) { + tree = tree.match; + } else { + tree = tree.notMatch; + } + } +} var predicates = { '==': function (a, b) { return a === b;