Skip to content
This repository has been archived by the owner on Apr 23, 2024. It is now read-only.

Commit

Permalink
feat: home button (#120)
Browse files Browse the repository at this point in the history
* feat: home button

* fix: button appears on pan and zoom

* fix: send in object to createContainer

* refactor: remove unused if from onClick

* fix: don't reset expandedState when pressing homebutton

* fix: same styling as sense

* refactor: move icons
  • Loading branch information
eliseeborn committed Mar 12, 2020
1 parent 429f069 commit 182894f
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 24 deletions.
14 changes: 8 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import './styles/tooltip.less';
import './styles/paths.less';
import './styles/warnings.less';
import './styles/nodes.less';
import './styles/home-button.less';

export default function supernova(env) {
return {
Expand All @@ -50,6 +51,7 @@ export default function supernova(env) {
const [wrapperState] = useState({
transform: {},
constraints,
expandedState,
});
const selectionObj = selectionHandler(translator);

Expand All @@ -65,6 +67,10 @@ export default function supernova(env) {
wrapperState.transform = transform;
}, [transform]);

useEffect(() => {
wrapperState.expandedState = expandedState;
}, [expandedState]);

const setExpandedCallback = newExpandedState => {
newExpandedState.useTransitions = true;
setExpandedState(newExpandedState);
Expand All @@ -91,20 +97,17 @@ export default function supernova(env) {
useEffect(() => {
if (element && dataTree) {
const viewState = viewStateUtil.getViewState(options, layout);
const container = createContainer({
createContainer({
element,
dataTree,
expandedState,
viewState,
wrapperState,
selectionObj,
setInitialZoom,
setTransform,
setExpandedState,
setContainerData,
});
if (container) {
setContainerData(container);
}
}
}, [element, dataTree, constraints]);

Expand All @@ -121,7 +124,6 @@ export default function supernova(env) {
if (containerData && expandedState && styling) {
paintTree({
containerData,
expandedState,
styling,
setExpandedCallback,
wrapperState,
Expand Down
3 changes: 2 additions & 1 deletion src/selections-handler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState, useSelections, useAction } from '@nebula.js/supernova';
import autoRegister from './locale/translations';
import { chainedSelectionIcon } from './utils/svg-icons';

export default function selectionHandler(translator) {
const [linked, setLinked] = useState(false);
Expand Down Expand Up @@ -58,7 +59,7 @@ export default function selectionHandler(translator) {
type: 'path',
attrs: {
d:
'M7.7,3 C7.86568542,3 8,3.13431458 8,3.3 L8,5.7 C8,5.86568542 7.86568542,6 7.7,6 L6,6 L6,9 L7.492,9 L7.49291992,8.3 C7.49291992,8.13431458 7.6272345,8 7.79291992,8 L12.1929199,8 C12.3586053,8 12.4929199,8.13431458 12.4929199,8.3 L12.4929199,10.7 C12.4929199,10.8656854 12.3586053,11 12.1929199,11 L7.79291992,11 C7.6272345,11 7.49291992,10.8656854 7.49291992,10.7 L7.492,10 L6,10 L6,13.7 C6,13.8420161 6.0986801,13.9609842 6.23121275,13.9920768 L6.3,14 L9.5,14 L9.5,13.3 C9.5,13.1343146 9.63431458,13 9.8,13 L14.2,13 C14.3656854,13 14.5,13.1343146 14.5,13.3 L14.5,15.7 C14.5,15.8656854 14.3656854,16 14.2,16 L9.8,16 C9.63431458,16 9.5,15.8656854 9.5,15.7 L9.5,15 L6.3,15 C5.62690296,15 5.07328475,14.4884503 5.00671175,13.8329174 L5,13.7 L5,6 L3.3,6 C3.13431458,6 3,5.86568542 3,5.7 L3,3.3 C3,3.13431458 3.13431458,3 3.3,3 L7.7,3 Z M0.5,13 C0.776142375,13 1,13.2238576 1,13.5 L1,14.4 C1,14.7313708 1.26862915,15 1.6,15 L2.5,15 C2.77614237,15 3,15.2238576 3,15.5 C3,15.7761424 2.77614237,16 2.5,16 L1,16 C0.44771525,16 0,15.5522847 0,15 L0,13.5 C0,13.2238576 0.223857625,13 0.5,13 Z M0.5,6 C0.776142375,6 1,6.22385763 1,6.5 L1,9.5 C1,9.77614237 0.776142375,10 0.5,10 C0.223857625,10 0,9.77614237 0,9.5 L0,6.5 C0,6.22385763 0.223857625,6 0.5,6 Z M15.5,6 C15.7761424,6 16,6.22385763 16,6.5 L16,9.5 C16,9.77614237 15.7761424,10 15.5,10 C15.2238576,10 15,9.77614237 15,9.5 L15,6.5 C15,6.22385763 15.2238576,6 15.5,6 Z M15,0 C15.5522847,0 16,0.44771525 16,1 L16,2.5 C16,2.77614237 15.7761424,3 15.5,3 C15.2238576,3 15,2.77614237 15,2.5 L15,1.6 C15,1.26862915 14.7313708,1 14.4,1 L13.5,1 C13.2238576,1 13,0.776142375 13,0.5 C13,0.223857625 13.2238576,0 13.5,0 L15,0 Z M2.5,2.22044605e-16 C2.77614237,2.22044605e-16 3,0.223857625 3,0.5 C3,0.776142375 2.77614237,1 2.5,1 L1.6,1 C1.26862915,1 1,1.26862915 1,1.6 L1,2.5 C1,2.77614237 0.776142375,3 0.5,3 C0.223857625,3 0,2.77614237 0,2.5 L0,1 C0,0.44771525 0.44771525,2.22044605e-16 1,2.22044605e-16 L2.5,2.22044605e-16 Z M9.5,0 C9.77614237,0 10,0.223857625 10,0.5 C10,0.776142375 9.77614237,1 9.5,1 L6.5,1 C6.22385763,1 6,0.776142375 6,0.5 C6,0.223857625 6.22385763,0 6.5,0 L9.5,0 Z',
chainedSelectionIcon,
},
},
],
Expand Down
21 changes: 21 additions & 0 deletions src/styles/home-button.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
.sn-org-chart {
.sn-org-homebutton {
position: absolute;
top: 20px;
right: 20px;
height: 20px;
width: 20px;
border-color: transparent;
background-color: transparent;
fill: rgba(89, 89, 89, 0.8);
transition: fill 200ms ease-out;

&:hover {
fill: #595959;
}

&.disabled {
display: none;
}
}
}
7 changes: 3 additions & 4 deletions src/tree/box.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ export default function box({
divBox,
nodes,
styling,
expandedState,
setExpandedCallback,
wrapperState,
selectionObj,
Expand All @@ -72,7 +71,7 @@ export default function box({
}) {
const { x, y } = positioning;
const { cardWidth, cardHeight, buttonWidth, buttonHeight, cardPadding, rootDiameter } = constants;
const { topId, isExpanded } = expandedState;
const { topId, isExpanded } = wrapperState.expandedState;
const topNode = nodes.find(node => node.data.id === topId);
const ancestorIds = topNode && topNode.parent ? topNode.parent.ancestors().map(anc => anc.data.id) : [];
const touchmode = document.getElementsByTagName('html')[0].classList.contains('touch-on');
Expand Down Expand Up @@ -139,11 +138,11 @@ export default function box({
})
.on('click', d => {
if (!wrapperState.constraints.active) {
setExpandedCallback(getNewState(d, expandedState, ancestorIds));
setExpandedCallback(getNewState(d, wrapperState.expandedState, ancestorIds));
event.stopPropagation();
}
})
.html(d => `${getSign(d, expandedState, ancestorIds)} ${d.data.children.length}`);
.html(d => `${getSign(d, wrapperState.expandedState, ancestorIds)} ${d.data.children.length}`);

// go up
if (navigationMode !== 'free') {
Expand Down
32 changes: 20 additions & 12 deletions src/tree/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import box from './box';
import createPaths from './path';
import transform, { getBBoxOfNodes, setZooming, getInitialZoomState } from './transform';
import { createTooltip } from './tooltip';
import { homeIcon } from '../utils/svg-icons';

export const filterTree = ({ topId, isExpanded, expandedChildren }, nodeTree, extended) => {
const topNode = nodeTree.descendants().find(node => node.data.id === topId) || nodeTree;
Expand Down Expand Up @@ -52,7 +53,6 @@ export const filterTree = ({ topId, isExpanded, expandedChildren }, nodeTree, ex

export const paintTree = ({
containerData,
expandedState,
styling,
setExpandedCallback,
wrapperState,
Expand All @@ -65,14 +65,13 @@ export const paintTree = ({
divBox.selectAll('*').remove();
svg.selectAll('*').remove();
// filter the nodes the nodes
const nodes = filterTree(expandedState, allNodes);
const nodes = filterTree(wrapperState.expandedState, allNodes);
// Create cards and naviagation buttons
box({
positioning,
divBox,
nodes,
styling,
expandedState,
setExpandedCallback,
wrapperState,
selectionObj,
Expand All @@ -85,24 +84,24 @@ export const paintTree = ({
.selectAll('.sn-org-paths')
.data(nodes)
.enter();
createPaths(node, positioning, expandedState.topId);
createPaths(node, positioning, wrapperState.expandedState.topId);
// Scale and translate
if (navigationMode !== 'free') {
transform(nodes, width, height, svg, divBox, useTransitions);
}
};

export function createContainer({
export const createContainer = ({
element,
dataTree,
selectionObj,
wrapperState,
setInitialZoom,
setTransform,
expandedState,
setExpandedState,
viewState,
}) {
setContainerData,
}) => {
element.innerHTML = '';
element.className = 'sn-org-chart';
let positioning = position('ttb', element, {});
Expand Down Expand Up @@ -135,6 +134,15 @@ export function createContainer({
.append('div')
.attr('class', 'sn-org-nodes');

const homeButton = select(element)
.append('button')
.attr('class', 'sn-org-homebutton disabled')
.on('click', () => {
createContainer({ element, dataTree, selectionObj, wrapperState, setInitialZoom, setTransform, setExpandedState, viewState, setContainerData });
})
.html(homeIcon)
.node();

const tooltip = createTooltip(element);

if (dataTree.error) {
Expand All @@ -161,10 +169,10 @@ export function createContainer({
const allNodes = treemap(hierarchy(dataTree));

const resetExpandedState =
!expandedState || !allNodes.descendants().find(node => node.data.id === expandedState.topId);
!wrapperState.expandedState || !allNodes.descendants().find(node => node.data.id === wrapperState.expandedState.topId);
const newExpandedState = resetExpandedState
? { topId: allNodes.data.id, isExpanded: true, expandedChildren: [], useTransitions: false }
: expandedState;
: wrapperState.expandedState;

const renderNodes = filterTree(newExpandedState, allNodes);
renderNodes.forEach(node => {
Expand All @@ -179,7 +187,7 @@ export function createContainer({
setInitialZoom(initialZoomState);
positioning = position('ttb', element, initialZoomState);
setZooming({
containerData: { svg, divBox, width, height, zoomWrapper, element, tooltip },
containerData: { svg, divBox, width, height, zoomWrapper, element, tooltip, homeButton },
setTransform,
transformState: (viewState && viewState.transform) || {},
wrapperState,
Expand All @@ -189,5 +197,5 @@ export function createContainer({
setExpandedState(newExpandedState);
}

return { svg, divBox, allNodes, positioning, width, height, element, zoomWrapper, tooltip };
}
return setContainerData({ svg, divBox, allNodes, positioning, width, height, element, zoomWrapper, tooltip, homeButton });
};
3 changes: 2 additions & 1 deletion src/tree/transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const applyTransform = (eventTransform, svg, divBox, width, height) => {
};

export function setZooming({ containerData, setTransform, transformState, wrapperState, initialZoomState }) {
const { svg, divBox, width, height, zoomWrapper, element, tooltip } = containerData;
const { svg, divBox, width, height, zoomWrapper, element, tooltip, homeButton } = containerData;
const { x = 0, y = 0 } = transformState;
const { minZoom, maxZoom } = constants;
const zoomFactor = (transformState && 1 / transformState.zoom) || initialZoomState.initialZoom;
Expand All @@ -94,6 +94,7 @@ export function setZooming({ containerData, setTransform, transformState, wrappe
};

const zoomed = () => {
select(homeButton).attr('class', 'sn-org-homebutton lui-fade-button lui-fade-button--large');
setTransform({ zoom: event.transform.k / scaleFactor, x: event.transform.x, y: event.transform.y });
bubbleEvent();
closeTooltip(tooltip);
Expand Down
10 changes: 10 additions & 0 deletions src/utils/svg-icons.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 182894f

Please sign in to comment.