Browse Source

react-chartjs 공통 컴포넌트 작업

master
박상현 8 months ago
parent
commit
29b7003f39
  1. 53
      src/components/analysis/history/AnalysisHistoryDetailStatic.js
  2. 160
      src/components/charts/chart-js/ChartjsAreaChart.js
  3. 117
      src/components/charts/chart-js/ChartjsBarChart.js
  4. 124
      src/components/charts/chart-js/ChartjsDoughnutChart.js
  5. 185
      src/components/charts/chart-js/ChartjsLineChart.js
  6. 6
      src/components/dashboard/DashboardStcsArea.js
  7. 4
      src/components/dashboard/DashboardStcsDay.js
  8. 13
      src/components/statistics/StatisticsSearch.js

53
src/components/analysis/history/AnalysisHistoryDetailStatic.js

@ -1,20 +1,7 @@
import { useEffect, useState } from 'react';
import { Line } from 'react-chartjs-2';
import { useSelector } from 'react-redux';
import {
Card,
CardHeader,
CardTitle,
CardBody,
CardSubtitle,
Button,
Row,
Col
} from 'reactstrap';
import { Card, CardBody, Row, Col } from 'reactstrap';
import ChartjsLineChart from '../../charts/chart-js/ChartjsLineChart';
export const AnalysisHistoryDetailStatic = props => {
// const { log } = useSelector(state => state.analysisHistoryState);
const [chartData, setChartData] = useState({});
useEffect(() => {
@ -83,16 +70,6 @@ export const AnalysisHistoryDetailStatic = props => {
});
};
const plugins = [
{
beforeInit(chart) {
chart.legend.afterFit = function () {
this.height += 20;
};
}
}
];
const options = {
responsive: true,
maintainAspectRatio: false,
@ -201,18 +178,18 @@ export const AnalysisHistoryDetailStatic = props => {
};
return (
<div className='pal-card-box'>
<Row>
<Col>
<Card>
<CardBody className='pal-card-body'>
<div style={{ height: '300px' }}>
<Line data={chartData} options={options} plugins={plugins} />
</div>
</CardBody>
</Card>
</Col>
</Row>
</div>
<div className='pal-card-box'>
<Row>
<Col>
<Card>
<CardBody className='pal-card-body'>
<div style={{ height: '300px' }}>
<ChartjsLineChart data={chartData} options={options} />
</div>
</CardBody>
</Card>
</Col>
</Row>
</div>
);
};

160
src/components/charts/chart-js/ChartjsAreaChart.js vendored

@ -1,148 +1,32 @@
import { Line } from 'react-chartjs-2'
import Flatpickr from 'react-flatpickr'
import { Calendar } from 'react-feather'
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
import { Line } from 'react-chartjs-2';
import Flatpickr from 'react-flatpickr';
import { Calendar } from 'react-feather';
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap';
const ChartjsAreaChart = ({ labelColor, tooltipShadow, gridLineColor, blueColor, blueLightColor, greyLightColor }) => {
const ChartjsAreaChart = ({
labelColor,
tooltipShadow,
gridLineColor,
blueColor,
blueLightColor,
greyLightColor
}) => {
const options = {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'top',
align: 'start',
labels: {
usePointStyle: true,
padding: 25,
boxWidth: 9
}
},
layout: {
padding: {
top: -20,
bottom: -20,
left: -20
}
},
tooltips: {
// Updated default tooltip UI
shadowOffsetX: 1,
shadowOffsetY: 1,
shadowBlur: 8,
shadowColor: tooltipShadow,
backgroundColor: '#fff',
titleFontColor: '#000',
bodyFontColor: '#000'
},
scales: {
xAxes: [
{
display: true,
gridLines: {
color: 'transparent',
zeroLineColor: gridLineColor
},
scaleLabel: {
display: true
},
ticks: {
fontColor: labelColor
}
}
],
yAxes: [
{
display: true,
gridLines: {
color: 'transparent',
zeroLineColor: gridLineColor
},
ticks: {
stepSize: 100,
min: 0,
max: 400,
fontColor: labelColor
},
scaleLabel: {
display: true
}
}
]
}
options
},
data = {
labels: [
'7/12',
'8/12',
'9/12',
'10/12',
'11/12',
'12/12',
'13/12',
'14/12',
'15/12',
'16/12',
'17/12',
'18/12',
'19/12',
'20/12',
''
],
datasets: [
{
label: 'Africa',
data: [40, 55, 45, 75, 65, 55, 70, 60, 100, 98, 90, 120, 125, 140, 155],
lineTension: 0,
backgroundColor: blueColor,
pointStyle: 'circle',
borderColor: 'transparent',
pointRadius: 0.5,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBackgroundColor: blueColor,
pointHoverBorderColor: '#fff'
},
{
label: 'Asia',
data: [70, 85, 75, 150, 100, 140, 110, 105, 160, 150, 125, 190, 200, 240, 275],
lineTension: 0,
backgroundColor: blueLightColor,
pointStyle: 'circle',
borderColor: 'transparent',
pointRadius: 0.5,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBackgroundColor: blueLightColor,
pointHoverBorderColor: '#fff'
},
{
label: 'Europe',
data: [240, 195, 160, 215, 185, 215, 185, 200, 250, 210, 195, 250, 235, 300, 315],
lineTension: 0,
backgroundColor: greyLightColor,
pointStyle: 'circle',
borderColor: 'transparent',
pointRadius: 0.5,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBackgroundColor: greyLightColor,
pointHoverBorderColor: '#fff'
}
]
}
data
};
//** To add spacing between legends and chart
const plugins = [
{
beforeInit(chart) {
chart.legend.afterFit = function () {
this.height += 20
}
this.height += 20;
};
}
}
]
];
return (
<Card>
@ -161,11 +45,11 @@ const ChartjsAreaChart = ({ labelColor, tooltipShadow, gridLineColor, blueColor,
</CardHeader>
<CardBody>
<div style={{ height: '450px' }}>
<Line data={data} options={options} height={450} plugins={plugins} />
<Line data={data} options={options} plugins={plugins} />
</div>
</CardBody>
</Card>
)
}
);
};
export default ChartjsAreaChart
export default ChartjsAreaChart;

