import { CloseIcon, RepeatClockIcon, ChevronDownIcon, SettingsIcon, InfoOutlineIcon, RepeatIcon, ArrowRightIcon, } from '@chakra-ui/icons' import { Accordion, AccordionButton, AccordionIcon, AccordionItem, AccordionPanel, Box, Button, Flex, IconButton, Menu, MenuButton, MenuItem, MenuList, MenuOptionGroup, MenuItemOption, Select, Slider, SliderFilledTrack, SliderThumb, SliderTrack, StackDivider, Switch, Text, Tooltip, VStack, Heading, Collapse, Grid, Portal, } from '@chakra-ui/react' import React, { useState, useContext } from 'react' import Scrollbars from 'react-custom-scrollbars-2' import { initialPhysics, initialFilter, initialVisuals, initialMouse } from './config' import { ThemeContext } from '../pages/themecontext' export interface TweakProps { physics: typeof initialPhysics setPhysics: any threeDim: boolean setThreeDim: (newValue: boolean) => void filter: typeof initialFilter setFilter: any visuals: typeof initialVisuals setVisuals: any mouse: typeof initialMouse setMouse: any } export const Tweaks = (props: TweakProps) => { const { physics, setPhysics, threeDim, setThreeDim, filter, setFilter, visuals, setVisuals, mouse, setMouse, } = props const [showTweaks, setShowTweaks] = useState(true) const { highlightColor, setHighlightColor } = useContext(ThemeContext) const colorList = [ 'red.500', 'orange.500', 'yellow.500', 'green.500', 'cyan.500', 'blue.500', 'pink.500', 'purple.500', 'gray.400', 'gray.500', 'gray.600', 'white', 'black', ] const grays = [ 'black', 'gray.100', 'gray.200', 'gray.300', 'gray.400', 'gray.500', 'gray.600', 'gray.700', 'gray.800', 'gray.900', 'white', ] return ( <> } onClick={() => setShowTweaks(true)} /> } onClick={() => setPhysics(initialPhysics)} variant="none" size="sm" /> } aria-label="Close Tweak Panel" variant="ghost" onClick={() => setShowTweaks(false)} /> ( )} > Filter } align="stretch" paddingLeft={7} color="gray.800" > Orphans { setFilter({ ...filter, orphans: !filter.orphans }) }} isChecked={filter.orphans} > Link nodes with parent file { setFilter({ ...filter, parents: !filter.parents }) }} isChecked={filter.parents} > Physics setPhysics({ ...physics, enabled: !physics.enabled })} isChecked={physics.enabled} /> } align="stretch" paddingLeft={7} color="gray.800" > setPhysics({ ...physics, gravityOn: !physics.gravityOn })} > setPhysics({ ...physics, gravity: v / 10 })} /> setPhysics({ ...physics, charge: -100 * value })} label="Repulsive Force" /> setPhysics({ ...physics, collision: !physics.collision })} > setPhysics({ ...physics, collisionStrength: value * 5 }) } label="Collision Radius" infoText="Easy with this one, high values can lead to a real jiggly mess" /> setPhysics({ ...physics, linkStrength: value / 5 })} label="Link Force" /> setPhysics({ ...physics, linkIts: value })} min={0} max={6} step={1} infoText="How many links down the line the physics of a single node affects (Slow)" /> setPhysics({ ...physics, velocityDecay: value / 10 })} /> Advanced } align="stretch" paddingLeft={3} color="gray.800" > setPhysics({ ...physics, alphaDecay: value / 50 }) } /> setPhysics({ ...physics, centering: !physics.centering }) } infoText="Keeps the nodes in the center of the viewport. If disabled you can drag the nodes anywhere you want." > setPhysics({ ...physics, centeringStrength: v })} /> {/* */} Visual Colors } align="stretch" color="gray.800" > Nodes } variant="ghost" onClick={() => { const arr = visuals.nodeColorScheme ?? [] setVisuals({ ...visuals, //shuffle that guy //definitely thought of this myself nodeColorScheme: arr .map((x: any) => [Math.random(), x]) .sort(([a], [b]) => a - b) .map(([_, x]) => x), }) }} /> } size="sm" variant="ghost" onClick={() => { const arr = visuals.nodeColorScheme ?? [] setVisuals({ ...visuals, nodeColorScheme: [...arr.slice(1, arr.length), arr[0]], }) }} /> } > {visuals.nodeColorScheme.map((color) => ( ))} {' '} { if (!colors.length) { return } setVisuals({ ...visuals, nodeColorScheme: colors }) }} > {colorList.map((color) => ( c === color, )} value={color} isDisabled={ visuals.nodeColorScheme.length === 1 && visuals.nodeColorScheme[0] === color } > {color[0]!.toUpperCase() + color!.slice(1)} ))} Links } > {visuals.linkColorScheme ? ( ) : ( {visuals.nodeColorScheme.map((color) => ( ))} )} {' '} setVisuals({ ...visuals, linkColorScheme: '' }) } justifyContent="space-between" alignItems="center" display="flex" > {visuals.nodeColorScheme.map((color) => ( ))} {grays.map((color) => ( setVisuals({ ...visuals, linkColorScheme: color, }) } justifyContent="space-between" alignItems="center" display="flex" > ))} Accent } > { } {' '} {colorList.map((color) => ( setHighlightColor(color)} justifyContent="space-between" alignItems="center" display="flex" > {color[0]!.toUpperCase() + color!.slice(1)} ))} Link Highlight } > { } {' '} setVisuals({ ...visuals, linkHighlight: '' }) } justifyContent="space-between" alignItems="center" display="flex" > Match current color {colorList.map((color) => ( setVisuals({ ...visuals, linkHighlight: color }) } justifyContent="space-between" alignItems="center" display="flex" > {color[0]!.toUpperCase() + color!.slice(1)} ))} Node Highlight } > { } {' '} setVisuals({ ...visuals, nodeHighlight: '' }) } justifyContent="space-between" alignItems="center" display="flex" > Match current color {colorList.map((color) => ( setVisuals({ ...visuals, nodeHighlight: color }) } justifyContent="space-between" alignItems="center" display="flex" > {color[0]!.toUpperCase() + color!.slice(1)} ))} Background } > { } {' '} {grays.map((color) => ( setVisuals({ ...visuals, backgroundColor: color }) } justifyContent="space-between" alignItems="center" display="flex" > {color[0]!.toUpperCase() + color!.slice(1)} ))} Emacs Node } > { } {' '} setVisuals({ ...visuals, emacsNodeColor: '' }) } justifyContent="space-between" alignItems="center" display="flex" > No change {colorList.map((color) => ( setVisuals({ ...visuals, emacsNodeColor: color }) } justifyContent="space-between" alignItems="center" display="flex" > {color[0]!.toUpperCase() + color!.slice(1)} ))} } align="stretch" paddingLeft={7} color="gray.800" > setPhysics({ ...physics, nodeRel: value })} /> {threeDim && ( <> setPhysics({ ...physics, nodeOpacity: value })} /> setPhysics({ ...physics, nodeResolution: value })} /> )} setPhysics({ ...physics, linkWidth: value })} /> {threeDim && ( setPhysics({ ...physics, linkOpacity: value })} /> )} Labels } > {!physics.labels ? 'Never' : physics.labels < 2 ? 'On Highlight' : 'Always'} {' '} setPhysics({ ...physics, labels: 0 })}> Never setPhysics({ ...physics, labels: 1 })}> On Highlight setPhysics({ ...physics, labels: 2 })}> Always setPhysics({ ...physics, labels: 3 })}> Always (even in 3D) 0} animateOpacity> } align="stretch" paddingLeft={2} color="gray.800" > Text } color="black" colorScheme="" > { } {' '} {grays.map((color) => ( setVisuals({ ...visuals, labelTextColor: color, }) } > ))} Background } color="black" colorScheme="" > { } {' '} setVisuals({ ...visuals, labelBackgroundColor: '', }) } justifyContent="space-between" alignItems="center" display="flex" > None {grays.map((color) => ( setVisuals({ ...visuals, labelBackgroundColor: color, }) } justifyContent="space-between" alignItems="center" display="flex" > ))} { console.log(visuals.labelBackgroundOpacity) setVisuals({ ...visuals, labelBackgroundOpacity: value }) }} min={0} max={1} step={0.01} /> 1} animateOpacity> setPhysics({ ...physics, labelScale: value / 5 }) } /> setPhysics({ ...physics, particles: !physics.particles })} > setPhysics({ ...physics, particlesNumber: value })} /> setPhysics({ ...physics, particlesWidth: value })} /> setPhysics({ ...physics, highlight: !physics.highlight })} value={physics.highlight} > } align="stretch" paddingLeft={0} > setPhysics({ ...physics, highlightLinkSize: value }) } /> setPhysics({ ...physics, highlightNodeSize: value }) } /> {/* Highlight node color Highlight link color */} { setPhysics({ ...physics, highlightAnim: !physics.highlightAnim }) }} value={physics.highlightAnim} > setPhysics({ ...physics, animationSpeed: v })} value={physics.animationSpeed} infoText="Slower speed has a chance of being buggy" min={50} max={1000} step={10} /> {/* setPhysics({ ...physics, algorithmName: { option } }), )} /> */} Behavior } align="stretch" paddingLeft={7} color="gray.800" > Expand Node } colorScheme="" color="black" > {mouse.local[0]!.toUpperCase() + mouse.local!.slice(1)} {' '} setMouse({ ...mouse, local: '' })}> Never setMouse({ ...mouse, local: 'click' })}> Click setMouse({ ...mouse, local: 'double' })}> Double Click setMouse({ ...mouse, local: 'right' })}> Right Click Open in Emacs } colorScheme="" color="black" > {mouse.follow[0]!.toUpperCase() + mouse.follow!.slice(1)} {' '} setMouse({ ...mouse, follow: '' })}> Never setMouse({ ...mouse, follow: 'click' })}> Click setMouse({ ...mouse, follow: 'double' })}> Double Click setMouse({ ...mouse, follow: 'right' })}> Right Click ) } export interface InfoTooltipProps { infoText?: string | boolean } export const InfoTooltip = (props: InfoTooltipProps) => { const { infoText } = props return ( ) } export interface SliderWithInfoProps { min?: number max?: number step?: number value: number onChange: (arg0: number) => void label: string infoText?: string } export const SliderWithInfo = ({ min = 0, max = 10, step = 0.1, value = 1, ...rest }: SliderWithInfoProps) => { const { onChange, label, infoText } = rest const { highlightColor } = useContext(ThemeContext) return ( {label} {infoText && } ) } export interface EnableSectionProps { label: string value: boolean | number onChange: () => void infoText?: string children: React.ReactNode } export const EnableSection = (props: EnableSectionProps) => { const { value, onChange, label, infoText, children } = props return ( {label} {infoText && } {children} ) } export interface DropDownMenuProps { textArray: string[] onClickArray: (() => void)[] displayValue: string } export const DropDownMenu = (props: DropDownMenuProps) => { const { textArray, onClickArray, displayValue } = props return ( }> {displayValue} {' '} {textArray.map((option, i) => { ; {option} })} ) }