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

Commit

Permalink
Merge branch 'master' into dvr/zooming
Browse files Browse the repository at this point in the history
  • Loading branch information
niekvanstaveren committed Feb 12, 2020
2 parents 294cb49 + 5a3cb00 commit c3ede56
Show file tree
Hide file tree
Showing 21 changed files with 1,158 additions and 1,056 deletions.
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
]
},
"peerDependencies": {
"@nebula.js/supernova": "0.1.0-alpha.29"
"@nebula.js/supernova": "0.1.0-alpha.30"
},
"devDependencies": {
"@after-work.js/aw": "6.0.10",
Expand All @@ -56,7 +56,7 @@
"@babel/preset-env": "7.8.4",
"@commitlint/cli": "8.3.5",
"@commitlint/config-conventional": "8.3.4",
"@nebula.js/cli": "0.1.0-alpha.29",
"@nebula.js/cli": "0.1.0-alpha.30",
"babel-plugin-istanbul": "6.0.0",
"d3": "^5.15.0",
"eslint": "6.8.0",
Expand All @@ -66,6 +66,7 @@
"husky": "4.2.1",
"lint-staged": "10.0.7",
"mocha-junit-reporter": "1.23.3",
"shx": "^0.3.2"
"shx": "^0.3.2",
"less": "^3.11.1"
}
}
5 changes: 5 additions & 0 deletions src/__tests__/default-orgchart-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ const defaultValues = {
data: {
id: '1',
},
children: [{
data: {
id: '2'
}
}],
},
children: [
{
Expand Down
35 changes: 18 additions & 17 deletions src/card/__tests__/card.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ describe('card', () => {
describe('card', () => {
function getHtml(html, selected) {
if (selected === ' selected') {
return `<div class="org-card-textarea${selected}" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
return `<div class="sn-org-card-text${selected}" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
}
if (selected) {
return `<div class="org-card-top" style="background-color:#737373;"></div><div class="org-card-textarea${selected}" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
return `<div class="sn-org-card-top" style="background-color:#737373;"></div><div class="sn-org-card-text${selected}" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
}
return `<div class="org-card-top" style="background-color:#737373;"></div><div class="org-card-textarea" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
return `<div class="sn-org-card-top" style="background-color:#737373;"></div><div class="sn-org-card-text" style="background-color:#e6e6e6;color:#484848;">${html}</div>`;
}
let data;
let cardStyling;
Expand All @@ -75,34 +75,35 @@ describe('card', () => {
data = {
id: 'someId',
attributes: {},
elemNo: 5,
};
cardStyling = { backgroundColor: '#e6e6e6', fontColor: 'default' };
selections = { isActive: () => false };
selections = { api: { isActive: () => false } };
});

it('should return html for root node', () => {
data.id = 'Root';
const result = card(data, cardStyling, selections);
expect(result).to.equal('<div class="org-root"/>');
expect(result).to.equal('<div class="sn-org-root"/>');
});

it('should return html for node with only id', () => {
const result = card(data, cardStyling, selections);
expect(result).to.equal(getHtml(`<div class="org-card-title">${data.id}</div>`));
expect(result).to.equal(getHtml(`<div class="sn-org-card-title">${data.id}</div>`));
});

it('should return html for node with attribute label', () => {
data.attributes.label = 'this is the label';
const result = card(data, cardStyling, selections);
expect(result).to.equal(getHtml('<div class="org-card-title">this is the label</div>'));
expect(result).to.equal(getHtml('<div class="sn-org-card-title">this is the label</div>'));
});

it('should return html for node with id and subLabel', () => {
data.attributes.subLabel = 'subsub';
const result = card(data, cardStyling, selections);
expect(result).to.equal(
getHtml(
`<div class="org-card-title">${data.id}</div><div class="org-card-text">${data.attributes.subLabel}</div>`
`<div class="sn-org-card-title">${data.id}</div><div class="sn-org-card-label">${data.attributes.subLabel}</div>`
)
);
});
Expand All @@ -113,7 +114,7 @@ describe('card', () => {
const result = card(data, cardStyling, selections);
expect(result).to.equal(
getHtml(
`<div class="org-card-title">${data.attributes.label}</div><div class="org-card-text">${data.attributes.subLabel}</div><div class="org-card-text">${data.attributes.extraLabel}</div>`
`<div class="sn-org-card-title">${data.attributes.label}</div><div class="sn-org-card-label">${data.attributes.subLabel}</div><div class="sn-org-card-label">${data.attributes.extraLabel}</div>`
)
);
});
Expand All @@ -125,26 +126,26 @@ describe('card', () => {
const result = card(data, cardStyling, selections);
expect(result).to.equal(
getHtml(
`<div class="org-card-title">${data.attributes.label}</div><div class="org-card-text">${data.attributes.subLabel}</div><div class="org-card-text">${data.measure}</div>`
`<div class="sn-org-card-title">${data.attributes.label}</div><div class="sn-org-card-label">${data.attributes.subLabel}</div><div class="sn-org-card-label">${data.measure}</div>`
)
);
});
it('should return html for node with id and measure', () => {
data.measure = 'measure';
const result = card(data, cardStyling, selections);
expect(result).to.equal(
getHtml(`<div class="org-card-title">${data.id}</div><div class="org-card-text">${data.measure}</div>`)
getHtml(`<div class="sn-org-card-title">${data.id}</div><div class="sn-org-card-label">${data.measure}</div>`)
);
});

it('should return html for selected node in active state', () => {
data.measure = 'measure';
data.selected = true;
selections = { isActive: () => true };
const result = card(data, cardStyling, selections);
selections = { api: { isActive: () => true } };
const result = card(data, cardStyling, selections, [data.elemNo]);
expect(result).to.equal(
getHtml(
`<div class="org-card-title">${data.id}</div><div class="org-card-text">${data.measure}</div>`,
`<div class="sn-org-card-title">${data.id}</div><div class="sn-org-card-label">${data.measure}</div>`,
' selected'
)
);
Expand All @@ -153,11 +154,11 @@ describe('card', () => {
it('should return html for not selected node in active state', () => {
data.measure = 'measure';
data.selected = false;
selections = { isActive: () => true };
const result = card(data, cardStyling, selections);
selections = { api: { isActive: () => true } };
const result = card(data, cardStyling, selections, [7]);
expect(result).to.equal(
getHtml(
`<div class="org-card-title">${data.id}</div><div class="org-card-text">${data.measure}</div>`,
`<div class="sn-org-card-title">${data.id}</div><div class="sn-org-card-label">${data.measure}</div>`,
' not-selected'
)
);
Expand Down
23 changes: 11 additions & 12 deletions src/card/card.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,27 @@ export function getFontColor(cardStyling, backgroundColor) {
return cardStyling.fontColor;
}

export default (data, cardStyling, selections) => {
export default (data, cardStyling, sel, selectionState) => {
const selections = sel.api;
if (data.id === 'Root') {
return '<div class="org-root"/>';
return '<div class="sn-org-root"/>';
}

const isSelected = selections && selections.isActive() && selectionState.indexOf(data.elemNo) !== -1;
const backgroundColor = getBackgroundColor(data, cardStyling);
const topColor = colorUtils.getDarkColor(backgroundColor);
const fontColor = getFontColor(cardStyling, backgroundColor);
const attributes = data.attributes || {};
let html = `<div class="org-card-title">${attributes.label || data.id}</div>`;
let html = `<div class="sn-org-card-title">${attributes.label || data.id}</div>`;
if (attributes.subLabel) {
html += `<div class="org-card-text">${attributes.subLabel}</div>`;
html += `<div class="sn-org-card-label">${attributes.subLabel}</div>`;
}
if (data.measure) {
html += `<div class="org-card-text">${data.measure}</div>`;
html += `<div class="sn-org-card-label">${data.measure}</div>`;
} else if (attributes.extraLabel) {
html += `<div class="org-card-text">${attributes.extraLabel}</div>`;
html += `<div class="sn-org-card-label">${attributes.extraLabel}</div>`;
}
const topbar =
selections.isActive() && data.selected
? ''
: `<div class="org-card-top" style="background-color:${topColor};"></div>`;
const selectedClass = selections.isActive() ? (data.selected ? ' selected' : ' not-selected') : '';
return `${topbar}<div class="org-card-textarea${selectedClass}" style="background-color:${backgroundColor};color:${fontColor};">${html}</div>`;
const topbar = isSelected ? '' : `<div class="sn-org-card-top" style="background-color:${topColor};"></div>`;
const selectedClass = selections && selections.isActive() ? (isSelected ? ' selected' : ' not-selected') : '';
return `${topbar}<div class="sn-org-card-text${selectedClass}" style="background-color:${backgroundColor};color:${fontColor};">${html}</div>`;
};
50 changes: 39 additions & 11 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ import { paintTree, preRenderTree } from './tree/render';
import stylingUtils from './utils/styling';
import treeTransform from './utils/tree-utils';
import { setZooming } from './tree/transform';
import './styles/treeCss.less';
import './styles/paths.less';
import './styles/warnings.less';
import './styles/nodes.less';

export default function supernova(env) {
return {
Expand All @@ -29,23 +33,40 @@ export default function supernova(env) {
const [styling, setStyling] = useState(null);
const [expandedState, setExpandedState] = useState(null);
const [linked, setLinked] = useState(false);
const [selState, setSelState] = useState([]);
const [selectionState, setSelectionState] = useState([]);
const layout = useStaleLayout();
const model = useModel();
const element = useElement();
const Theme = useTheme();
const selectionsAPI = useSelections();
selectionsAPI.refreshSelectionState = setSelState;
const [selections] = useState({ api: selectionsAPI, setState: setSelectionState, linked: false });

const resetSelections = () => {
setSelectionState([]);
};
useEffect(() => {
selections.api = selectionsAPI;
selections.api.on('canceled', resetSelections);
selections.api.on('cleared', resetSelections);
// Return function called on unmount
return () => {
selections.api.removeListener('deactivated', resetSelections);
selections.api.removeListener('canceled', resetSelections);
selections.api.removeListener('cleared', resetSelections);
};
}, [selectionsAPI]);

useAction(
() => ({
action() {
selections.linked = !linked;
setLinked(!linked);
},
icon: {
d:
'M9.5,15 C9.77614237,15 10,15.2238576 10,15.5 C10,15.7761424 9.77614237,16 9.5,16 L6.5,16 C6.22385763,16 6,15.7761424 6,15.5 C6,15.2238576 6.22385763,15 6.5,15 L9.5,15 Z M15.5,13 C15.7761424,13 16,13.2238576 16,13.5 L16,15 C16,15.5522847 15.5522847,16 15,16 L13.5,16 C13.2238576,16 13,15.7761424 13,15.5 C13,15.2238576 13.2238576,15 13.5,15 L14.4,15 C14.7313708,15 15,14.7313708 15,14.4 L15,13.5 C15,13.2238576 15.2238576,13 15.5,13 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 1.28867715e-16,15.5522847 6.123234e-17,15 L1.5308085e-16,13.5 C1.19263162e-16,13.2238576 0.223857625,13 0.5,13 Z M7.5,2.5 L7.5,5.5 L5.5,5.5 L5.5,7.5 L7,7.5 L7,6.5 L12,6.5 L12,9.5 L7,9.5 L7,8.5 L5.5,8.5 L5.5,11.2 C5.5,11.3420161 5.5986801,11.4609842 5.73121275,11.4920768 L5.8,11.5 L9,11.5 L9,10.5 L14,10.5 L14,13.5 L9,13.5 L9,12.5 L5.8,12.5 C5.12690296,12.5 4.57328475,11.9884503 4.50671175,11.3329174 L4.5,11.2 L4.5,5.5 L2.5,5.5 L2.5,2.5 L7.5,2.5 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 M2.5,2.48689958e-14 C2.77614237,2.48689958e-14 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.48689958e-14 1,2.48689958e-14 L2.5,2.48689958e-14 Z M15,2.48689958e-14 C15.5522847,2.48689958e-14 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,2.48689958e-14 13.5,2.48689958e-14 L15,2.48689958e-14 Z M9.5,2.51445413e-14 C9.77614237,2.51614501e-14 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,2.45765414e-14 6.5,2.45934502e-14 L9.5,2.51445413e-14 Z',
},
active: linked,
}),
[linked]
);
Expand All @@ -71,8 +92,9 @@ export default function supernova(env) {
};
}, []);

const setStateCallback = newNode => {
setExpandedState(newNode);
const setStateCallback = newState => {
newState.useTransitions = true;
setExpandedState(newState);
};

/*
Expand All @@ -83,17 +105,14 @@ export default function supernova(env) {
* - render [allNodes, positioning, styling, rect]
*/

useEffect(() => {
selectionsAPI.linked = linked;
}, [linked]);

usePromise(() => {
// Get and transform the data into a tree structure
if (layout && model) {
if (layout) {
return treeTransform({ layout, model }).then(transformed => {
setDataTree(transformed);
setStyling(stylingUtils.cardStyling({ Theme, layout }));
setExpandedState(null);
setSelectionState([]);
});
}
return Promise.resolve();
Expand All @@ -110,16 +129,25 @@ export default function supernova(env) {
topId: preRender.allNodes.data.id,
isExpanded: true,
expandedChildren: [],
useTransitions: false,
});
}
}
}, [element, dataTree]);

useEffect(() => {
if (objectData && expandedState && styling) {
paintTree({ objectData, expandedState, styling, setStateCallback, selectionsAPI, linked });
paintTree({
objectData,
expandedState,
styling,
setStateCallback,
selections,
selectionState,
useTransitions: expandedState.useTransitions,
});
}
}, [expandedState, objectData, selState]);
}, [expandedState, objectData, selectionState]);

useEffect(() => {
if (objectData && layout.navigationMode === 'free') {
Expand Down
72 changes: 72 additions & 0 deletions src/styles/nodes.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.sn-org-chart {
.sn-org-nodes {
position: absolute;
transform-origin: 0% 0%;

&:not(.org-disable-transition) {
transition-property: all;
transition-duration: 0.5s;
}

.sn-org-traverse {
position: absolute;
background-color: white;
font-size: 20px;
font-weight: bold;
border-radius: 3px;
border: 1px solid #8c8c8c;
text-align: center;
line-height: 24px;
}

.sn-org-card {
position: absolute;
.sn-org-root {
background-color: #8c8c8c;
width: 20px;
height: 20px;
border-radius: 20px;
}

.sn-org-card-top {
height: 4px;
width: 100%;
border-radius: 3px 3px 0px 0px;
}
.sn-org-card-text {
height: 60px;
padding-left: 5px;
padding-right: 5px;
border-radius: 0px 0px 3px 3px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
&.selected {
border: 4px solid black;
border-radius: 4px;
}
&.not-selected {
opacity: 0.5;
}
}

.sn-org-card-title {
font-size: 14px;
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.sn-org-card-label {
font-size: 11px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
17 changes: 17 additions & 0 deletions src/styles/paths.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.sn-org-chart {
.sn-org-svg {
position: absolute;

.sn-org-path {
fill: none;
stroke: #8c8c8c;
stroke-width: 1;
}
/* For css only transitions, does not work in IE11 */
.sn-org-paths:not(.org-disable-transition) {
transform-origin: 0% 0%;
transition-property: all;
transition-duration: 0.5s;
}
}
}
Empty file added src/styles/treeCss.less
Empty file.
Loading

0 comments on commit c3ede56

Please sign in to comment.