117
src/components/charts/chart-js/ChartjsBarChart.js vendored

@ -1,109 +1,14 @@
import React, { useState } from 'react'
import Flatpickr from 'react-flatpickr'
import DatePicker from "react-datepicker";
import { Calendar } from 'react-feather'
import { Bar } from 'react-chartjs-2'
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
import { ko } from 'date-fns/esm/locale'
import "react-datepicker/dist/react-datepicker.css";
const ChartjsBarChart = ({ tooltipShadow, gridLineColor, labelColor, successColorShade }) => {
const [startDate, setStartDate] = useState(new Date());
const options = {
elements: {
rectangle: {
borderWidth: 2,
borderSkipped: 'bottom'
}
},
responsive: true,
maintainAspectRatio: false,
responsiveAnimationDuration: 500,
legend: {
display: false
},
tooltips: {
// Updated default tooltip UI
shadowOffsetX: 1,
shadowOffsetY: 1,
shadowBlur: 8,
shadowColor: tooltipShadow,
backgroundColor: '#fff',
titleFontColor: '#000',
bodyFontColor: '#000'
},
scales: {
xAxes: [
{
display: true,
gridLines: {
display: true,
color: gridLineColor,
zeroLineColor: gridLineColor
},
scaleLabel: {
display: false
},
ticks: {
fontColor: labelColor
}
}
],
yAxes: [
{
display: true,
gridLines: {
color: gridLineColor,
zeroLineColor: gridLineColor
},
ticks: {
stepSize: 100,
min: 0,
max: 400,
fontColor: labelColor
}
}
]
}
},
data = {
labels: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31'],
datasets: [
{
data: [275, 90, 190, 205, 125, 85, 55, 87, 127, 150, 230, 280, 190, 220, 100, 300, 250, 10, 20, 30, 40, 50, 60],
backgroundColor: successColorShade,
borderColor: 'transparent',
barThickness: 15
}
]
}
import { Bar } from 'react-chartjs-2';
const ChartjsBarChart = ({ data, options, plugins = [], topData = null }) => {
return (
<Card>
<CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
<CardTitle tag='h4'> 비행횟수 통계</CardTitle>
<div className='datepicker-border-sm'>
<div className='datepicker-custom'>
<Calendar size={14} />
<DatePicker
locale={ko}
selected={startDate}
onChange={(date) => setStartDate(date)}
dateFormat="yyy / MMMM"
showMonthYearPicker
showFullMonthYearPicker
showFourColumnMonthYearPicker
className='form-control bg-transparent border-0 shadow-none'
/>
</div>
</div>
</CardHeader>
<CardBody>
<div style={{ height: '400px' }}>
<Bar data={data} options={options} height={400} />
</div>
</CardBody>
</Card>
)
}
<Bar
data={data}
options={options}
height={400}
plugins={topData ? plugins(topData) : plugins}
/>
);
};
export default ChartjsBarChart
export default ChartjsBarChart;

