diff --git a/src/pages/WellOperations/Tvd/NetGraphExport.jsx b/src/pages/WellOperations/Tvd/NetGraphExport.jsx index 72a5d72..048a024 100755 --- a/src/pages/WellOperations/Tvd/NetGraphExport.jsx +++ b/src/pages/WellOperations/Tvd/NetGraphExport.jsx @@ -14,15 +14,16 @@ export const NetGraphExport = memo(({ idWell, ...other }) => { ), [idWell]) return ( - +
+ +
) }) diff --git a/src/pages/WellOperations/Tvd/StatExport.jsx b/src/pages/WellOperations/Tvd/StatExport.jsx new file mode 100644 index 0000000..e425ecc --- /dev/null +++ b/src/pages/WellOperations/Tvd/StatExport.jsx @@ -0,0 +1,38 @@ +import { memo, useCallback, useEffect, useState } from 'react' +import { Button, Input } from 'antd' + +import { useIdWell } from '@asb/context' +import { download, invokeWebApiWrapperAsync } from '@components/factory' +import { WellService } from '@api' + +export const StatExport = memo(() => { + const [isFileExporting, setIsFileExporting] = useState(false) + const [idCluster, setIdCluster] = useState() + const idWell = useIdWell() + + useEffect(() => { + invokeWebApiWrapperAsync( + async () => { + const { idCluster } = await WellService.get(idWell) + setIdCluster(idCluster) + }, + setIsFileExporting, + 'Не удалось загрузить ID куста' + ) + }, [idWell]) + + const onExport = useCallback((well) => invokeWebApiWrapperAsync( + async () => await download(`/api/DetectedOperation/export?${well ? 'idWell' : 'idCluster'}=${well ? idWell : idCluster}`), + setIsFileExporting, + 'Не удалось загрузить файл' + ), [idWell, idCluster]) + + return ( + + + + + ) +}) + +export default StatExport diff --git a/src/pages/WellOperations/Tvd/TLPie.jsx b/src/pages/WellOperations/Tvd/TLPie.jsx index c4cd1ca..1305ca5 100644 --- a/src/pages/WellOperations/Tvd/TLPie.jsx +++ b/src/pages/WellOperations/Tvd/TLPie.jsx @@ -4,10 +4,21 @@ import { Empty } from 'antd' import * as d3 from 'd3' import { useIdWell } from '@asb/context' +import { makeColumn, makeNumericColumn, makeTextColumn, Table } from '@components/Table' import LoaderPortal from '@components/LoaderPortal' import { invokeWebApiWrapperAsync } from '@components/factory' import { DetectedOperationService } from '@api' +const tableColumns = [ + makeColumn('Цвет', 'color', { width: 50, render: (d) => ( +
+ ) }), + makeTextColumn('Название', 'category', undefined, undefined, undefined, { width: 300 }), + makeNumericColumn('Время, мин', 'minutesTotal', undefined, undefined, undefined, 100), + makeNumericColumn('Кол-во', 'count', undefined, undefined, (d) => d ? d.toString() : '---', 100), + makeNumericColumn('Процент, %', 'percent', undefined, undefined, (d) => d ? d.toFixed(2) : '---', 100) +] + export const TLPie = memo(({ color }) => { const [isLoading, setIsLoading] = useState(false) const [svgRef, setSvgRef] = useState() @@ -17,10 +28,21 @@ export const TLPie = memo(({ color }) => { const idWell = useIdWell() - const pie = useMemo(() => d3.pie().value((d) => d.count), []) - const data = useMemo(() => stats ? pie(stats) : null, [stats, pie]) + const pie = useMemo(() => d3.pie().value((d) => d.minutesTotal), []) - const radius = useMemo(() => Math.min(width, height) / 2 - 100, [width, height]) + const tableData = useMemo(() => { + if (!stats) return null + const totalTime = stats.reduce((out, stat) => out + stat.minutesTotal, 0) + return stats.map((stat) => ({ + ...stat, + color: color(stat.idCategory), + percent: stat.minutesTotal / totalTime * 100, + })) + }, [stats, color]) + + const data = useMemo(() => tableData ? pie(tableData) : null, [tableData]) + + const radius = useMemo(() => Math.min(width, height) / 2, [width, height]) useEffect(() => { invokeWebApiWrapperAsync( @@ -88,21 +110,32 @@ export const TLPie = memo(({ color }) => { }) .style('text-anchor', (d) => abovePi(d) ? 'start' : 'end') .attr('width', radius * 0.4) - .text((d) => `${d.data.category} (${d.data.count})`) + .text((d) => `${d.data.percent.toFixed(2)}% (${d.data.minutesTotal.toFixed(2)} мин)`) }, [svgRef, data, radius]) return ( -
+
{data ? ( - - - - - - - +
+
+ + + + + + + +
+ + ) : (
diff --git a/src/pages/WellOperations/Tvd/index.jsx b/src/pages/WellOperations/Tvd/index.jsx index c2e5139..8b495c9 100755 --- a/src/pages/WellOperations/Tvd/index.jsx +++ b/src/pages/WellOperations/Tvd/index.jsx @@ -1,6 +1,6 @@ import { LineChartOutlined, LinkOutlined } from '@ant-design/icons' import { memo, useState, useEffect, useMemo } from 'react' -import { Switch, Segmented } from 'antd' +import { Switch, Segmented, Button } from 'antd' import { Link } from 'react-router-dom' import * as d3 from 'd3' @@ -14,6 +14,7 @@ import { DetectedOperationService } from '@api' import TLPie from './TLPie' import TLChart from './TLChart' import NptTable from './NptTable' +import StatExport from './StatExport' import NetGraphExport from './NetGraphExport' import AdditionalTables from './AdditionalTables' @@ -21,8 +22,10 @@ import '@styles/index.css' import '@styles/tvd.less' const colorArray = [ - '#1abc9c', '#16a085', '#2ecc71', '#27ae60', '#3498db', '#2980b9', '#9b59b6', '#8e44ad', '#34495e', '#2c3e50', - '#f1c40f', '#f39c12', '#e67e22', '#d35400', '#e74c3c', '#c0392b', '#ecf0f1', '#bdc3c7', '#95a5a6', '#7f8c8d', + '#1abc9c', '#16a085', '#2ecc71', '#27ae60', '#3498db', + '#2980b9', '#9b59b6', '#8e44ad', '#34495e', '#2c3e50', + '#f1c40f', '#f39c12', '#e67e22', '#d35400', '#e74c3c', + '#c0392b', '#ecf0f1', '#bdc3c7', '#95a5a6', '#7f8c8d', ] const Item = ({ label, children, ...other }) => (
{label}: {children}
) @@ -222,6 +225,7 @@ const Tvd = memo(({ idWell: wellId, title, ...other }) => {
+