diff --git a/src/components/AnalysisDepthToInterval.jsx b/src/components/AnalysisDepthToInterval.jsx
index c0f846c..840206c 100644
--- a/src/components/AnalysisDepthToInterval.jsx
+++ b/src/components/AnalysisDepthToInterval.jsx
@@ -40,7 +40,7 @@ export function AnalysisDepthToInterval() {
AnalyticsService.getWellDepthToInterval(id, chartInterval)
.then(handleReceiveDepthToIntervalData)
.catch(error => {
- notify(`Не удалось получить данные для Анализа Глубина-День по скважине "${id}"`,
+ notify(`Не удалось получить данные для Анализа скорость проходки-интервал "${id}"`,
'warning')
console.log(error)
})
diff --git a/src/components/AnalysisOperationTime.jsx b/src/components/AnalysisOperationTime.jsx
new file mode 100644
index 0000000..1bcd261
--- /dev/null
+++ b/src/components/AnalysisOperationTime.jsx
@@ -0,0 +1,60 @@
+import { useParams } from "react-router-dom"
+import { DatePicker, ConfigProvider } from 'antd';
+import notify from "../components/notify"
+import { useState, useEffect } from 'react'
+import { AnalyticsService } from '../services/api'
+import { ChartOperationTime } from './charts/ChartOperationTime'
+import locale from "antd/lib/locale/ru_RU";
+
+const { RangePicker } = DatePicker
+
+const lines = [{ labelAccessorName: "processName", pieceAccessorName: "duration" }]
+
+export function AnalysisOperationTime() {
+ let { id } = useParams()
+ const [operationTimeData, setOperationTimeData] = useState([])
+ const [loader, setLoader] = useState(false)
+ const [range, setRange] = useState([])
+
+ let begin = null
+ let end = null
+
+ const onChangeRange = (range) => {
+ setRange(range)
+ }
+
+ const handleReceiveOperationTimeData = (data) => {
+ setOperationTimeData(data)
+ }
+
+ useEffect(() => {
+ setLoader(true)
+ if (range?.length > 1) {
+ begin = range[0].toISOString()
+ end = range[1].toISOString()
+ }
+ AnalyticsService.getOperationsSummary(id, begin, end)
+ .then(handleReceiveOperationTimeData)
+ .catch(error => {
+ notify(`Не удалось получить данные для Анализа Операция-Время по скважине "${id}" за период с ${begin} по ${end}`,
+ 'warning')
+ console.log(error)
+ })
+ .finally(setLoader(false))
+ }, [id, range])
+
+ return (
+ <>
+
+
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/components/charts/ChartDepthToIntervalBase.tsx b/src/components/charts/ChartDepthToIntervalBase.tsx
index e043091..9b53d50 100644
--- a/src/components/charts/ChartDepthToIntervalBase.tsx
+++ b/src/components/charts/ChartDepthToIntervalBase.tsx
@@ -220,8 +220,5 @@ export const ChartDepthToIntervalBase: React.FC = ({ options
chart.update()
}, [chart, dataParams, options])
- return ()
+ return ()
}
\ No newline at end of file
diff --git a/src/components/charts/ChartOperationTime.jsx b/src/components/charts/ChartOperationTime.jsx
new file mode 100644
index 0000000..85dc6a3
--- /dev/null
+++ b/src/components/charts/ChartOperationTime.jsx
@@ -0,0 +1,67 @@
+import { useEffect, useState } from 'react'
+import { ChartOpertationTimeBase } from './ChartOperationTimeBase'
+import moment from 'moment'
+
+export const CreateLabels = (lineConfig) => {
+ let labels = []
+ return labels
+}
+
+export const CreateData = (lineConfig) => {
+ let datasets = {
+ label: lineConfig.label,
+ data: [],
+ backgroundColor: [
+ '#f00', '#ff0', '#f0f', '#0ff', '#00f', '#0f0'
+ ],
+ }
+ return datasets
+}
+
+export const ChartOperationTime = ({ lines, data, rangeDate }) => {
+ const [opertationTimeDataParams, setOpertationTimeDataParams] = useState({ data: { labels: [], datasets: [] } })
+
+ useEffect(() => {
+ if ((!lines)
+ || (!data))
+ return
+
+ let newLabels = lines.map(lineCfg => {
+ let labels = CreateLabels(lineCfg)
+ if (data.length !== 0)
+ labels = data.map(dataItem => {
+ return dataItem[lineCfg.labelAccessorName]
+ })
+ return labels
+ })
+
+ let newDatasets = lines.map(lineCfg => {
+ let datasets = CreateData(lineCfg)
+ if (data.length !== 0)
+ datasets.data = data.map(dataItem => {
+ return dataItem[lineCfg.pieceAccessorName]
+ })
+ return datasets
+ })
+
+ let interval = rangeDate ? (rangeDate[1] - rangeDate[0]) / 1000 : null
+ let startDate = rangeDate ? rangeDate[0] : moment()
+ let newParams = {
+ xInterval: interval,
+ xStart: startDate,
+ data: {
+ labels: newLabels,
+ datasets: newDatasets
+ }
+ }
+ setOpertationTimeDataParams(newParams)
+
+ console.log(newParams)
+
+ }, [data, lines, rangeDate])
+
+ return (<>
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/components/charts/ChartOperationTimeBase.tsx b/src/components/charts/ChartOperationTimeBase.tsx
new file mode 100644
index 0000000..5d9e96c
--- /dev/null
+++ b/src/components/charts/ChartOperationTimeBase.tsx
@@ -0,0 +1,177 @@
+import { useEffect, useRef, useState } from 'react'
+import {
+ Chart,
+ ArcElement,
+ TimeScale,
+ Legend,
+ PointElement,
+ ChartData,
+ ChartTypeRegistry,
+ ChartOptions,
+ DoughnutController,
+} from 'chart.js'
+import 'chartjs-adapter-moment'
+import ChartDataLabels from 'chartjs-plugin-datalabels'
+
+Chart.register(TimeScale, DoughnutController, PointElement, ArcElement, Legend, ChartDataLabels)
+
+const defaultOptions = {
+ responsive: true,
+ title: {
+ display: true,
+ position: "top",
+ text: "Doughnut Chart",
+ fontSize: 18,
+ fontColor: "#111"
+ },
+ legend: {
+ display: true,
+ position: "bottom",
+ labels: {
+ fontColor: "#333",
+ fontSize: 16
+ }
+ }
+}
+
+export type ChartTimeData = ChartData
+
+export type ChartTimeDataParams = {
+ data: ChartTimeData,
+ xStart?: Date,
+ xInterval?: number,
+ displayLabels?: Boolean,
+}
+
+export type ChartTimeBaseProps = {
+ dataParams: ChartTimeDataParams,
+ // TODO: Create good type for options
+ options?: ChartOptions | any,
+}
+
+export type TimeParams = {
+ unit: String
+ stepSize: number
+}
+
+const linesPerInterval = 32
+
+export const timeUnitByInterval = (intervalSec: number): String => {
+ if (intervalSec <= 60)
+ return 'millisecond'
+
+ if (intervalSec <= 32 * 60)
+ return 'second'
+
+ if (intervalSec <= 32 * 60 * 60)
+ return 'minute'
+
+ if (intervalSec <= 32 * 12 * 60 * 60)
+ return 'hour'
+
+ if (intervalSec <= 32 * 24 * 60 * 60)
+ return 'day'
+
+ if (intervalSec <= 32 * 7 * 24 * 60 * 60)
+ return 'week'
+
+ if (intervalSec <= 32 * 30.4375 * 24 * 60 * 60)
+ return 'month'
+
+ if (intervalSec <= 32 * 121.75 * 24 * 60 * 60)
+ return 'quarter'
+ else
+ return 'year'
+}
+
+export const timeParamsByInterval = (intervalSec: number): TimeParams => {
+ let stepSize = intervalSec
+ let unit = timeUnitByInterval(intervalSec)
+
+ switch (unit) {
+ case "millisecond":
+ stepSize *= 1000
+ break;
+ case "second":
+ //stepSize *= 1
+ break;
+ case "minute":
+ stepSize /= 60
+ break;
+ case "hour":
+ stepSize /= 60 * 60
+ break;
+ case "day":
+ stepSize /= 24 * 60 * 60
+ break;
+ case "week":
+ stepSize /= 7 * 24 * 60 * 60
+ break;
+ case "month":
+ stepSize /= 30 * 24 * 60 * 60
+ break;
+ case "quarter":
+ stepSize /= 91 * 24 * 60 * 60
+ break;
+ case "year":
+ stepSize /= 365.25 * 24 * 60 * 60
+ break;
+ }
+
+ stepSize = Math.round(stepSize / linesPerInterval)
+ stepSize = stepSize > 0 ? stepSize : 1;
+ return { unit, stepSize }
+}
+
+export const ChartOpertationTimeBase: React.FC = ({ options, dataParams }) => {
+ const chartRef = useRef(null)
+ const [chart, setChart] = useState()
+
+ useEffect(() => {
+ if ((chartRef.current) && (!chart)) {
+ let thisOptions = {}
+ Object.assign(thisOptions, defaultOptions, options)
+
+ let newChart = new Chart(chartRef.current, {
+ type: 'doughnut',
+ plugins: [ChartDataLabels],
+ options: thisOptions,
+ data: dataParams.data
+ })
+ setChart(newChart)
+
+ return () => chart?.destroy()
+ }
+ }, [chart, options, dataParams])
+
+ useEffect(() => {
+ if (!chart)
+ return
+
+ chart.data = dataParams.data
+ chart.options.aspectRatio = options?.aspectRatio
+ if (dataParams.xStart) {
+ let interval = Number(dataParams.xInterval ?? 600)
+ let start = new Date(dataParams.xStart)
+ let end = new Date(dataParams.xStart)
+ end.setSeconds(end.getSeconds() + interval)
+ let { unit, stepSize } = timeParamsByInterval(interval)
+
+ if (chart.options.scales?.x) {
+ chart.options.scales.x.max = end.getTime()
+ chart.options.scales.x.min = start.getTime()
+ chart.options.scales.x.ticks.display = dataParams.displayLabels ?? true
+ chart.options.scales.x.time.unit = unit
+ chart.options.scales.x.time.stepSize = stepSize
+ }
+ }
+
+ chart.update()
+ }, [chart, dataParams, options])
+
+ return ()
+}
\ No newline at end of file
diff --git a/src/pages/Analysis.jsx b/src/pages/Analysis.jsx
index 71c823f..9f8956d 100644
--- a/src/pages/Analysis.jsx
+++ b/src/pages/Analysis.jsx
@@ -1,13 +1,30 @@
import { AnalysisDepthToDay } from '../components/AnalysisDepthToDay'
import { AnalysisDepthToInterval } from '../components/AnalysisDepthToInterval'
+import { AnalysisOperationTime } from '../components/AnalysisOperationTime'
+import { Row, Col } from 'antd'
export default function Analysis() {
return (
<>
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
>
)
}
\ No newline at end of file