ardhi
2 years ago
6 changed files with 558 additions and 269 deletions
@ -0,0 +1,483 @@ |
|||||||
|
import React, { useEffect, useState } from 'react'; |
||||||
|
import axios from 'axios' |
||||||
|
import { Row, Col, Button } from 'antd'; |
||||||
|
import { |
||||||
|
Chart as ChartJS, |
||||||
|
CategoryScale, |
||||||
|
LineController, |
||||||
|
LineElement, |
||||||
|
LinearScale, |
||||||
|
BarController, |
||||||
|
BarElement, |
||||||
|
PieController, |
||||||
|
Title, |
||||||
|
Tooltip, |
||||||
|
Legend, |
||||||
|
ArcElement |
||||||
|
} from 'chart.js'; |
||||||
|
// import Chart from 'chart.js/auto';
|
||||||
|
import {Chart, Bar, Line, Pie } from 'react-chartjs-2'; |
||||||
|
import ChartDataLabels from 'chartjs-plugin-datalabels'; |
||||||
|
|
||||||
|
ChartJS.register( |
||||||
|
CategoryScale, |
||||||
|
LineController, |
||||||
|
LineElement, |
||||||
|
LinearScale, |
||||||
|
BarController, |
||||||
|
BarElement, |
||||||
|
PieController, |
||||||
|
Title, |
||||||
|
Tooltip, |
||||||
|
Legend, |
||||||
|
ArcElement, |
||||||
|
ChartDataLabels |
||||||
|
); |
||||||
|
|
||||||
|
const styles = { |
||||||
|
cardContainer: {backgroundColor: '#F8F8F8', margin: 2, paddingLeft: 20, paddingRight: 20, paddingTop: 10}, |
||||||
|
cardHeaderContainer: {display: 'flex', flexDirection: 'row', marginBottom: 10}, |
||||||
|
cardChartContainer: {position: 'relative', height: '21vh', margin: 'auto', paddingBottom: 10, justifyContent: 'center'}, |
||||||
|
cardTitle: {color: '#444444', fontSize: 16, fontWeight: 'bold'}, |
||||||
|
cardSubtitle: {color: '#888888', fontSize: 12} |
||||||
|
} |
||||||
|
|
||||||
|
const verticalBarChartOption = { |
||||||
|
elements: { |
||||||
|
bar: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
indexAxis: 'x', |
||||||
|
responsive: true, |
||||||
|
maintainAspectRatio: false, |
||||||
|
plugins: { |
||||||
|
legend: { |
||||||
|
display: true, |
||||||
|
position: 'right', |
||||||
|
labels: { |
||||||
|
boxWidth: 10 |
||||||
|
} |
||||||
|
}, |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const horizontalBarChartOption = { |
||||||
|
indexAxis: 'y', |
||||||
|
elements: { |
||||||
|
bar: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
responsive: true, |
||||||
|
maintainAspectRatio: false, |
||||||
|
plugins: { |
||||||
|
legend: { |
||||||
|
display: false, |
||||||
|
}, |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const pieChartOption = { |
||||||
|
elements: { |
||||||
|
pie: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
responsive: true, |
||||||
|
maintainAspectRatio: false, |
||||||
|
plugins: { |
||||||
|
legend: { |
||||||
|
display: true, |
||||||
|
position: 'right', |
||||||
|
labels: { |
||||||
|
boxWidth: 10 |
||||||
|
} |
||||||
|
}, |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const lineChartOption = { |
||||||
|
elements: { |
||||||
|
line: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
responsive: false, |
||||||
|
plugins: { |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const optionsExpenditure = { |
||||||
|
indexAxis: 'y', |
||||||
|
elements: { |
||||||
|
bar: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
responsive: true, |
||||||
|
maintainAspectRatio: false, |
||||||
|
plugins: { |
||||||
|
legend: { |
||||||
|
display: false, |
||||||
|
position: 'right', |
||||||
|
labels: { |
||||||
|
boxWidth: 10 |
||||||
|
} |
||||||
|
}, |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
// title: {
|
||||||
|
// display: true,
|
||||||
|
// text: 'Chart.js Horizontal Bar Chart',
|
||||||
|
// },
|
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
const optionsScheduleHealthPerDivision = { |
||||||
|
elements: { |
||||||
|
bar: { |
||||||
|
borderWidth: 2, |
||||||
|
}, |
||||||
|
}, |
||||||
|
responsive: false, |
||||||
|
plugins: { |
||||||
|
legend: { |
||||||
|
display: true, |
||||||
|
position: 'top', |
||||||
|
labels: { |
||||||
|
boxWidth: 10 |
||||||
|
} |
||||||
|
}, |
||||||
|
datalabels: { |
||||||
|
color: '#FFFFFF' |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const dataExpenditure = { |
||||||
|
labels: ['Total Budget', 'Expenditure', 'Invoice', 'Cash In'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: '', |
||||||
|
data: [302, 197, 197, 157], |
||||||
|
borderColor: ['#480CA8', '#B5179E', '#A26A16', '#4C4747'], |
||||||
|
backgroundColor: ['#480CA8', '#B5179E', '#A26A16', '#4C4747'], |
||||||
|
borderRadius: 5, |
||||||
|
borderSkipped: false |
||||||
|
} |
||||||
|
], |
||||||
|
}; |
||||||
|
|
||||||
|
const dataScheduleHealthPerDivision = { |
||||||
|
labels: ['Telecommunication Solution Service', 'Telecommunication Solution Product', 'Energy Solution', 'Constructions'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "Behind Schedule", |
||||||
|
data: [1, 0, 0, 0], |
||||||
|
borderColor: '#E80053', |
||||||
|
backgroundColor: '#E80053', |
||||||
|
borderWidth: 2, |
||||||
|
borderRadius: 20, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: "Early Warning", |
||||||
|
data: [2, 0, 1, 1], |
||||||
|
borderColor: '#FFD600', |
||||||
|
backgroundColor: '#FFD600', |
||||||
|
borderWidth: 2, |
||||||
|
borderRadius: 20, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: "On Schedule", |
||||||
|
data: [4, 2, 3, 1], |
||||||
|
borderColor: '#52AC0B', |
||||||
|
backgroundColor: '#52AC0B', |
||||||
|
borderWidth: 2, |
||||||
|
borderRadius: 20, |
||||||
|
borderSkipped: false |
||||||
|
} |
||||||
|
], |
||||||
|
} |
||||||
|
|
||||||
|
const CardExpenditure = ({title, subtitle}) => { |
||||||
|
return ( |
||||||
|
<div style={styles.cardContainer}> |
||||||
|
<div style={styles.cardHeaderContainer}> |
||||||
|
<div style={{flex: 20, display: 'flex', flexDirection: 'column'}}> |
||||||
|
<div style={styles.cardTitle}>{title}</div> |
||||||
|
<div style={styles.cardSubtitle}>{subtitle}</div> |
||||||
|
</div> |
||||||
|
<div style={{flex: 6, display: 'flex', justifyContent: 'center', alignItems: 'center'}}> |
||||||
|
<div style={{backgroundColor: '#DDDDDD', color: '#4C4747', borderRadius: 5, padding: 4, fontWeight: 500, cursor: 'pointer', fontSize: 12, textAlign: 'center', lineHeight: 'normal'}}>Detailed View</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div style={styles.cardChartContainer}> |
||||||
|
<Bar options={optionsExpenditure} data={dataExpenditure} /> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
const CardDashboard = ({title, subtitle, chartType, chartData, chartOption}) => { |
||||||
|
let chart = null; |
||||||
|
if (chartType === 'vertical-bar') { |
||||||
|
chart = <Bar
|
||||||
|
options={chartOption ? chartOption : verticalBarChartOption}
|
||||||
|
data={chartData ? chartData : null} |
||||||
|
/> |
||||||
|
} |
||||||
|
else if (chartType === 'horizontal-bar') { |
||||||
|
chart = <Bar |
||||||
|
options={chartOption ? chartOption : horizontalBarChartOption} |
||||||
|
data={chartData ? chartData : null} |
||||||
|
/> |
||||||
|
} |
||||||
|
else if (chartType === 'pie') { |
||||||
|
chart = <Pie
|
||||||
|
options={chartOption ? chartOption : pieChartOption} |
||||||
|
data={chartData ? chartData : null} |
||||||
|
/> |
||||||
|
} |
||||||
|
else if (chartType === 'line') { |
||||||
|
chart = <Line
|
||||||
|
options={chartOption ? chartOption : lineChartOption} |
||||||
|
data={chartData ? chartData : null} |
||||||
|
/> |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div style={styles.cardContainer}> |
||||||
|
<div style={styles.cardHeaderContainer}> |
||||||
|
<div style={{flex: 20, display: 'flex', flexDirection: 'column'}}> |
||||||
|
<div style={styles.cardTitle}>{title}</div> |
||||||
|
<div style={styles.cardSubtitle}>{subtitle}</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div style={styles.cardChartContainer}> |
||||||
|
{chart} |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const CardScheduleHealthPerDivision = ({title, subtitle, chartData, chartOption}) => { |
||||||
|
return ( |
||||||
|
<div style={styles.cardContainer}> |
||||||
|
<div style={styles.cardHeaderContainer}> |
||||||
|
<div style={{flex: 20, display: 'flex', flexDirection: 'column'}}> |
||||||
|
<div style={styles.cardTitle}>{title}</div> |
||||||
|
<div style={styles.cardSubtitle}>{subtitle}</div> |
||||||
|
</div> |
||||||
|
<div style={{flex: 6, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center'}}> |
||||||
|
<div style={{width: '100%', textAlign: 'center', height: 24, fontSize: 12, verticalAlign: 'middle', cursor: 'pointer', color: '#FFFFFF', backgroundColor: '#777777'}}>Budget</div> |
||||||
|
<div style={{width: '100%', textAlign: 'center', height: 24, fontSize: 12, verticalAlign: 'middle', cursor: 'pointer', color: '#FFFFFF', backgroundColor: '#52AC0B'}} >Schedule</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div style={styles.cardChartContainer}> |
||||||
|
<Bar options={optionsScheduleHealthPerDivision} data={dataScheduleHealthPerDivision} /> |
||||||
|
</div> |
||||||
|
|
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const DashboardBOD = () => { |
||||||
|
const token = localStorage.getItem("token") |
||||||
|
const HEADER = { |
||||||
|
headers: { |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Authorization": `Bearer ${token}` |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div style={{marginLeft: -25, marginRight: -25}}> |
||||||
|
<Row> |
||||||
|
<Col span={8}> |
||||||
|
<CardExpenditure
|
||||||
|
title="Project Expenditure"
|
||||||
|
subtitle="Total Project Expenditure from on-going project." |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col span={16}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project Invoice vs Cash In"
|
||||||
|
subtitle="Total Invoice vs Cash In taken from all project." |
||||||
|
chartType="vertical-bar" |
||||||
|
chartData={{ |
||||||
|
// labels: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'],
|
||||||
|
labels: ["Gedung Tenaga Panel Surya", "Pembangunan Gedung Tower ABC", "Tower Jaringan Jawa Barat", "Tower Jaringan Jawa Timur", "Tower Jaringan Jawa Tengah", "Tower Jaringan Bali", "Project Tower ABC", "Tower Jaringan DKI Jakarta", "Tower Jaringan NTT"], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "This Year", |
||||||
|
data: [16, 8, 12, 10, 13, 12, 10, 10, 8], |
||||||
|
borderColor: '#A36A16', |
||||||
|
backgroundColor: '#A36A16', |
||||||
|
// borderWidth: 2,
|
||||||
|
borderRadius: 5, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
{ |
||||||
|
label: "Last Year", |
||||||
|
data: [1, 1, 7, 6, 10, 9.5, 8, 9, 7.5], |
||||||
|
borderColor: '#4C4747', |
||||||
|
backgroundColor: '#4C4747', |
||||||
|
// borderWidth: 2,
|
||||||
|
borderRadius: 5, |
||||||
|
borderSkipped: false |
||||||
|
} |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col span={8}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project By Financial Health"
|
||||||
|
subtitle="Amount of project grouped by financial health." |
||||||
|
chartType="pie" |
||||||
|
chartData={{ |
||||||
|
labels: ["Cost Overrun", "Early Warning", "On Budget"], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [2, 4, 10], |
||||||
|
borderColor: ["#E80053", "#FFD600", "#52AC0B",], |
||||||
|
backgroundColor: ["#E80053", "#FFD600", "#52AC0B",], |
||||||
|
borderWidth: 2, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col span={8}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project By Schedule Health"
|
||||||
|
subtitle="Amount of project grouped by Schedule health." |
||||||
|
chartType="pie" |
||||||
|
chartData={{ |
||||||
|
labels: ["Behind Schedule", "Early Warning", "On Schedule"], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [1, 3, 11], |
||||||
|
borderColor: ["#E80053", "#FFD600", "#52AC0B"], |
||||||
|
backgroundColor: ["#E80053", "#FFD600", "#52AC0B"], |
||||||
|
borderWidth: 2, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col span={8}> |
||||||
|
<CardScheduleHealthPerDivision
|
||||||
|
title="Project By Schedule Health"
|
||||||
|
subtitle="Amount of project grouped by Schedule health." |
||||||
|
chartData={{ |
||||||
|
labels: ["Behind Schedule", "Early Warning", "On Schedule"], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [1, 3, 11], |
||||||
|
borderColor: ["#E80053", "#FFD600", "#52AC0B"], |
||||||
|
backgroundColor: ["#E80053", "#FFD600", "#52AC0B"], |
||||||
|
borderWidth: 2, |
||||||
|
borderRadius: 5, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
<Row> |
||||||
|
<Col span={8}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project By Phase"
|
||||||
|
subtitle="Progress of project from multiple division." |
||||||
|
chartType="horizontal-bar" |
||||||
|
chartData={{ |
||||||
|
labels: ["Initiation", "Planning", "Execution", "Control Monitoring", "Close"], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [3, 1, 2, 3, 7], |
||||||
|
borderColor: ["#F74B25", "#B5179E", "#7209B7", "#023E8A", "#3B009A"], |
||||||
|
backgroundColor: ["#F74B25", "#B5179E", "#7209B7", "#023E8A", "#3B009A"], |
||||||
|
borderWidth: 2, |
||||||
|
borderRadius: 5, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col span={8}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project By Division"
|
||||||
|
subtitle="Amount of project from multiple division." |
||||||
|
chartType="pie" |
||||||
|
chartData={{ |
||||||
|
labels: ['Telecommunication Solution Service', 'Telecommunication Solution Product', 'Energy Solution', 'Constructions'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [7, 2, 4, 3], |
||||||
|
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"], |
||||||
|
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"], |
||||||
|
borderWidth: 2, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
<Col span={8}> |
||||||
|
<CardDashboard
|
||||||
|
title="Project Value By Division"
|
||||||
|
subtitle="Value of project from multiple division." |
||||||
|
chartType="pie" |
||||||
|
chartData={{ |
||||||
|
labels: [['Telecommunication', 'Solution Service'], ['Telecommunication','Solution Product'], 'Energy Solution', 'Constructions'], |
||||||
|
datasets: [ |
||||||
|
{ |
||||||
|
label: "", |
||||||
|
data: [50, 120, 72, 60], |
||||||
|
borderColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"], |
||||||
|
backgroundColor: ["#023E8A", "#C851B7", "#FD7034", "#3A0CA3"], |
||||||
|
borderWidth: 2, |
||||||
|
borderSkipped: false |
||||||
|
}, |
||||||
|
], |
||||||
|
}} |
||||||
|
/> |
||||||
|
</Col> |
||||||
|
</Row> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default DashboardBOD; |
@ -1,65 +0,0 @@ |
|||||||
import React, { useEffect, useState } from 'react'; |
|
||||||
import axios from 'axios' |
|
||||||
import { Bar } from 'react-chartjs-2'; |
|
||||||
|
|
||||||
const labels = ['January', 'February', 'March', 'April', 'May', 'June', 'July']; |
|
||||||
|
|
||||||
const data = { |
|
||||||
labels, |
|
||||||
datasets: [ |
|
||||||
{ |
|
||||||
label: 'Dataset 1', |
|
||||||
borderColor: 'rgb(255, 99, 132)', |
|
||||||
backgroundColor: 'rgba(255, 99, 132, 0.5)', |
|
||||||
data: [] |
|
||||||
}, |
|
||||||
{ |
|
||||||
label: 'Dataset 2', |
|
||||||
borderColor: 'rgb(53, 162, 235)', |
|
||||||
backgroundColor: 'rgba(53, 162, 235, 0.5)', |
|
||||||
}, |
|
||||||
], |
|
||||||
}; |
|
||||||
|
|
||||||
|
|
||||||
const options = { |
|
||||||
indexAxis: 'y', |
|
||||||
elements: { |
|
||||||
bar: { |
|
||||||
borderWidth: 2, |
|
||||||
}, |
|
||||||
}, |
|
||||||
responsive: true, |
|
||||||
plugins: { |
|
||||||
legend: { |
|
||||||
position: 'right', |
|
||||||
}, |
|
||||||
title: { |
|
||||||
display: true, |
|
||||||
text: 'Chart.js Horizontal Bar Chart', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
const DashboardPMO = () => { |
|
||||||
const token = localStorage.getItem("token") |
|
||||||
const HEADER = { |
|
||||||
headers: { |
|
||||||
"Content-Type": "application/json", |
|
||||||
"Authorization": `Bearer ${token}` |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return ( |
|
||||||
<> |
|
||||||
<div> |
|
||||||
<Bar |
|
||||||
options={options} |
|
||||||
data={data} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
</> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
export default DashboardPMO; |
|
Loading…
Reference in new issue