124
src/components/charts/chart-js/ChartjsDoughnutChart.js vendored

@ -1,111 +1,19 @@
import React, { useState } from 'react'
import { Doughnut } from 'react-chartjs-2'
import { Monitor, Tablet, ArrowDown, ArrowUp } from 'react-feather'
import { Card, CardHeader, CardTitle, CardBody } from 'reactstrap'
import Flatpickr from 'react-flatpickr'
import { Calendar } from 'react-feather'
import DatePicker from "react-datepicker";
import { ko } from 'date-fns/esm/locale'
import "react-datepicker/dist/react-datepicker.css";
const ChartjsRadarChart = ({ tooltipShadow, successColorShade, warningLightColor, primary, yellowColor, blueColor }) => {
const [startDate, setStartDate] = useState(new Date());
const options = {
responsive: true,
maintainAspectRatio: false,
responsiveAnimationDuration: 500,
cutoutPercentage: 60,
legend: { display: false },
tooltips: {
callbacks: {
label(tooltipItem, data) {
const label = data.datasets[0].labels[tooltipItem.index] || '',
value = data.datasets[0].data[tooltipItem.index]
const output = ` ${label} : ${value} %`
return output
}
},
// Updated default tooltip UI
shadowOffsetX: 1,
shadowOffsetY: 1,
shadowBlur: 8,
shadowColor: tooltipShadow,
backgroundColor: '#fff',
titleFontColor: '#000',
bodyFontColor: '#000'
}
},
data = {
datasets: [
{
labels: ['경기도', '인천광역시', '충청북도', '세종시', '제주도'],
data: [10, 10, 10, 20, 80],
backgroundColor: [successColorShade, warningLightColor, primary, yellowColor, blueColor],
borderWidth: 0,
pointStyle: 'rectRounded'
}
]
}
import { Doughnut } from 'react-chartjs-2';
const ChartjsDoughnutChart = ({
data,
options,
plugins = [],
topData = null
}) => {
return (
<Card>
<CardHeader className='d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
<CardTitle tag='h4'>TOP5 지역 비행횟수 통계</CardTitle>
{/* <div className='d-flex align-items-center'>
<Calendar size={14} />
<Flatpickr
options={{
mode: 'single',
dateFormat: "Y-m-d",
defaultDate: ['today'],
}}
className='form-control flat-picker bg-transparent border-0 shadow-none'
/>
</div> */}
<div className='datepicker-border-sm'>
<div className='datepicker-custom'>
<Calendar size={14} />
<DatePicker
locale={ko}
selected={startDate}
onChange={(date) => setStartDate(date)}
dateFormat="yyy / MMMM"
showMonthYearPicker
showFullMonthYearPicker
showFourColumnMonthYearPicker
className='form-control bg-transparent border-0 shadow-none'
/>
</div>
</div>
</CardHeader>
<CardBody>
<div style={{ height: '275px' }}>
<Doughnut data={data} options={options} height={275} />
</div>
<div className='doughnut-chart-list'>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon successColorShade'></span>
<span className='ti'>경기도</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon warningLightColor'></span>
<span className='ti'>인천광역시</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon primaryColorShade'></span>
<span className='ti'>충청북도</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon yellowColor'></span>
<span className='ti'>세종시</span>
</div>
<div className='doughnut-chart-list-ti'>
<span className='dot-icon blueColor'></span>
<span className='ti'>제주도</span>
</div>
</div>
</CardBody>
</Card>
)
}
<Doughnut
data={data}
options={options}
height={275}
plugins={topData ? plugins(topData) : plugins}
/>
);
};
export default ChartjsRadarChart
export default ChartjsDoughnutChart;

