Initiated Organization Chart
parent
36e9c27028
commit
1c10bdf86d
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="p-organizationchart p-component">
|
<div class="p-organizationchart p-component">
|
||||||
<OrganizationChartNode :node="value" />
|
<OrganizationChartNode :node="value" :templates="$scopedSlots" @node-toggle="onNodeToggle" :collapsedKeys="d_collapsedKeys" :collapsible="collapsible" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -12,6 +12,29 @@ export default {
|
||||||
value: {
|
value: {
|
||||||
type: null,
|
type: null,
|
||||||
default: null
|
default: null
|
||||||
|
},
|
||||||
|
collapsible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
collapsedKeys: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
d_collapsedKeys: this.collapsedKeys || {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onNodeToggle(key) {
|
||||||
|
if (this.d_collapsedKeys[key])
|
||||||
|
delete this.d_collapsedKeys[key];
|
||||||
|
else
|
||||||
|
this.d_collapsedKeys[key] = true;
|
||||||
|
|
||||||
|
this.d_collapsedKeys = {...this.d_collapsedKeys};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
@ -49,6 +72,7 @@ export default {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.p-organizationchart .p-organizationchart-line-down {
|
.p-organizationchart .p-organizationchart-line-down {
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
<tr v-if="node">
|
<tr v-if="node">
|
||||||
<td :colspan="colspan">
|
<td :colspan="colspan">
|
||||||
<div :class="nodeContentClass" @click="onNodeClick">
|
<div :class="nodeContentClass" @click="onNodeClick">
|
||||||
{{node.label}}
|
<OrganizationChartNodeTemplate :node="node" :template="templates[node.type]||templates['default']" />
|
||||||
<a v-if="!leaf" tabindex="0" class="p-node-toggler" @click="toggleNode" @keydown.enter="toggleNode">
|
<a v-if="collapsible && !leaf" tabindex="0" class="p-node-toggler" @click="toggleNode" @keydown.enter="toggleNode">
|
||||||
<i class="p-node-toggler-icon pi" :class="{'pi-chevron-down': node.expanded, 'pi-chevron-up': !node.expanded}"></i>
|
<i class="p-node-toggler-icon pi" :class="{'pi-chevron-down': expanded, 'pi-chevron-up': !expanded}"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -24,14 +24,14 @@
|
||||||
</template>
|
</template>
|
||||||
<template v-if="node.children && node.children.length > 1">
|
<template v-if="node.children && node.children.length > 1">
|
||||||
<template v-for="(child,i) of node.children">
|
<template v-for="(child,i) of node.children">
|
||||||
<td :key="(child.key || child.label) + '_left'" class="p-organizationchart-line-left" :class="{'p-organizationchart-line-top': !(i === 0)}"> </td>
|
<td :key="child.key + '_left'" class="p-organizationchart-line-left" :class="{'p-organizationchart-line-top': !(i === 0)}"> </td>
|
||||||
<td :key="(child.key || child.label) + '_right'" class="p-organizationchart-line-right" :class="{'p-organizationchart-line-top': !(i === (node.children.length - 1))}"> </td>
|
<td :key="child.key + '_right'" class="p-organizationchart-line-right" :class="{'p-organizationchart-line-top': !(i === (node.children.length - 1))}"> </td>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
<tr :style="childStyle" class="p-organizationchart-nodes">
|
<tr :style="childStyle" class="p-organizationchart-nodes">
|
||||||
<td v-for="child of node.children" :key="child.key || child.label" colspan="2">
|
<td v-for="child of node.children" :key="child.key" colspan="2">
|
||||||
<sub-node :node="child" />
|
<sub-node :node="child" :templates="templates" :collapsedKeys="collapsedKeys" @node-toggle="onChildNodeToggle" :collapsible="collapsible" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -39,6 +39,26 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
const OrganizationChartNodeTemplate = {
|
||||||
|
functional: true,
|
||||||
|
props: {
|
||||||
|
node: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
template: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render(createElement, context) {
|
||||||
|
const content = context.props.template({
|
||||||
|
'node': context.props.node
|
||||||
|
});
|
||||||
|
return [content];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'sub-node',
|
name: 'sub-node',
|
||||||
props: {
|
props: {
|
||||||
|
@ -53,6 +73,18 @@ export default {
|
||||||
selectable: {
|
selectable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
},
|
||||||
|
templates: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
collapsible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
collapsedKeys: {
|
||||||
|
type: null,
|
||||||
|
default: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -60,7 +92,10 @@ export default {
|
||||||
|
|
||||||
},
|
},
|
||||||
toggleNode() {
|
toggleNode() {
|
||||||
|
this.$emit('node-toggle', this.node.key);
|
||||||
|
},
|
||||||
|
onChildNodeToggle(key) {
|
||||||
|
this.$emit('node-toggle', key);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -75,9 +110,15 @@ export default {
|
||||||
},
|
},
|
||||||
childStyle() {
|
childStyle() {
|
||||||
return {
|
return {
|
||||||
visibility: !this.leaf && this.node.expanded ? 'inherit' : 'hidden'
|
visibility: !this.leaf && this.expanded ? 'inherit' : 'hidden'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
expanded() {
|
||||||
|
return this.collapsedKeys[this.node.key] === undefined;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
'OrganizationChartNodeTemplate': OrganizationChartNodeTemplate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -9,7 +9,27 @@
|
||||||
|
|
||||||
<div class="content-section implementation">
|
<div class="content-section implementation">
|
||||||
<h3 class="first">Advanced</h3>
|
<h3 class="first">Advanced</h3>
|
||||||
<OrganizationChart :value="data1" />
|
<p>Hierarchical data with zero configuration.</p>
|
||||||
|
<OrganizationChart :value="data1" :collapsible="true" class="company">
|
||||||
|
<template #person="slotProps">
|
||||||
|
<div class="node-header ui-corner-top">{{slotProps.node.data.label}}</div>
|
||||||
|
<div class="node-content">
|
||||||
|
<img :src="'demo/images/organization/' + slotProps.node.data.avatar" width="32">
|
||||||
|
<div>{{slotProps.node.data.name}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #default="slotProps">
|
||||||
|
<span>{{slotProps.node.data.label}}</span>
|
||||||
|
</template>
|
||||||
|
</OrganizationChart>
|
||||||
|
|
||||||
|
<h3>Basic</h3>
|
||||||
|
<p>Hierarchical data with zero configuration.</p>
|
||||||
|
<OrganizationChart :value="data2">
|
||||||
|
<template #default="slotProps">
|
||||||
|
<span>{{slotProps.node.data.label}}</span>
|
||||||
|
</template>
|
||||||
|
</OrganizationChart>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<OrganizationChartDoc />
|
<OrganizationChartDoc />
|
||||||
|
@ -22,102 +42,110 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
data1: {
|
data1: {
|
||||||
label: 'CEO',
|
key: '0',
|
||||||
type: 'person',
|
type: 'person',
|
||||||
className: 'p-person',
|
styleClass: 'p-person',
|
||||||
expanded: true,
|
data: {label: 'CEO', name: 'Walter White', avatar: 'walter.jpg'},
|
||||||
data: {name:'Walter White', 'avatar': 'walter.jpg'},
|
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: 'CFO',
|
key: '0_0',
|
||||||
type: 'person',
|
type: 'person',
|
||||||
className: 'p-person',
|
styleClass: 'p-person',
|
||||||
expanded: true,
|
data: {label: 'CFO', name:'Saul Goodman', avatar: 'saul.jpg'},
|
||||||
data: {name:'Saul Goodman', 'avatar': 'saul.jpg'},
|
|
||||||
children:[{
|
children:[{
|
||||||
label: 'Tax',
|
key: '0_0_0',
|
||||||
className: 'department-cfo'
|
data: {label: 'Tax'},
|
||||||
|
styleClass: 'department-cfo'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Legal',
|
key: '0_0_1',
|
||||||
className: 'department-cfo'
|
data: {label: 'Legal'},
|
||||||
|
styleClass: 'department-cfo'
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'COO',
|
key: '0_1',
|
||||||
type: 'person',
|
type: 'person',
|
||||||
className: 'p-person',
|
styleClass: 'p-person',
|
||||||
expanded: true,
|
data: {label: 'COO', name:'Mike E.', avatar: 'mike.jpg'},
|
||||||
data: {name:'Mike E.', 'avatar': 'mike.jpg'},
|
|
||||||
children:[{
|
children:[{
|
||||||
label: 'Operations',
|
key: '0_1_0',
|
||||||
className: 'department-coo'
|
data: {label: 'Operations'},
|
||||||
|
styleClass: 'department-coo'
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'CTO',
|
key: '0_2',
|
||||||
type: 'person',
|
type: 'person',
|
||||||
className: 'p-person',
|
styleClass: 'p-person',
|
||||||
expanded: true,
|
data: {label: 'CTO', name:'Jesse Pinkman', avatar: 'jesse.jpg'},
|
||||||
data: {name:'Jesse Pinkman', 'avatar': 'jesse.jpg'},
|
|
||||||
children:[{
|
children:[{
|
||||||
label: 'Development',
|
key: '0_2_0',
|
||||||
className: 'department-cto',
|
data: {label: 'Development'},
|
||||||
expanded: true,
|
styleClass: 'department-cto',
|
||||||
children:[{
|
children:[{
|
||||||
label: 'Analysis',
|
key: '0_2_0_0',
|
||||||
className: 'department-cto'
|
data: {label: 'Analysis'},
|
||||||
|
styleClass: 'department-cto'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Front End',
|
key: '0_2_0_1',
|
||||||
className: 'department-cto'
|
data: {label: 'Front End'},
|
||||||
|
styleClass: 'department-cto'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Back End',
|
key: '0_2_0_2',
|
||||||
className: 'department-cto'
|
data: {label: 'Back End'},
|
||||||
|
styleClass: 'department-cto'
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'QA',
|
key: '0_2_1',
|
||||||
className: 'department-cto'
|
data: {label: 'QA'},
|
||||||
|
styleClass: 'department-cto'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'R&D',
|
key: '0_2_2',
|
||||||
className: 'department-cto'
|
data: {label: 'R&D'},
|
||||||
|
styleClass: 'department-cto'
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
data2 : [{
|
data2 : {
|
||||||
label: 'F.C Barcelona',
|
key: '0',
|
||||||
expanded: true,
|
data: {label: 'F.C. Barcelona'},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: 'F.C Barcelona',
|
key: '0_0',
|
||||||
expanded: true,
|
data: {label: 'F.C. Barcelona'},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: 'Chelsea FC'
|
key: '0_0_0',
|
||||||
|
data: {label: 'Chelsea F.C.'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'F.C. Barcelona'
|
key: '0_0_1',
|
||||||
|
data: {label: 'F.C. Barcelona'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Real Madrid',
|
key: '0_1',
|
||||||
expanded: true,
|
data: {label: 'Real Madrid'},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
label: 'Bayern Munich'
|
key: '0_1_0',
|
||||||
|
data: {label: 'Bayern Munich'}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Real Madrid'
|
key: '0_1_1',
|
||||||
|
data: {label: 'Real Madrid'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}],
|
},
|
||||||
selection: []
|
selection: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -126,3 +154,59 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
/deep/ .p-organizationchart {
|
||||||
|
.p-person {
|
||||||
|
padding: 0;
|
||||||
|
border: 0 none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-header, .node-content {
|
||||||
|
padding: .5em .7em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-header {
|
||||||
|
background-color: #495ebb;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-content {
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid #495ebb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-content img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-cfo {
|
||||||
|
background-color: #7247bc;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-coo {
|
||||||
|
background-color: #a534b6;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-cto {
|
||||||
|
background-color: #e9286f;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-organizationchart .p-highlight {
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-person .p-node-toggler {
|
||||||
|
color: #495ebb !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.department-cto .p-node-toggler {
|
||||||
|
color: #8a0a39 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
Loading…
Reference in New Issue