chart.js полностью вырезан из проекта

This commit is contained in:
goodmice 2022-07-29 18:23:31 +05:00
parent 183e9b8cde
commit 7a3f7e05c9
4 changed files with 0 additions and 423 deletions

75
package-lock.json generated
View File

@ -10,10 +10,6 @@
"dependencies": { "dependencies": {
"@microsoft/signalr": "^6.0.5", "@microsoft/signalr": "^6.0.5",
"antd": "^4.20.7", "antd": "^4.20.7",
"chart.js": "^3.8.0",
"chartjs-adapter-moment": "^1.0.0",
"chartjs-plugin-datalabels": "^2.0.0",
"chartjs-plugin-zoom": "^1.2.1",
"d3": "^7.4.4", "d3": "^7.4.4",
"moment": "^2.29.3", "moment": "^2.29.3",
"pigeon-maps": "^0.21.0", "pigeon-maps": "^0.21.0",
@ -4532,39 +4528,6 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/chart.js": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.0.tgz",
"integrity": "sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg=="
},
"node_modules/chartjs-adapter-moment": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.0.tgz",
"integrity": "sha512-PqlerEvQcc5hZLQ/NQWgBxgVQ4TRdvkW3c/t+SUEQSj78ia3hgLkf2VZ2yGJtltNbEEFyYGm+cA6XXevodYvWA==",
"peerDependencies": {
"chart.js": "^3.0.0",
"moment": "^2.10.2"
}
},
"node_modules/chartjs-plugin-datalabels": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.0.0.tgz",
"integrity": "sha512-WBsWihphzM0Y8fmQVm89+iy99mmgejmj5/jcsYqwxSioLRL/zqJ4Scv/eXq5ZqvG3TpojlGzZLeaOaSvDm7fwA==",
"peerDependencies": {
"chart.js": "^3.0.0"
}
},
"node_modules/chartjs-plugin-zoom": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.1.tgz",
"integrity": "sha512-2zbWvw2pljrtMLMXkKw1uxYzAne5PtjJiOZftcut4Lo3Ee8qUt95RpMKDWrZ+pBZxZKQKOD/etdU4pN2jxZUmg==",
"dependencies": {
"hammerjs": "^2.0.8"
},
"peerDependencies": {
"chart.js": "^3.2.0"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "3.5.3", "version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -6458,14 +6421,6 @@
"integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
"dev": true "dev": true
}, },
"node_modules/hammerjs": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE=",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/handle-thing": { "node_modules/handle-thing": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
@ -15549,31 +15504,6 @@
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
"dev": true "dev": true
}, },
"chart.js": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.8.0.tgz",
"integrity": "sha512-cr8xhrXjLIXVLOBZPkBZVF6NDeiVIrPLHcMhnON7UufudL+CNeRrD+wpYanswlm8NpudMdrt3CHoLMQMxJhHRg=="
},
"chartjs-adapter-moment": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/chartjs-adapter-moment/-/chartjs-adapter-moment-1.0.0.tgz",
"integrity": "sha512-PqlerEvQcc5hZLQ/NQWgBxgVQ4TRdvkW3c/t+SUEQSj78ia3hgLkf2VZ2yGJtltNbEEFyYGm+cA6XXevodYvWA==",
"requires": {}
},
"chartjs-plugin-datalabels": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chartjs-plugin-datalabels/-/chartjs-plugin-datalabels-2.0.0.tgz",
"integrity": "sha512-WBsWihphzM0Y8fmQVm89+iy99mmgejmj5/jcsYqwxSioLRL/zqJ4Scv/eXq5ZqvG3TpojlGzZLeaOaSvDm7fwA==",
"requires": {}
},
"chartjs-plugin-zoom": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-1.2.1.tgz",
"integrity": "sha512-2zbWvw2pljrtMLMXkKw1uxYzAne5PtjJiOZftcut4Lo3Ee8qUt95RpMKDWrZ+pBZxZKQKOD/etdU4pN2jxZUmg==",
"requires": {
"hammerjs": "^2.0.8"
}
},
"chokidar": { "chokidar": {
"version": "3.5.3", "version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -16996,11 +16926,6 @@
"integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==", "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==",
"dev": true "dev": true
}, },
"hammerjs": {
"version": "2.0.8",
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
},
"handle-thing": { "handle-thing": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",

View File

@ -5,10 +5,6 @@
"dependencies": { "dependencies": {
"@microsoft/signalr": "^6.0.5", "@microsoft/signalr": "^6.0.5",
"antd": "^4.20.7", "antd": "^4.20.7",
"chart.js": "^3.8.0",
"chartjs-adapter-moment": "^1.0.0",
"chartjs-plugin-datalabels": "^2.0.0",
"chartjs-plugin-zoom": "^1.2.1",
"d3": "^7.4.4", "d3": "^7.4.4",
"moment": "^2.29.3", "moment": "^2.29.3",
"pigeon-maps": "^0.21.0", "pigeon-maps": "^0.21.0",

View File

@ -1,222 +0,0 @@
import { memo, useEffect, useRef, useState } from 'react'
import {
Chart,
TimeScale,
LinearScale,
Legend,
LineController,
PointElement,
LineElement,
ChartData,
ChartOptions,
ChartType,
ChartDataset,
Tooltip
} from 'chart.js'
import 'chartjs-adapter-moment'
import ChartDataLabels from 'chartjs-plugin-datalabels'
import zoomPlugin from 'chartjs-plugin-zoom'
Chart.register(
TimeScale,
LinearScale,
LineController,
LineElement,
PointElement,
Legend,
ChartDataLabels,
zoomPlugin,
Tooltip,
)
const defaultOptions: ChartOptions = {
responsive: true,
aspectRatio: 0.45,
animation: false,
events: ['mousemove', 'mouseout', 'click', 'touchstart', 'touchmove'],
scales: {
y: {
type: 'time',
reverse: true,
time: {
stepSize: 20,
displayFormats: {
millisecond: 'HH:mm:ss.SSS',
second: 'HH:mm:ss',
minute: 'HH:mm:ss',
hour: 'DD HH:mm:ss',
day: 'MM.DD HH:mm',
week: 'yy.MM.DD HH:mm',
month: 'yyyy.MM.DD',
quarter: 'yyyy.MM.DD',
year: 'yyyy.MM',
},
},
grid: {
drawTicks: false,
},
ticks: {
z: 1,
display : false,
textStrokeColor : '#ffff',
textStrokeWidth : 2,
color:'#000',
}
},
x: {
type: 'linear',
position: 'top'
}
},
parsing: false,
elements: {
point: {
radius: 0,
hoverRadius: 5,
},
},
plugins: {
legend: {
display: false,
},
datalabels: {
display: false,
},
zoom: {
zoom: {
wheel: {
enabled: true,
modifierKey: 'alt',
},
pinch: {
enabled: true
},
mode: 'x',
}
},
tooltip: {
enabled: true,
callbacks: {
label: (tooltipItem: any) => tooltipItem.yLabel
}
},
}
}
export type ChartTimeDataPoint = {
x: number
label: number
y: Date
}
export type ChartTimeDataset = ChartDataset<ChartType, ChartTimeDataPoint[]>
export type ChartTimeData = ChartData<ChartType, ChartTimeDataPoint[], unknown>
export type ChartTimeDataParams = {
data: ChartTimeData
yStart?: Date
yInterval?: number
displayLabels?: boolean
}
export type ChartTimeBaseProps = {
dataParams: ChartTimeDataParams
options?: ChartOptions
}
export type TimeParams = {
unit: string
stepSize: number
}
const linesPerInterval = 32
const intervals = {
millisecond: 0.001,
second: 1,
minute: 60,
hour: 60 * 60,
day: 60 * 60 * 24,
week: 60 * 60 * 24 * 7,
month: 60 * 60 * 24 * 30,
quarter: 60 * 60 * 24 * 91,
year: 60 * 60 * 24 * 365.25
}
type IntervalType = keyof typeof intervals
export const timeUnitByInterval = (intervalSec: number): IntervalType => {
if(intervalSec <= intervals.minute)
return 'millisecond'
if(intervalSec <= 32 * intervals.minute)
return 'second'
if(intervalSec <= 32 * intervals.hour)
return 'minute'
if(intervalSec <= 32 * intervals.day / 2)
return 'hour'
if(intervalSec <= 32 * intervals.day)
return 'day'
if(intervalSec <= 32 * intervals.week)
return 'week'
if(intervalSec <= 32 * intervals.year / 12)
return 'month'
if(intervalSec <= 32 * intervals.year / 3)
return 'quarter'
return 'year'
}
export const timeParamsByInterval = (intervalSec: number): TimeParams => {
const unit = timeUnitByInterval(intervalSec)
const stepSize = Math.max(1, Math.round(intervalSec / intervals[unit] / linesPerInterval))
return { unit, stepSize }
}
export const ChartTimeBase = memo<ChartTimeBaseProps>(({ options, dataParams }) => {
const chartRef = useRef<HTMLCanvasElement>(null)
const [chart, setChart] = useState<any>()
useEffect(() => {
const chartOptions: ChartOptions = {}
Object.assign(chartOptions, defaultOptions, options)
const newChart = new Chart(chartRef.current ?? '', {
type: 'line',
plugins: [ChartDataLabels],
options: chartOptions,
data: { datasets: [] }
})
setChart(newChart)
return () => newChart?.destroy()
}, [options])
useEffect(() => {
if (!chart) return
chart.data = dataParams.data
if(dataParams.yStart){
const interval = Number(dataParams.yInterval ?? 600_000)
const { unit, stepSize } = timeParamsByInterval(Number(interval / 1000))
if(chart.options.scales?.y){
chart.options.scales.y.max = +dataParams.yStart + interval
chart.options.scales.y.min = +dataParams.yStart
chart.options.scales.y.ticks.display = dataParams.displayLabels ?? true
chart.options.scales.y.time.unit = unit
chart.options.scales.y.time.stepSize = stepSize
}
}
chart.update(0)
}, [chart, dataParams])
return(<canvas ref={chartRef} />)
})

View File

@ -1,122 +0,0 @@
import { ChartOptions, Scriptable, ScriptableContext } from 'chart.js'
import React, { useState, useEffect } from 'react'
import { makeDateSorter } from '@components/Table'
import {
ChartTimeBase,
ChartTimeData,
ChartTimeDataset,
ChartTimeDataPoint,
ChartTimeDataParams
} from './ChartTimeBase'
export type ColumnLineConfig = {
label?: string
units?: string
xAccessorName: string
yAccessorName: string
color?: string
showLine?: boolean
isShape?: boolean
xConstValue?: number | string
dash?: Array<number>
borderColor?: string
backgroundColor?: string
borderWidth?: Scriptable<number, ScriptableContext<'line'>>
showDatalabels?: boolean
fill?: string
}
export type ColumnPostParsing = (data: ChartTimeDataParams) => void
export type ColumnData = { [accessors: string]: any }
export type ColumnAdditionalData = (point: ColumnData, cfg: ColumnLineConfig) => object
export type ColumnProps = {
postParsing?: ColumnPostParsing
additionalPointData?: ColumnAdditionalData
interval?: number
yDisplay?: boolean
yStart?: Date
lineGroup: ColumnLineConfig[]
data: ColumnData[]
}
const chartPluginsOptions: ChartOptions = {
plugins: {
datalabels: {
backgroundColor: 'transparent',
borderRadius: 4,
color: '#000B',
display: context => !!context.dataset.label?.endsWith(' ') && 'auto',
formatter: value => `${value.y.toLocaleTimeString()} ${value.label.toPrecision(4)}`,
padding: 6,
align: 'left',
anchor: 'center',
clip: true
},
legend: { display: false },
tooltip: { enabled: true }
}
}
const GetRandomColor = () => '#' + Math.floor(Math.random() * (16**6 - 1)).toString(16)
export const GetOrCreateDatasetByLineConfig = (data: ChartTimeData, lineConfig: ColumnLineConfig): ChartTimeDataset => {
let dataset = data?.datasets.find(d => d.label === lineConfig.label)
if (!dataset) {
const color = lineConfig.borderColor
?? lineConfig.backgroundColor
?? lineConfig.color
?? GetRandomColor()
dataset = {
label: lineConfig.label?.trimEnd() + (lineConfig.showDatalabels ? ' ' : ''),
data: [],
backgroundColor: lineConfig.backgroundColor ?? color,
borderColor: lineConfig.borderColor ?? color,
borderWidth: lineConfig.borderWidth ?? 1,
borderDash: lineConfig.dash ?? [],
showLine: lineConfig.showLine ?? !lineConfig.isShape,
fill: lineConfig.fill ?? (lineConfig.isShape ? 'shape' : 'none'),
}
data.datasets.push(dataset)
}
return dataset
}
export const Column: React.NamedExoticComponent<ColumnProps> = React.memo(({ lineGroup, data, postParsing, additionalPointData, interval, yDisplay, yStart }) => {
const [dataParams, setDataParams] = useState<ChartTimeDataParams>({data: {datasets:[]}, yStart, })
useEffect(()=>{
if((lineGroup.length === 0) || (data.length === 0)) return
setDataParams((preDataParams) => {
lineGroup.forEach(lineCfg => {
const dataset = GetOrCreateDatasetByLineConfig(preDataParams.data, lineCfg)
let points: ChartTimeDataPoint[] = data.map(dataItem => ({
x: lineCfg.xConstValue ?? dataItem[lineCfg.xAccessorName],
label: dataItem[lineCfg.xAccessorName],
y: new Date(dataItem[lineCfg.yAccessorName]),
...additionalPointData?.(dataItem, lineCfg)
}))
points = points.filter(point => (point.x ?? null) !== null && (point.y ?? null) !== null)
if(points?.length > 2)
points.sort(makeDateSorter('y'))
dataset.data = points
})
preDataParams.yStart = yStart
preDataParams.yInterval = interval
preDataParams.displayLabels = yDisplay
postParsing?.(preDataParams)
return {...preDataParams}
})
}, [data, lineGroup, interval, yDisplay, yStart, postParsing, additionalPointData])
return <ChartTimeBase dataParams = { dataParams } options = { chartPluginsOptions } />
})