185
src/components/charts/chart-js/ChartjsLineChart.js vendored

@ -1,186 +1,17 @@
import Flatpickr from 'react-flatpickr'
import { Calendar, Search } from 'react-feather'
import { Line } from 'react-chartjs-2'
import { Card, CardHeader, CardTitle, CardBody, CardSubtitle, Button } from 'reactstrap'
import { Line } from 'react-chartjs-2';
const ChartjsLineChart = ({
tooltipShadow,
gridLineColor,
labelColor,
warningColorShade,
lineChartDanger,
lineChartPrimary
}) => {
const options = {
responsive: true,
maintainAspectRatio: false,
backgroundColor: false,
legend: {
position: 'top',
labels: {
usePointStyle: true,
padding: 25,
boxWidth: 10
}
},
hover: {
mode: 'label'
},
tooltips: {
// Updated default tooltip UI
shadowOffsetX: 1,
shadowOffsetY: 1,
shadowBlur: 8,
shadowColor: tooltipShadow,
backgroundColor: '#fff',
titleFontColor: '#000',
bodyFontColor: '#000'
},
layout: {
padding: {
top: -15,
bottom: -25,
left: -15
}
},
scales: {
xAxes: [
{
display: true,
scaleLabel: {
display: true
},
gridLines: {
display: true,
color: gridLineColor,
zeroLineColor: gridLineColor
},
ticks: {
fontColor: labelColor
}
}
],
yAxes: [
{
display: true,
scaleLabel: {
display: true
},
ticks: {
stepSize: 100,
min: 0,
max: 400,
fontColor: labelColor
},
gridLines: {
display: true,
color: gridLineColor,
zeroLineColor: gridLineColor
}
}
]
},
legend: {
position: 'top',
align: 'start',
labels: {
usePointStyle: true,
padding: 25,
boxWidth: 9
}
}
},
data = {
labels: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140],
datasets: [
{
data: [80, 150, 180, 270, 210, 160, 160, 202, 265, 210, 270, 255, 290, 360, 375],
label: 'Europe',
borderColor: lineChartDanger,
lineTension: 0.5,
pointStyle: 'circle',
backgroundColor: lineChartDanger,
fill: false,
pointRadius: 1,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBorderColor: '#fff',
pointHoverBackgroundColor: lineChartDanger,
pointShadowOffsetX: 1,
pointShadowOffsetY: 1,
pointShadowBlur: 5,
pointShadowColor: tooltipShadow
},
{
data: [80, 125, 105, 130, 215, 195, 140, 160, 230, 300, 220, 170, 210, 200, 280],
label: 'Asia',
borderColor: lineChartPrimary,
lineTension: 0.5,
pointStyle: 'circle',
backgroundColor: lineChartPrimary,
fill: false,
pointRadius: 1,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBorderColor: '#fff',
pointHoverBackgroundColor: lineChartPrimary,
pointShadowOffsetX: 1,
pointShadowOffsetY: 1,
pointShadowBlur: 5,
pointShadowColor: tooltipShadow
},
{
data: [80, 99, 82, 90, 115, 115, 74, 75, 130, 155, 125, 90, 140, 130, 180],
label: 'Africa',
borderColor: warningColorShade,
lineTension: 0.5,
pointStyle: 'circle',
backgroundColor: warningColorShade,
fill: false,
pointRadius: 1,
pointHoverRadius: 5,
pointHoverBorderWidth: 5,
pointBorderColor: 'transparent',
pointHoverBorderColor: '#fff',
pointHoverBackgroundColor: warningColorShade,
pointShadowOffsetX: 1,
pointShadowOffsetY: 1,
pointShadowBlur: 5,
pointShadowColor: tooltipShadow
}
]
}
//** To add spacing between legends and chart
const ChartjsLineChart = ({ data, options }) => {
const plugins = [
{
beforeInit(chart) {
chart.legend.afterFit = function () {
this.height += 20
}
this.height += 20;
};
}
}
]
];
return (
<Card>
{/* <CardHeader className='cont-ti d-flex justify-content-between align-items-sm-center align-items-start flex-sm-row flex-column'>
<div>
<h4>비행 현황 목록</h4>
</div>
<div className='d-flex align-items-center'>
<Button.Ripple color='primary' size='sm'><Search size={16} />검색</Button.Ripple>
</div>
</CardHeader> */}
<CardBody className="pal-card-body">
<div style={{ height: '150px' }}>
<Line data={data} options={options} height={150} plugins={plugins} />
</div>
</CardBody>
</Card>
)
}
return <Line data={data} options={options} plugins={plugins} />;
};
export default ChartjsLineChart
export default ChartjsLineChart;

