From 926d0f7857fb09508a6dd14c1c866d80461b81d6 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 23 Jul 2021 12:01:07 +0500 Subject: [PATCH] =?UTF-8?q?=D0=93=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=82=D1=83=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/settings.json | 3 +- src/components/charts/ChartDepthToDayBase.tsx | 2 +- .../charts/ChartDepthToIntervalBase.tsx | 2 +- src/components/charts/ChartOperationTime.jsx | 2 +- src/concept/AnalisysOperationsToInterval.jsx | 44 +++++ src/concept/ChartOperationsToInterval.jsx | 83 ++++++++ src/concept/ChartOperationsToIntervalBase.tsx | 180 ++++++++++++++++++ src/pages/Analysis.jsx | 16 +- 8 files changed, 320 insertions(+), 12 deletions(-) create mode 100644 src/concept/AnalisysOperationsToInterval.jsx create mode 100644 src/concept/ChartOperationsToInterval.jsx create mode 100644 src/concept/ChartOperationsToIntervalBase.tsx diff --git a/.vscode/settings.json b/.vscode/settings.json index 24a6479..a8ab85f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,6 @@ { "cSpell.words": [ "день" - ] + ], + "liveServer.settings.port": 5501 } \ No newline at end of file diff --git a/src/components/charts/ChartDepthToDayBase.tsx b/src/components/charts/ChartDepthToDayBase.tsx index e1e6159..e5236c0 100644 --- a/src/components/charts/ChartDepthToDayBase.tsx +++ b/src/components/charts/ChartDepthToDayBase.tsx @@ -220,5 +220,5 @@ export const ChartDepthToDayBase: React.FC = ({options, data chart.update() }, [chart, dataParams, options]) - return() + return() } \ No newline at end of file diff --git a/src/components/charts/ChartDepthToIntervalBase.tsx b/src/components/charts/ChartDepthToIntervalBase.tsx index 9b53d50..9760d0b 100644 --- a/src/components/charts/ChartDepthToIntervalBase.tsx +++ b/src/components/charts/ChartDepthToIntervalBase.tsx @@ -220,5 +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 index 85dc6a3..e3f4829 100644 --- a/src/components/charts/ChartOperationTime.jsx +++ b/src/components/charts/ChartOperationTime.jsx @@ -2,7 +2,7 @@ import { useEffect, useState } from 'react' import { ChartOpertationTimeBase } from './ChartOperationTimeBase' import moment from 'moment' -export const CreateLabels = (lineConfig) => { +export const CreateLabels = () => { let labels = [] return labels } diff --git a/src/concept/AnalisysOperationsToInterval.jsx b/src/concept/AnalisysOperationsToInterval.jsx new file mode 100644 index 0000000..2080547 --- /dev/null +++ b/src/concept/AnalisysOperationsToInterval.jsx @@ -0,0 +1,44 @@ +import { ChartOperationsToInterval } from './charts/ChartOperationsToInterval' +import { useParams } from "react-router-dom" +import notify from "../components/notify" +import { useState, useEffect } from 'react' +import { AnalyticsService } from "../services/api" + +const lines = [ + { yAccessorName: "operationName", xAccessorName: "duration" }, +] + +export function AnalysisOperationsToInterval() { + let { id } = useParams() + const [operationsToInterval, setOperationsToInterval] = useState([]) + const [loader, setLoader] = useState(false) + + const handleReceiveOperationsToIntervalData = (data) => { + setOperationsToInterval(data[0].operations) + console.log(data) + } + + useEffect(() => { + setLoader(true) + let intervalHoursTimestamp = 600 + let workBeginTimestamp = 1 + + AnalyticsService.getOperationsToInterval(id, intervalHoursTimestamp, workBeginTimestamp) + .then(handleReceiveOperationsToIntervalData) + .catch(error => { + notify(`Не удалось получить данные для Анализа Глубина-День по скважине "${id}"`, + 'warning') + console.log(error) + }) + .finally(setLoader(false)) + }, [id]) + + return ( + <> + + + ) +} \ No newline at end of file diff --git a/src/concept/ChartOperationsToInterval.jsx b/src/concept/ChartOperationsToInterval.jsx new file mode 100644 index 0000000..e3264a5 --- /dev/null +++ b/src/concept/ChartOperationsToInterval.jsx @@ -0,0 +1,83 @@ +import { ChartDepthToIntervalBase } from './ChartOperationsToIntervalBase' +import { useEffect, useState } from 'react' +import { GetRandomColor, CreateDataset } from './ChartTimeArchive' + +const CreateLabels = () => { + let labels = [] + return labels +} + +const CreateData = (lineConfig) => { + + let datasets = { + label: lineConfig.label, + data: [], + backgroundColor: GetRandomColor() + } + return datasets +} + +const labels = ['Первый'] +const datasets = [ + { + label: 'Dataset 1', + data: [123], + backgroundColor: "#00f", + }, + { + label: 'Dataset 2', + data: [170], + backgroundColor: "#f0f", + }, + { + label: 'Dataset 3', + data: [150], + backgroundColor: "#0f0", + } +] + + +export const ChartOperationsToInterval = ({ data, lines }) => { + const [operationsToIntervalDataParams, setOperationsToIntervalDataParams] = useState({data: {labels: labels, datasets: datasets}}) + + useEffect(() => { + // if ((!lines) + // || (!data)) + // return + + let newDatasets = lines.map(lineCfg => { + let datasets = CreateData(lineCfg) + if (data.length !== 0) + datasets = data.map(dataItem => { + return { + label: 'Dataset 1', + data: [dataItem[lineCfg.xAccessorName]], + backgroundColor: "#00f", + } + }) + return datasets + }) + + // let newLabels = lines.map(lineCfg => { + // let labels = CreateLabels(lineCfg) + // if (data.length !== 0) + // labels = data.map(dataItem => { + // return dataItem[lineCfg.yAccessorName] + // }) + // return labels + // }) + + let newParams = { + data: { + datasets: newDatasets + } + } + setOperationsToIntervalDataParams(newParams) + + }, [data, lines]) + + return (<> + + + ) +} \ No newline at end of file diff --git a/src/concept/ChartOperationsToIntervalBase.tsx b/src/concept/ChartOperationsToIntervalBase.tsx new file mode 100644 index 0000000..3f715e4 --- /dev/null +++ b/src/concept/ChartOperationsToIntervalBase.tsx @@ -0,0 +1,180 @@ +import { useEffect, useRef, useState } from 'react' +import { + Chart, + TimeScale, + Legend, + PointElement, + ChartData, + ChartTypeRegistry, + ChartOptions, + BarController, + BarElement, + TimeSeriesScale, + LinearScale, + LineController, + CategoryScale +} from 'chart.js' +import 'chartjs-adapter-moment' +import ChartDataLabels from 'chartjs-plugin-datalabels' + +Chart.register(TimeScale, BarController, BarElement, PointElement, TimeSeriesScale, LineController, LinearScale, CategoryScale, Legend, ChartDataLabels) + +const defaultOptions = { + plugins: { + title: { + display: true, + text: 'Chart.js Bar Chart - Stacked' + }, + }, + responsive: true, + scales: { + x: { + stacked: true, + }, + y: { + stacked: true + } + } +} + +export type ChartTimeData = ChartData + +export type ChartTimeDataParams = { + data: ChartTimeData, + xStart?: 0, + 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 ChartDepthToIntervalBase: 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: 'bar', + 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 9f8956d..dacb12c 100644 --- a/src/pages/Analysis.jsx +++ b/src/pages/Analysis.jsx @@ -7,23 +7,23 @@ export default function Analysis() { return ( <> - +   + +

График Глубина-день

- +

График Глубина за интервал

-
- + +
 
+ +

График Операция за время

- - - -
)