import React, { Component } from 'react' import ReactSpeedometer from "react-d3-speedometer" import { GridList, GridListTile, Checkbox, FormControlLabel, Menu, Paper, Typography, Button } from '@material-ui/core' import Images from '../../assets/Images' import LineChart from 'react-linechart'; import { titleCase } from '../../library/Utils'; import NumberFormat from 'react-number-format'; import { tr } from 'date-fns/locale'; import ReactECharts from 'echarts-for-react'; import api from '../../api'; export default class ExceutiveScoreboard extends Component { constructor(props) { super(props) this.state = { listDummy: [ { judul: "Overall", kpi: 0, rank: 'BS', value: 3.67, status: 'up' }, { judul: "Financial", kpi: 5, rank: 'BS', value: 3.67, status: 'up' }, { judul: "Customer Perspective", kpi: 2, rank: 'B', value: 3.05, status: 'down' }, { judul: "Internal Perspective", kpi: 5, rank: 'C', value: 2.61, status: 'down' }, { judul: "Financial", kpi: 5, rank: 'B+', value: 3.52, status: 'up' }, ], arraySpeedo: [], data: this.props.data, newData: [], dataPayload: this.props.dataPayload, selectIndex: null, loading: false, listKPI: [], selectedKPI: this.props.selectedKPI, listDetailKPI: [], checkAll: true, checkYTD: true, checkAB: true, checkYoy: true, loading2: false, newDataParent: [] } } componentDidMount() { // console.log() console.log(this.state.dataPayload) this.setState({ loading: true, loading2: true }) this.olahDataChart() this.getDetailDashboardCAT() } olahDataChart() { let listKPI = [] let newDataParent = [] this.state.data.executive_scoreboard.category.map((item, index) => { let perfomanceScore = 'K' let lastTotal = Number(item.current_value).toFixed(2) if (lastTotal >= 1.00 && lastTotal <= 2.00) { perfomanceScore = 'K' } else if (lastTotal >= 2.01 && lastTotal <= 2.75) { perfomanceScore = 'C' } else if (lastTotal >= 2.76 && lastTotal <= 3.00) { perfomanceScore = 'B-' } else if (lastTotal >= 3.01 && lastTotal <= 3.75) { perfomanceScore = 'B' } else if (lastTotal >= 3.76 && lastTotal <= 4.00) { perfomanceScore = 'B+' } else if (lastTotal >= 4.01 && lastTotal <= 4.75) { perfomanceScore = 'BS' } else if (lastTotal >= 4.76 && lastTotal <= 5.00) { perfomanceScore = 'IST' } newDataParent.push({ ...item, current_value: Number(item.current_value).toFixed(2), perfomanceScore }) }) console.log(newDataParent) this.state.data.kpi.category.map((item, index) => { if (item.nodes.length > 0) { item.nodes.map((items, indexs) => { listKPI.push(items.item_name) }) } }) this.setState({ loading: false, listKPI, newDataParent }) } handleValueChild(item) { let data = this.state.newData.filter((val) => val.parent != null) let indexID = data.findIndex((val) => val.item_name == item.item_name) let indexMonthID = data[indexID].month.findIndex((val) => val.name == `month${this.state.dataPayload.month.month_id}`) return data[indexID].month[indexMonthID].value == null ? 0 : data[indexID].month[indexMonthID].value } handleValueSpeedo(item) { let indexMonthID = item.month.findIndex((val) => val.name == `month${this.state.dataPayload.month.month_id}`) return item.month[indexMonthID].value } handleListKPI(item) { let list = this.state.selectedKPI let indexID = list.findIndex((val) => val == item) if (indexID == -1) { if (list.length < 4) { list.push(item) } } else { list.splice(indexID, 1) } this.props.setSelectedKPI(list) this.getDetailDashboardCAT() // this.setState({ selectedKPI: list }, () => { this.getDetailDashboardCAT() }) } getDetailDashboardCAT() { this.setState({ loading2: true }) let payload = { "company_id": this.state.dataPayload.company.company_id, "periode": this.state.dataPayload.periode.periode, "months": this.state.dataPayload.month.month_id, "checklist": this.state.selectedKPI } console.log(payload) api.create().getDashboardCATDetail(payload).then((res) => { if (res.data) { let responseArray = res.data.data.executive_scoreboard.category // let newArr = [] // responseArray.map((item,index) => { // if // }) let aa = responseArray.filter((val) => this.state.selectedKPI.includes(val.category_name)) console.log(aa) let arrayNew = [] aa.map((item, index) => { let act = [] let mbv = [] let yoy = [] let minACT = 0 let maxACT = 0 let minMBV = 0 let maxMBV = 0 let minYOY = 0 let maxYOY = 0 item.nodes.map((items, indexs) => { act.push(items.nodes_actual_value) mbv.push(items.nodes_mb_value) yoy.push(items.nodes_yoy_value) if (minACT > items.nodes_actual_value) { minACT = items.nodes_actual_value } if (maxACT < items.nodes_actual_value) { maxACT = items.nodes_actual_value } if (minMBV > items.nodes_mb_value) { minMBV = items.nodes_mb_value } if (maxMBV < items.nodes_mb_value) { maxMBV = items.nodes_mb_value } if (minYOY > items.nodes_yoy_value) { minYOY = items.nodes_yoy_value } if (maxYOY < items.nodes_yoy_value) { maxYOY = items.nodes_yoy_value } }) let sortMin = [] let sortMax = [] if (this.state.checkAll) { sortMin = [minACT, minMBV, minYOY].sort((a, b) => a - b) sortMax = [maxACT, maxMBV, maxYOY].sort((a, b) => b - a) } else if (this.state.checkAB && this.state.checkYTD && !this.state.checkYoy) { sortMin = [minACT, minMBV].sort((a, b) => a - b) sortMax = [maxACT, maxMBV].sort((a, b) => b - a) } else if (this.state.checkAB && !this.state.checkYTD && this.state.checkYoy) { sortMin = [minACT, minYOY].sort((a, b) => a - b) sortMax = [maxACT, maxYOY].sort((a, b) => b - a) } else if (this.state.checkAB && !this.state.checkYTD && !this.state.checkYoy) { sortMin = [minMBV] sortMax = [maxMBV] } else if (!this.state.checkAB && this.state.checkYTD && this.state.checkYoy) { sortMin = [minMBV, minYOY].sort((a, b) => a - b) sortMax = [maxMBV, maxYOY].sort((a, b) => b - a) } else if (!this.state.checkAB && this.state.checkYTD && !this.state.checkYoy) { sortMin = [minMBV] sortMax = [maxMBV] } else if (!this.state.checkAB && !this.state.checkYTD && this.state.checkYoy) { sortMin = [minYOY] sortMax = [maxYOY] } let options = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, legend: { data: this.state.checkAll ? ['Actual', 'MB', 'Yoy'] : (this.state.checkAB && this.state.checkYTD && !this.state.checkYoy ? ['Actual', 'MB'] : (this.state.checkAB && !this.state.checkYTD && this.state.checkYoy ? ['Actual', 'Yoy'] : (this.state.checkAB && !this.state.checkYTD && !this.state.checkYoy ? ['Actual'] : (!this.state.checkAB && this.state.checkYTD && this.state.checkYoy ? ['MB', 'Yoy'] : (!this.state.checkAB && this.state.checkYTD && !this.state.checkYoy ? ['MB'] : ['Yoy']))))) }, grid: { left: 0, bottom: 0 }, xAxis: { type: 'category', data: this.props.selectedMonth }, yAxis: { type: 'value', min: sortMin[0] - 0.5, max: sortMax[0] + 0.5, }, series: this.state.checkAll ? [ { name: 'Actual', data: act, type: 'line' }, { name: 'MB', data: mbv, type: 'line' }, { name: 'Yoy', data: yoy, type: 'line' } ] : this.state.checkAB && this.state.checkYTD && !this.state.checkYoy ? [ { name: 'Actual', data: act, type: 'line' }, { name: 'MB', data: mbv, type: 'line' }, ] : this.state.checkAB && !this.state.checkYTD && this.state.checkYoy ? [ { name: 'Actual', data: act, type: 'line' }, { name: 'Yoy', data: yoy, type: 'line' } ] : this.state.checkAB && !this.state.checkYTD && !this.state.checkYoy ? [ { name: 'Actual', data: act, type: 'line' }, ] : !this.state.checkAB && this.state.checkYTD && this.state.checkYoy ? [ { name: 'MB', data: mbv, type: 'line' }, { name: 'Yoy', data: yoy, type: 'line' } ] : !this.state.checkAB && this.state.checkYTD && !this.state.checkYoy ? [ { name: 'MB', data: mbv, type: 'line' }, ] : [ { name: 'Yoy', data: yoy, type: 'line' } ] } arrayNew.push({ ...item, options}) }) console.log(arrayNew) console.log(this.state.checkAll) this.setState({ listDetailKPI: arrayNew }, () => { setTimeout(() => { this.setState({loading2: false}) }, 500); }) // console.log(aa) } }) } handleBackgroundPerform(total) { let color = 'white' if (total >= 1.00 && total <= 2.00) { color = 'red' } else if (total >= 2.01 && total <= 2.75) { color = 'yellow' } else if (total >= 2.76 && total <= 3.00) { color = 'lightgreen' } else if (total >= 3.01 && total <= 3.75) { color = 'yellowgreen' } else if (total >= 3.76 && total <= 4.00) { color = 'forestgreen' } else if (total >= 4.01 && total <= 4.75) { color = 'deepskyblue' } else if (total >= 4.76 && total <= 5.00) { color = 'dodgerblue' } return color } render() { let { selectIndex } = this.state let yuk = [1, 2, 3] const data = [ { color: "steelblue", points: [ { x: 1, y: 4.1 }, { x: 2, y: 0 }, { x: 3, y: 3 }, { x: 4, y: 0 }, { x: 5, y: -2 }, { x: 6, y: 5 }, { x: 7, y: 4 }, ] } ]; const optionzzz = { tooltip: { trigger: 'axis', axisPointer: { type: 'cross', crossStyle: { color: '#999' } } }, grid: { left: 0, bottom: 0 }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [{ data: [150, 230, 224, 218, 135, 147, 260], type: 'line' }] }; return ( <div style={{ padding: 20 }}> <div style={{ display: 'flex', width: '100%', justifyContent: 'space-between', flexFlow: 'wrap' }}> {!this.state.loading && this.state.newDataParent.map((item, index) => { return ( <div style={{ padding: 10, backgroundColor: this.state.selectIndex === index ? '#6885a6' : '#fff', borderRadius: 6, paddingBottom: 20, margin: 10, boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.25)', width: 250 }}> {/* <span style={{ fontSize: '17px', color: this.state.selectIndex === index ? '#fff' : '#7e8085', maxWidth: 100 }}>{item.category_name}</span> */} <div style={{ fontSize: '17px', width: '100%' }}> <Typography style={{ textAlign: 'left' }}>{titleCase(String(item.category_name).toLocaleLowerCase())}</Typography> </div> {item.total_kpi != null && <div style={{ width: '100%', display: 'flex', justifyContent: 'center', marginTop: String(item.category_name).toLocaleLowerCase().includes('internal') ? 0 : 25 }}> <span style={{ textAlign: 'center', fontSize: '18px', color: selectIndex === index ? "#fff" : '#4b4b4b' }}>{item.total_kpi}</span> {/* <span style={{ textAlign: 'center', fontSize: '11px', color: selectIndex === index ? "#fff" : '#4b4b4b' }}>KPIs</span> */} </div>} <div style={{ display: 'flex', justifyContent: 'center', marginTop: String(item.category_name).toLocaleLowerCase() == 'overall' ? 50 : 0 }}> <div style={{ backgroundColor: this.handleBackgroundPerform(Number(item.current_value).toFixed(2)), textAlign: 'center', display: 'flex', justifyContent: 'center', width: 40, height: 21 }}> <Typography style={{ textAlign: 'center' }}>{item.performance}</Typography> </div> </div> <div style={{ display: 'flex', justifyContent: 'center' }}> <ReactSpeedometer maxSegmentLabels={0} segmentColors={[ this.handleBackgroundPerform(Number(item.current_value).toFixed(2)), "#d8d8d8" ]} needleColor={this.state.selectIndex === index ? "#fff" : '#4b4b4b'} value={Number(item.current_value).toFixed(2)} valueFormat={'.2f'} minValue={Number(item.low)} maxValue={Number(item.high)} customSegmentStops={[0, Number(item.current_value).toFixed(2), 5]} width={200} height={140} ringWidth={25} textColor={selectIndex === index ? "#fff" : '#4b4b4b'} /> </div> <div style={{ backgroundColor: 'transparent', display: 'flex', marginTop: 20, placeContent: 'center' }}> {item.is_higher == '-' ? <div style={{ textAlign: '-webkit-center' }}> <Typography style={{ fontSize: 16, color: '#4b4b4b' }}> - </Typography> </div> : <div style={{ textAlign: '-webkit-center' }}> {item.is_higher == 'true' ? <img src={Images.up} /> : <img src={Images.down} />} <Typography style={{ fontSize: 16, color: '#4b4b4b' }}>vs Last Month</Typography> </div> } </div> </div> ) })} </div> <div style={{ display: 'flex', marginTop: 15 }}> <div> <Button aria-controls="simple-menu" aria-haspopup="true" onClick={(e) => this.setState({ openMenuKPI: e.currentTarget })}> KPI List </Button> <Menu id="simple-menu" anchorEl={this.state.openMenuKPI} keepMounted open={Boolean(this.state.openMenuKPI)} onClose={() => this.setState({ openMenuKPI: false })} > <div style={{ padding: 20 }}> <div style={{ display: 'flex', borderBottom: 'solid 3px #979696' }}> <FormControlLabel control={ <Checkbox checked={this.state.deleteKPIList} onChange={() => { this.setState({ deleteKPIList: !this.state.deleteKPIList }, () => { this.props.setSelectedKPI(this.state.deleteKPIList ? [] : this.state.selectedKPI) // this.setState({ selectedKPI: this.state.deleteKPIList ? [] : this.state.selectedKPI }) }) }} name="checkedB" color="primary" /> } label={"Hapus Semua"} /> </div> <div style={{ display: 'grid' }}> {this.state.listKPI.map((item, index) => { return ( <FormControlLabel control={ <Checkbox checked={this.state.selectedKPI.includes(item)} onChange={() => { this.handleListKPI(item) }} name="checkedB" color="primary" /> } label={item} /> ) })} </div> </div> </Menu> </div> <div> <Button aria-controls="simple-menu" aria-haspopup="true" onClick={(e) => this.setState({ openMenu: e.currentTarget })}> Filter </Button> <Menu id="simple-menu" anchorEl={this.state.openMenu} keepMounted open={Boolean(this.state.openMenu)} onClose={() => this.setState({ openMenu: false })} > <div style={{ padding: 20 }}> <div style={{ display: 'flex', borderBottom: 'solid 3px #979696' }}> <FormControlLabel control={ <Checkbox checked={this.state.checkAll} onChange={() => { this.setState({ checkAll: true, checkYTD: true, checkAB: true, checkYoy: true }, () => { this.getDetailDashboardCAT() }) }} name="checkedB" color="primary" /> } style={{ marginRight: 20 }} label={"Pilih Semua"} /> <FormControlLabel control={ <Checkbox checked={!this.state.checkAll && !this.state.checkYoy && !this.state.checkAB && !this.state.checkYTD} onChange={() => { this.setState({ checkAll: false, checkYTD: false, checkAB: false, checkYoy: false }, () => { this.getDetailDashboardCAT() }) }} name="checkedB" color="primary" /> } label={"Hapus Semua"} /> </div> <div style={{ display: 'grid' }}> <FormControlLabel control={ <Checkbox checked={this.state.checkYTD} onChange={() => { this.setState({ checkYTD: !this.state.checkYTD }, () => { this.setState({ checkAll: this.state.checkYoy && this.state.checkAB && this.state.checkYTD }, () => { this.getDetailDashboardCAT() }) }) }} name="checkedB" color="primary" /> } label={"Tren YTD"} /> <FormControlLabel control={ <Checkbox checked={this.state.checkAB} onChange={() => { this.setState({ checkAB: !this.state.checkAB }, () => { this.setState({ checkAll: this.state.checkYoy && this.state.checkAB && this.state.checkYTD }, () => { this.getDetailDashboardCAT() }) }) }} name="checkedB" color="primary" /> } label={"Actual vs Budget"} /> <FormControlLabel control={ <Checkbox checked={this.state.checkYoy} onChange={() => { this.setState({ checkYoy: !this.state.checkYoy }, () => { this.setState({ checkAll: this.state.checkYoy && this.state.checkAB && this.state.checkYTD }, () => { this.getDetailDashboardCAT() }) }) }} name="checkedB" color="primary" /> } label={"Yoy"} /> </div> </div> </Menu> </div> </div> <div style={{ padding: 10, marginTop: 10, display: 'flex', width: '100%' }}> {/* <div style={{ maxWidth: 566, boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.25)', padding: 20, marginLeft: 5, marginTop: 5, marginRight: 5, display: 'inline-grid' }}> <div> <span style={{ fontSize: 17 }}>{'kuntul'}</span> <Typography style={{ fontSize: 24, fontWeight: 'bold' }}><NumberFormat value={123345} displayType={'text'} thousandSeparator={true} prefix={'Rp. '} /></Typography> <Typography style={{ fontSize: 16, fontWeight: 'bold' }}>In IDR mn</Typography> </div> <div style={{ marginTop: -50 }}> <LineChart width={400} height={250} data={data} // yMin={0} // yMax={10} hideXAxis={true} hideYAxis={true} hideXLabel={true} hideYLabel={true} /> </div> </div> */} <GridList cellHeight={500} cols={2}> {this.state.listDetailKPI.map((item, index) => { return ( <GridListTile key={item} cols={this.state.listDetailKPI.length == 1 ? 2 : 1} style={{ marginBottom: 10 }}> {!this.state.loading2 && <div style={{ width: 600, boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.25)', padding: 20, marginLeft: 15, marginTop: index > 1 ? 20 : 5, marginRight: 5, display: 'inline-grid' }}> <div> <span style={{ fontSize: 17 }}>{item.category_name}</span> <Typography style={{ fontSize: 24, fontWeight: 'bold' }}><NumberFormat value={item.current_value} displayType={'text'} thousandSeparator={true} /></Typography> <Typography style={{ fontSize: 16, fontWeight: 'bold' }}>{item.uom}</Typography> </div> <div style={{}}> {(this.state.checkAB || this.state.checkYTD || this.state.checkYoy) && !this.state.loading && <ReactECharts showLoading={this.state.loading2} lazyUpdate style={{ height: 350, width: '100%', marginTop: 20 }} option={item.options} />} </div> </div>} </GridListTile> ) } )} </GridList> </div> {/* <div style={{ width: 566, height: 233, boxShadow: '0 1px 4px 0 rgba(0, 0, 0, 0.25)', padding: 20, justifyContent: 'space-between', display: 'grid', margin: 10 }}> <div> <span style={{ fontSize: 17 }}>YTD Revenue</span> <Typography style={{ fontSize: 24, fontWeight: 'bold' }}>1,016,489.78</Typography> <Typography style={{ fontSize: 16, fontWeight: 'bold' }}>In IDR mn</Typography> </div> <LineChart width={400} height={50} data={data} yMin={0} yMax={10} hideXAxis={true} hideYAxis={true} hideXLabel={true} hideYLabel={true} /> </div> */} </div> ) } }