6
src/components/dashboard/DashboardStcsArea.js

@ -1,12 +1,12 @@
import { ko } from 'date-fns/esm/locale';
import { useEffect, useState } from 'react';
import { Plus } from 'react-feather';
import { Doughnut } from 'react-chartjs-2';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { Calendar } from 'react-feather';
import { Card, CardBody, CardHeader, CardTitle } from 'reactstrap';
import ChartjsDoughnutChart from '../charts/chart-js/ChartjsDoughnutChart';
const tooltipShadow = 'rgba(0, 0, 0, 0.25)';
const warningLightColor = '#FDAC34';
const successColorShade = '#28dac6';
@ -141,7 +141,7 @@ export const DashboardStcsArea = ({
}}
>
{Object.keys(chartData).length > 0 ? (
<Doughnut data={chartData} options={options} height={275} />
<ChartjsDoughnutChart data={chartData} options={options} />
) : (
<div className='d-flex justify-content-center align-items-center h-100'>
<p>표시할 데이터가 없습니다.</p>

4
src/components/dashboard/DashboardStcsDay.js

@ -2,7 +2,7 @@ import 'react-datepicker/dist/react-datepicker.css';
import { ko } from 'date-fns/esm/locale';
import { Plus } from 'react-feather';
import { useEffect, useState, useRef } from 'react';
import { Bar } from 'react-chartjs-2';
import ChartjsBarChart from '../charts/chart-js/ChartjsBarChart';
import DatePicker from 'react-datepicker';
import { Calendar } from 'react-feather';
import { Card, CardBody, CardHeader, CardTitle } from 'reactstrap';
@ -143,7 +143,7 @@ export const DashboardStcsDay = ({
<CardBody>
<div style={{ height: '400px' }}>
{Object.keys(chartData).length > 0 ? (
<Bar data={chartData} options={options} height={400} />
<ChartjsBarChart data={chartData} options={options} />
) : (
<div className='d-flex justify-content-center align-items-center h-100'>
<p>표시할 데이터가 없습니다.</p>

13
src/components/statistics/StatisticsSearch.js

@ -8,9 +8,9 @@ import {
CustomInput
} from 'reactstrap';
import { Search } from 'react-feather';
import { Bar, Doughnut } from 'react-chartjs-2';
import { useEffect, useState } from 'react';
import ChartjsDoughnutChart from '../charts/chart-js/ChartjsDoughnutChart';
import ChartjsBarChart from '../charts/chart-js/ChartjsBarChart';
// 그룹명 리스트
const competentAgency = [
{
@ -506,10 +506,9 @@ export default function StatisticsSearch({
</CardHeader>
<CardBody>
<div style={{ height: '400px' }}>
<Bar
<ChartjsBarChart
data={totalData}
options={barOptions}
height={400}
plugins={plugins(totalData)}
/>
</div>
@ -525,11 +524,11 @@ export default function StatisticsSearch({
</CardHeader>
<CardBody>
<div style={{ height: '275px' }}>
<Doughnut
<ChartjsDoughnutChart
data={topData}
options={doughnutOptions}
height={275}
plugins={plugins(topData)}
plugins={plugins}
topData={topData}
/>
</div>
{/* <div className='d-flex justify-content-between mt-3 mb-1'>

Loading…
Cancel
Save