mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-10 09:11:55 +00:00
add time range slider
This commit is contained in:
parent
0ad63b55d3
commit
94a70f4fbe
|
@ -0,0 +1,44 @@
|
|||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
const Handle = ({
|
||||
error,
|
||||
domain: [min, max],
|
||||
handle: { id, value, percent = 0 },
|
||||
disabled,
|
||||
getHandleProps,
|
||||
}) => {
|
||||
const leftPosition = `${percent}%`
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='react_time_range__handle_wrapper' style={{ left: leftPosition }} {...getHandleProps(id)} />
|
||||
<div
|
||||
role='slider'
|
||||
aria-valuemin={min}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={value}
|
||||
className={`react_time_range__handle_container${disabled ? '__disabled' : ''}`}
|
||||
style={{ left: leftPosition }}
|
||||
>
|
||||
<div className={`react_time_range__handle_marker${error ? '__error' : ''}`} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Handle.propTypes = {
|
||||
domain: PropTypes.array.isRequired,
|
||||
handle: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired
|
||||
}).isRequired,
|
||||
getHandleProps: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool,
|
||||
style: PropTypes.object,
|
||||
}
|
||||
|
||||
Handle.defaultProps = { disabled: false }
|
||||
|
||||
export default Handle
|
|
@ -0,0 +1,32 @@
|
|||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
const KeyboardHandle = ({ domain: [min, max], handle: { id, value, percent = 0 }, disabled, getHandleProps }) => (
|
||||
<button
|
||||
role='slider'
|
||||
aria-valuemin={min}
|
||||
aria-valuemax={max}
|
||||
aria-valuenow={value}
|
||||
className='react_time_range__keyboard_handle'
|
||||
style={{
|
||||
left: `${percent}%`,
|
||||
backgroundColor: disabled ? '#666' : '#ffc400'
|
||||
}}
|
||||
{...getHandleProps(id)}
|
||||
/>
|
||||
)
|
||||
|
||||
KeyboardHandle.propTypes = {
|
||||
domain: PropTypes.array.isRequired,
|
||||
handle: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired
|
||||
}).isRequired,
|
||||
getHandleProps: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool
|
||||
}
|
||||
|
||||
KeyboardHandle.defaultProps = { disabled: false }
|
||||
|
||||
export default KeyboardHandle
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export const SliderRail = ({ getRailProps }) => (
|
||||
<>
|
||||
<div className='react_time_range__rail__outer' {...getRailProps()} />
|
||||
<div className='react_time_range__rail__inner' />
|
||||
</>
|
||||
)
|
||||
|
||||
SliderRail.propTypes = { getRailProps: PropTypes.func.isRequired }
|
||||
|
||||
export default SliderRail
|
|
@ -0,0 +1,41 @@
|
|||
import { getMinutes } from 'date-fns'
|
||||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
const Tick = ({ tick, count, format }) => {
|
||||
const isFullHour = !getMinutes(tick.value)
|
||||
|
||||
const tickLabelStyle = {
|
||||
marginLeft: `${-(100 / count) / 2}%`,
|
||||
width: `${100 / count}%`,
|
||||
left: `${tick.percent}%`,
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={`react_time_range__tick_marker${isFullHour ? '__large' : ''}`}
|
||||
style={{ left: `${tick.percent}%` }}
|
||||
/>
|
||||
{isFullHour && (
|
||||
<div className='react_time_range__tick_label' style={tickLabelStyle}>
|
||||
{format(tick.value)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Tick.propTypes = {
|
||||
tick: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired
|
||||
}).isRequired,
|
||||
count: PropTypes.number.isRequired,
|
||||
format: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
Tick.defaultProps = { format: d => d }
|
||||
|
||||
export default Tick
|
|
@ -0,0 +1,52 @@
|
|||
import PropTypes from 'prop-types'
|
||||
import React from 'react'
|
||||
|
||||
const getTrackConfig = ({ error, source, target, disabled }) => {
|
||||
const basicStyle = {
|
||||
left: `${source.percent}%`,
|
||||
width: `calc(${target.percent - source.percent}% - 1px)`,
|
||||
}
|
||||
|
||||
if (disabled) return basicStyle
|
||||
|
||||
const coloredTrackStyle = error
|
||||
? {
|
||||
backgroundColor: 'rgba(214,0,11,0.5)',
|
||||
borderLeft: '1px solid rgba(214,0,11,0.5)',
|
||||
borderRight: '1px solid rgba(214,0,11,0.5)',
|
||||
}
|
||||
: {
|
||||
backgroundColor: 'rgba(98, 203, 102, 0.5)',
|
||||
borderLeft: '1px solid #62CB66',
|
||||
borderRight: '1px solid #62CB66',
|
||||
}
|
||||
|
||||
return { ...basicStyle, ...coloredTrackStyle }
|
||||
}
|
||||
|
||||
const Track = ({ error, source, target, getTrackProps, disabled }) => (
|
||||
<div
|
||||
className={`react_time_range__track${disabled ? '__disabled' : ''}`}
|
||||
style={getTrackConfig({ error, source, target, disabled })}
|
||||
{...getTrackProps()}
|
||||
/>
|
||||
)
|
||||
|
||||
Track.propTypes = {
|
||||
source: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired
|
||||
}).isRequired,
|
||||
target: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.number.isRequired,
|
||||
percent: PropTypes.number.isRequired
|
||||
}).isRequired,
|
||||
getTrackProps: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool
|
||||
}
|
||||
|
||||
Track.defaultProps = { disabled: false }
|
||||
|
||||
export default Track
|
256
apps/backtest-report/components/TimeRangeSlider/index.jsx
Normal file
256
apps/backtest-report/components/TimeRangeSlider/index.jsx
Normal file
|
@ -0,0 +1,256 @@
|
|||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {scaleTime} from 'd3-scale'
|
||||
import {Handles, Rail, Slider, Ticks, Tracks} from 'react-compound-slider'
|
||||
import {
|
||||
addHours,
|
||||
addMinutes,
|
||||
differenceInMilliseconds,
|
||||
endOfToday,
|
||||
format,
|
||||
isAfter,
|
||||
isBefore,
|
||||
set,
|
||||
startOfToday,
|
||||
} from 'date-fns'
|
||||
|
||||
import SliderRail from './components/SliderRail'
|
||||
import Track from './components/Track'
|
||||
import Tick from './components/Tick'
|
||||
import Handle from './components/Handle'
|
||||
|
||||
|
||||
const getTimelineConfig = (timelineStart, timelineLength) => (date) => {
|
||||
const percent = differenceInMilliseconds(date, timelineStart) / timelineLength * 100
|
||||
const value = Number(format(date, 'T'))
|
||||
return {percent, value}
|
||||
}
|
||||
|
||||
const getFormattedBlockedIntervals = (blockedDates = [], [startTime, endTime]) => {
|
||||
if (!blockedDates.length) return null
|
||||
|
||||
const timelineLength = differenceInMilliseconds(endTime, startTime)
|
||||
const getConfig = getTimelineConfig(startTime, timelineLength)
|
||||
|
||||
const formattedBlockedDates = blockedDates.map((interval, index) => {
|
||||
let {start, end} = interval
|
||||
|
||||
if (isBefore(start, startTime)) start = startTime
|
||||
if (isAfter(end, endTime)) end = endTime
|
||||
|
||||
const source = getConfig(start)
|
||||
const target = getConfig(end)
|
||||
|
||||
return {id: `blocked-track-${index}`, source, target}
|
||||
})
|
||||
|
||||
return formattedBlockedDates
|
||||
}
|
||||
|
||||
const getNowConfig = ([startTime, endTime]) => {
|
||||
const timelineLength = differenceInMilliseconds(endTime, startTime)
|
||||
const getConfig = getTimelineConfig(startTime, timelineLength)
|
||||
|
||||
const source = getConfig(new Date())
|
||||
const target = getConfig(addMinutes(new Date(), 1))
|
||||
|
||||
return {id: 'now-track', source, target}
|
||||
}
|
||||
|
||||
class TimeRange extends React.Component {
|
||||
get disabledIntervals() {
|
||||
return getFormattedBlockedIntervals(this.props.disabledIntervals, this.props.timelineInterval)
|
||||
}
|
||||
|
||||
get now() {
|
||||
return getNowConfig(this.props.timelineInterval)
|
||||
}
|
||||
|
||||
onChange = newTime => {
|
||||
const formattedNewTime = newTime.map(t => new Date(t))
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(formattedNewTime)
|
||||
}
|
||||
}
|
||||
|
||||
checkIsSelectedIntervalNotValid = ([start, end], source, target) => {
|
||||
const {value: startInterval} = source
|
||||
const {value: endInterval} = target
|
||||
|
||||
if (startInterval > start && endInterval <= end || startInterval >= start && endInterval < end)
|
||||
return true
|
||||
if (start >= startInterval && end <= endInterval) return true
|
||||
|
||||
const isStartInBlockedInterval = start > startInterval && start < endInterval && end >= endInterval
|
||||
const isEndInBlockedInterval = end < endInterval && end > startInterval && start <= startInterval
|
||||
|
||||
return isStartInBlockedInterval || isEndInBlockedInterval
|
||||
}
|
||||
|
||||
onUpdate = newTime => {
|
||||
const {onUpdate} = this.props
|
||||
if (!onUpdate) {
|
||||
return
|
||||
}
|
||||
|
||||
const disabledIntervals = this.disabledIntervals
|
||||
|
||||
if (disabledIntervals?.length) {
|
||||
const isValuesNotValid = disabledIntervals.some(({source, target}) =>
|
||||
this.checkIsSelectedIntervalNotValid(newTime, source, target))
|
||||
const formattedNewTime = newTime.map(t => new Date(t))
|
||||
onUpdate({error: isValuesNotValid, time: formattedNewTime})
|
||||
return
|
||||
}
|
||||
|
||||
const formattedNewTime = newTime.map(t => new Date(t))
|
||||
onUpdate({error: false, time: formattedNewTime})
|
||||
}
|
||||
|
||||
getDateTicks = () => {
|
||||
const {timelineInterval, ticksNumber} = this.props
|
||||
return scaleTime().domain(timelineInterval).ticks(ticksNumber).map(t => +t)
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
sliderRailClassName,
|
||||
timelineInterval,
|
||||
selectedInterval,
|
||||
containerClassName,
|
||||
error,
|
||||
step,
|
||||
showNow,
|
||||
formatTick,
|
||||
mode,
|
||||
} = this.props
|
||||
|
||||
const domain = timelineInterval.map(t => Number(t))
|
||||
|
||||
const disabledIntervals = this.disabledIntervals
|
||||
|
||||
return (
|
||||
<div className={containerClassName || 'react_time_range__time_range_container'}>
|
||||
<Slider
|
||||
mode={mode}
|
||||
step={step}
|
||||
domain={domain}
|
||||
onUpdate={this.onUpdate}
|
||||
onChange={this.onChange}
|
||||
values={selectedInterval?.map(t => +t)}
|
||||
rootStyle={{position: 'relative', width: '100%'}}
|
||||
>
|
||||
<Rail>
|
||||
{({getRailProps}) =>
|
||||
<SliderRail className={sliderRailClassName} getRailProps={getRailProps}/>}
|
||||
</Rail>
|
||||
|
||||
<Handles>
|
||||
{({handles, getHandleProps}) => (
|
||||
<>
|
||||
{handles.map(handle => (
|
||||
<Handle
|
||||
error={error}
|
||||
key={handle.id}
|
||||
handle={handle}
|
||||
domain={domain}
|
||||
getHandleProps={getHandleProps}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</Handles>
|
||||
|
||||
<Tracks left={false} right={false}>
|
||||
{({tracks, getTrackProps}) => (
|
||||
<>
|
||||
{tracks?.map(({id, source, target}) =>
|
||||
<Track
|
||||
error={error}
|
||||
key={id}
|
||||
source={source}
|
||||
target={target}
|
||||
getTrackProps={getTrackProps}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Tracks>
|
||||
|
||||
{disabledIntervals?.length && (
|
||||
<Tracks left={false} right={false}>
|
||||
{({getTrackProps}) => (
|
||||
<>
|
||||
{disabledIntervals.map(({id, source, target}) => (
|
||||
<Track
|
||||
key={id}
|
||||
source={source}
|
||||
target={target}
|
||||
getTrackProps={getTrackProps}
|
||||
disabled
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</Tracks>
|
||||
)}
|
||||
|
||||
{showNow && (
|
||||
<Tracks left={false} right={false}>
|
||||
{({getTrackProps}) => (
|
||||
<Track
|
||||
key={this.now?.id}
|
||||
source={this.now?.source}
|
||||
target={this.now?.target}
|
||||
getTrackProps={getTrackProps}
|
||||
/>
|
||||
)}
|
||||
</Tracks>
|
||||
)}
|
||||
|
||||
<Ticks values={this.getDateTicks()}>
|
||||
{({ticks}) => (
|
||||
<>
|
||||
{ticks.map(tick => (
|
||||
<Tick
|
||||
key={tick.id}
|
||||
tick={tick}
|
||||
count={ticks.length}
|
||||
format={formatTick}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
</Ticks>
|
||||
</Slider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
TimeRange.propTypes = {
|
||||
ticksNumber: PropTypes.number.isRequired,
|
||||
selectedInterval: PropTypes.arrayOf(PropTypes.object),
|
||||
timelineInterval: PropTypes.arrayOf(PropTypes.object),
|
||||
disabledIntervals: PropTypes.arrayOf(PropTypes.object),
|
||||
containerClassName: PropTypes.string,
|
||||
sliderRailClassName: PropTypes.string,
|
||||
step: PropTypes.number,
|
||||
formatTick: PropTypes.func,
|
||||
}
|
||||
|
||||
TimeRange.defaultProps = {
|
||||
selectedInterval: [
|
||||
set(new Date(), {minutes: 0, seconds: 0, milliseconds: 0}),
|
||||
set(addHours(new Date(), 1), {minutes: 0, seconds: 0, milliseconds: 0})
|
||||
],
|
||||
timelineInterval: [startOfToday(), endOfToday()],
|
||||
formatTick: ms => format(new Date(ms), 'HH:mm'),
|
||||
disabledIntervals: [],
|
||||
step: 1000 * 60 * 30,
|
||||
ticksNumber: 48,
|
||||
error: false,
|
||||
mode: 3,
|
||||
}
|
||||
|
||||
export default TimeRange
|
126
apps/backtest-report/components/TimeRangeSlider/index.scss
Normal file
126
apps/backtest-report/components/TimeRangeSlider/index.scss
Normal file
|
@ -0,0 +1,126 @@
|
|||
$react-time-range--gray: #C8CACC;
|
||||
$react-time-range--highlight-tap: #000000;
|
||||
$react-time-range--rail-bg: #F5F7FA;
|
||||
$react-time-range--handle-bg: #FFFFFF;
|
||||
$react-time-range--handle-bg--disabled: #666;
|
||||
$react-time-range--track--valid: rgb(98, 203, 102);
|
||||
$react-time-range--track--not-valid: rgb(214, 0, 11);
|
||||
$react-time-range--tick-label: #77828C;
|
||||
$react-time-range--track--disabled: repeating-linear-gradient( -45deg, transparent, transparent 3px, #D0D3D7 4px, #D0D3D7 2px);
|
||||
|
||||
.react_time_range__time_range_container {
|
||||
padding: 30px 52px 0 52px;
|
||||
height: 70px;
|
||||
// width: 90%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.react_time_range__keyboard_handle {
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 3;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.react_time_range__track {
|
||||
position: absolute;
|
||||
transform: translate(0%, -50%);
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
transition: background-color .15s ease-in-out, border-color .15s ease;
|
||||
z-index: 3;
|
||||
&__disabled {
|
||||
@extend .react_time_range__track;
|
||||
z-index: 1;
|
||||
border-left: 1px solid $react-time-range--gray;
|
||||
border-right: 1px solid $react-time-range--gray;
|
||||
background: $react-time-range--track--disabled;
|
||||
}
|
||||
}
|
||||
|
||||
.react_time_range__rail {
|
||||
&__outer {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
transform: translate(0%, -50%);
|
||||
cursor: pointer;
|
||||
}
|
||||
&__inner {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
transform: translate(0%, -50%);
|
||||
pointer-events: none;
|
||||
background-color: $react-time-range--rail-bg;
|
||||
border-bottom: 1px solid $react-time-range--gray;
|
||||
}
|
||||
}
|
||||
|
||||
.react_time_range__handle {
|
||||
&_wrapper {
|
||||
position: absolute;
|
||||
transform: translate(-50%, -50%);
|
||||
-webkit-tap-highlight-color: $react-time-range--highlight-tap;
|
||||
z-index: 6;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
}
|
||||
&_container {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 4;
|
||||
width: 10px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 3px rgba(0,0,0, 0.4);
|
||||
background-color: $react-time-range--handle-bg;
|
||||
&__disabled {
|
||||
@extend .react_time_range__handle_container;
|
||||
background-color: $react-time-range--handle-bg--disabled;
|
||||
}
|
||||
}
|
||||
&_marker {
|
||||
width: 2px;
|
||||
height: 12px;
|
||||
margin: auto;
|
||||
border-radius: 2px;
|
||||
background-color: $react-time-range--track--valid;
|
||||
transition: background-color .2s ease;
|
||||
&__error {
|
||||
@extend .react_time_range__handle_marker;
|
||||
background-color: $react-time-range--track--not-valid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.react_time_range__tick {
|
||||
&_marker {
|
||||
position: absolute;
|
||||
margin-top: 20px;
|
||||
width: 1px;
|
||||
height: 5px;
|
||||
background-color: $react-time-range--gray;
|
||||
z-index: 2;
|
||||
&__large {
|
||||
@extend .react_time_range__tick_marker;
|
||||
margin-top: 15px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
&_label {
|
||||
position: absolute;
|
||||
margin-top: 28px;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
color: $react-time-range--tick-label;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
}
|
|
@ -2,12 +2,12 @@ import React, {useEffect, useRef, useState} from 'react';
|
|||
import {tsvParse} from "d3-dsv";
|
||||
import {Checkbox, Group, SegmentedControl, Table} from '@mantine/core';
|
||||
|
||||
|
||||
// https://github.com/tradingview/lightweight-charts/issues/543
|
||||
// const createChart = dynamic(() => import('lightweight-charts'));
|
||||
import {createChart, CrosshairMode, MouseEventParams, TimeRange} from 'lightweight-charts';
|
||||
import {ReportSummary} from "../types";
|
||||
import moment from "moment";
|
||||
import TimeRangeSlider from './TimeRangeSlider';
|
||||
|
||||
const parseKline = () => {
|
||||
return (d: any) => {
|
||||
|
@ -34,6 +34,23 @@ const parseKline = () => {
|
|||
};
|
||||
};
|
||||
|
||||
const selectKLines = (klines: KLine[], startTime: Date, endTime: Date): KLine[] => {
|
||||
const selected = [];
|
||||
for (let i = 0; i < klines.length; i++) {
|
||||
const k = klines[i]
|
||||
if (k.startTime < startTime) {
|
||||
continue
|
||||
}
|
||||
if (k.startTime > endTime) {
|
||||
break
|
||||
}
|
||||
|
||||
selected.push(k)
|
||||
}
|
||||
|
||||
return selected
|
||||
}
|
||||
|
||||
|
||||
const parseOrder = () => {
|
||||
return (d: any) => {
|
||||
|
@ -383,6 +400,13 @@ const TradingViewChart = (props: TradingViewChartProps) => {
|
|||
const [showPositionAverageCost, setShowPositionAverageCost] = useState(false);
|
||||
const [orders, setOrders] = useState<Order[]>([]);
|
||||
|
||||
const reportTimeRange = [
|
||||
new Date(props.reportSummary.startTime),
|
||||
new Date(props.reportSummary.endTime),
|
||||
]
|
||||
const [selectedTimeRange, setSelectedTimeRange] = useState(reportTimeRange)
|
||||
const [timeRange, setTimeRange] = useState(reportTimeRange);
|
||||
|
||||
useEffect(() => {
|
||||
if (!chartContainerRef.current || chartContainerRef.current.children.length > 0) {
|
||||
return;
|
||||
|
@ -412,7 +436,10 @@ const TradingViewChart = (props: TradingViewChartProps) => {
|
|||
}
|
||||
|
||||
const kLinesFetcher = fetchKLines(props.basePath, props.runID, props.symbol, currentInterval, new Date(props.reportSummary.startTime), new Date(props.reportSummary.endTime)).then((klines) => {
|
||||
chartData.klines = removeDuplicatedKLines(klines as Array<KLine>)
|
||||
if (klines) {
|
||||
chartData.allKLines = removeDuplicatedKLines(klines)
|
||||
chartData.klines = selectKLines(chartData.allKLines, selectedTimeRange[0], selectedTimeRange[1])
|
||||
}
|
||||
});
|
||||
fetchers.push(kLinesFetcher);
|
||||
|
||||
|
@ -537,7 +564,7 @@ const TradingViewChart = (props: TradingViewChartProps) => {
|
|||
}
|
||||
|
||||
};
|
||||
}, [props.runID, props.reportSummary, currentInterval, showPositionBase, showPositionAverageCost])
|
||||
}, [props.runID, props.reportSummary, currentInterval, showPositionBase, showPositionAverageCost, selectedTimeRange])
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
@ -558,6 +585,15 @@ const TradingViewChart = (props: TradingViewChartProps) => {
|
|||
|
||||
</div>
|
||||
|
||||
<TimeRangeSlider
|
||||
selectedInterval={selectedTimeRange}
|
||||
timelineInterval={timeRange}
|
||||
onChange={(tr: any) => {
|
||||
console.log("selectedTimeRange", tr)
|
||||
setSelectedTimeRange(tr)
|
||||
}}
|
||||
/>
|
||||
|
||||
<Group>
|
||||
<Checkbox label="Show Canceled" checked={showCanceledOrders}
|
||||
onChange={(event) => setShowCanceledOrders(event.currentTarget.checked)}/>
|
||||
|
@ -575,7 +611,7 @@ const TradingViewChart = (props: TradingViewChartProps) => {
|
|||
console.log("orderTime", orderTime)
|
||||
console.log("visibleRange", visibleRange)
|
||||
console.log("setVisibleRange", from, to, to - from)
|
||||
chart.current.timeScale().setVisibleRange({ from, to } as TimeRange);
|
||||
chart.current.timeScale().setVisibleRange({from, to} as TimeRange);
|
||||
// chart.current.timeScale().scrollToPosition(20, true);
|
||||
}}/>
|
||||
</div>
|
||||
|
@ -592,7 +628,7 @@ const OrderListTable = (props: OrderListTableProps) => {
|
|||
let orders = props.orders;
|
||||
|
||||
if (!props.showCanceled) {
|
||||
orders = orders.filter((order : Order) => {
|
||||
orders = orders.filter((order: Order) => {
|
||||
return order.status != "CANCELED"
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,11 +15,14 @@
|
|||
"@mantine/next": "^4.2.5",
|
||||
"d3-dsv": "^3.0.1",
|
||||
"d3-format": "^3.1.0",
|
||||
"d3-scale": "^4.0.2",
|
||||
"d3-time-format": "^4.1.0",
|
||||
"date-fns": "^2.28.0",
|
||||
"lightweight-charts": "^3.8.0",
|
||||
"moment": "^2.29.3",
|
||||
"next": "12.1.6",
|
||||
"react": "18.1.0",
|
||||
"react-compound-slider": "^3.4.0",
|
||||
"react-dom": "18.1.0",
|
||||
"tabler-icons-react": "^1.48.0"
|
||||
},
|
||||
|
@ -33,6 +36,7 @@
|
|||
"eslint": "8.14.0",
|
||||
"eslint-config-next": "12.1.6",
|
||||
"next-transpile-modules": "^9.0.0",
|
||||
"sass": "^1.53.0",
|
||||
"typescript": "4.6.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import '../styles/globals.css'
|
||||
import '../components/TimeRangeSlider/index.scss'
|
||||
|
||||
import type {AppProps} from 'next/app'
|
||||
import Head from 'next/head';
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ class MyDocument extends Document {
|
|||
styles: [
|
||||
<>
|
||||
{initialProps.styles}
|
||||
<ServerStyles html={initialProps.html} server={stylesServer}/>
|
||||
<ServerStyles key="server-styles" html={initialProps.html} server={stylesServer}/>
|
||||
</>
|
||||
],
|
||||
};
|
||||
|
|
|
@ -17,6 +17,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.12.5":
|
||||
version "7.18.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4"
|
||||
integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@emotion/cache@11.7.1", "@emotion/cache@^11.7.1":
|
||||
version "11.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
||||
|
@ -515,6 +522,14 @@ ansi-styles@^4.1.0:
|
|||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
anymatch@~3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
|
||||
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
|
||||
dependencies:
|
||||
normalize-path "^3.0.0"
|
||||
picomatch "^2.0.4"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
|
@ -584,6 +599,11 @@ balanced-match@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
|
@ -592,7 +612,7 @@ brace-expansion@^1.1.7:
|
|||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
braces@^3.0.2:
|
||||
braces@^3.0.2, braces@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
|
||||
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
|
||||
|
@ -630,6 +650,21 @@ chalk@^4.0.0:
|
|||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0":
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
|
||||
dependencies:
|
||||
anymatch "~3.1.2"
|
||||
braces "~3.0.2"
|
||||
glob-parent "~5.1.2"
|
||||
is-binary-path "~2.1.0"
|
||||
is-glob "~4.0.1"
|
||||
normalize-path "~3.0.0"
|
||||
readdirp "~3.6.0"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
clsx@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188"
|
||||
|
@ -686,13 +721,25 @@ csstype@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
|
||||
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
|
||||
|
||||
"d3-array@2 - 3":
|
||||
"d3-array@2 - 3", "d3-array@2.10.0 - 3":
|
||||
version "3.1.6"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.1.6.tgz#0342c835925826f49b4d16eb7027aec334ffc97d"
|
||||
integrity sha512-DCbBBNuKOeiR9h04ySRBMW52TFVc91O9wJziuyXw6Ztmy8D3oZbmCkOO3UHKC7ceNJsN2Mavo9+vwV8EAEUXzA==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
d3-array@^2.8.0:
|
||||
version "2.12.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
|
||||
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
|
||||
dependencies:
|
||||
internmap "^1.0.0"
|
||||
|
||||
"d3-color@1 - 3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2"
|
||||
integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==
|
||||
|
||||
d3-dsv@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-3.0.1.tgz#c63af978f4d6a0d084a52a673922be2160789b73"
|
||||
|
@ -702,19 +749,37 @@ d3-dsv@^3.0.1:
|
|||
iconv-lite "0.6"
|
||||
rw "1"
|
||||
|
||||
d3-format@^3.1.0:
|
||||
"d3-format@1 - 3", d3-format@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641"
|
||||
integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==
|
||||
|
||||
d3-time-format@^4.1.0:
|
||||
"d3-interpolate@1.2.0 - 3":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d"
|
||||
integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==
|
||||
dependencies:
|
||||
d3-color "1 - 3"
|
||||
|
||||
d3-scale@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396"
|
||||
integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==
|
||||
dependencies:
|
||||
d3-array "2.10.0 - 3"
|
||||
d3-format "1 - 3"
|
||||
d3-interpolate "1.2.0 - 3"
|
||||
d3-time "2.1.1 - 3"
|
||||
d3-time-format "2 - 4"
|
||||
|
||||
"d3-time-format@2 - 4", d3-time-format@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a"
|
||||
integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==
|
||||
dependencies:
|
||||
d3-time "1 - 3"
|
||||
|
||||
"d3-time@1 - 3":
|
||||
"d3-time@1 - 3", "d3-time@2.1.1 - 3":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.0.0.tgz#65972cb98ae2d4954ef5c932e8704061335d4975"
|
||||
integrity sha512-zmV3lRnlaLI08y9IMRXSDshQb5Nj77smnfpnd2LrBa/2K281Jijactokeak14QacHs/kKq0AQ121nidNYlarbQ==
|
||||
|
@ -726,6 +791,11 @@ damerau-levenshtein@^1.0.7:
|
|||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==
|
||||
|
||||
date-fns@^2.28.0:
|
||||
version "2.28.0"
|
||||
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.28.0.tgz#9570d656f5fc13143e50c975a3b6bbeb46cd08b2"
|
||||
integrity sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==
|
||||
|
||||
debug@^2.6.9:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
|
@ -1178,6 +1248,11 @@ fs.realpath@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
|
||||
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
|
@ -1220,7 +1295,7 @@ get-symbol-description@^1.0.0:
|
|||
call-bind "^1.0.2"
|
||||
get-intrinsic "^1.1.1"
|
||||
|
||||
glob-parent@^5.1.2:
|
||||
glob-parent@^5.1.2, glob-parent@~5.1.2:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
|
@ -1376,6 +1451,11 @@ ignore@^5.2.0:
|
|||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a"
|
||||
integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==
|
||||
|
||||
immutable@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef"
|
||||
integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==
|
||||
|
||||
import-fresh@^3.0.0, import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
|
@ -1421,6 +1501,11 @@ internal-slot@^1.0.3:
|
|||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
|
||||
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
|
||||
|
||||
internmap@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
|
||||
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
|
||||
|
||||
is-bigint@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
|
||||
|
@ -1428,6 +1513,13 @@ is-bigint@^1.0.1:
|
|||
dependencies:
|
||||
has-bigints "^1.0.1"
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
|
||||
dependencies:
|
||||
binary-extensions "^2.0.0"
|
||||
|
||||
is-boolean-object@^1.1.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
|
||||
|
@ -1460,7 +1552,7 @@ is-extglob@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
|
||||
|
||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3:
|
||||
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
|
@ -1720,6 +1812,11 @@ next@12.1.6:
|
|||
"@next/swc-win32-ia32-msvc" "12.1.6"
|
||||
"@next/swc-win32-x64-msvc" "12.1.6"
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
@ -1860,7 +1957,7 @@ picocolors@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picomatch@^2.3.1:
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
|
||||
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
|
||||
|
@ -1903,6 +2000,15 @@ queue-microtask@^1.2.2:
|
|||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||
|
||||
react-compound-slider@^3.4.0:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-compound-slider/-/react-compound-slider-3.4.0.tgz#0367befe1367bb7968b38d0cbf07db6192b3c57e"
|
||||
integrity sha512-KSje/rB0xSvvcb7YV0+82hkiXTV5ljSS7axKrNiXLf9AEO+rrr1Xq4MJWA+6v030YNNo/RoSoEB6D6fnoy+8ng==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
d3-array "^2.8.0"
|
||||
warning "^4.0.3"
|
||||
|
||||
react-dom@18.1.0:
|
||||
version "18.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.1.0.tgz#7f6dd84b706408adde05e1df575b3a024d7e8a2f"
|
||||
|
@ -1973,6 +2079,13 @@ readable-stream@~1.0.17, readable-stream@~1.0.27-1:
|
|||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readdirp@~3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
|
||||
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
regenerator-runtime@^0.13.4:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
|
@ -2048,6 +2161,15 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
|||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
sass@^1.53.0:
|
||||
version "1.53.0"
|
||||
resolved "https://registry.yarnpkg.com/sass/-/sass-1.53.0.tgz#eab73a7baac045cc57ddc1d1ff501ad2659952eb"
|
||||
integrity sha512-zb/oMirbKhUgRQ0/GFz8TSAwRq2IlR29vOUJZOx0l8sV+CkHUfHa4u5nqrG+1VceZp7Jfj59SVW9ogdhTvJDcQ==
|
||||
dependencies:
|
||||
chokidar ">=3.0.0 <4.0.0"
|
||||
immutable "^4.0.0"
|
||||
source-map-js ">=0.6.2 <2.0.0"
|
||||
|
||||
scheduler@^0.22.0:
|
||||
version "0.22.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.22.0.tgz#83a5d63594edf074add9a7198b1bae76c3db01b8"
|
||||
|
@ -2093,7 +2215,7 @@ slash@^3.0.0:
|
|||
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
|
||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||
|
||||
source-map-js@^1.0.1:
|
||||
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
@ -2313,7 +2435,7 @@ v8-compile-cache@^2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
|
||||
|
||||
warning@^4.0.2:
|
||||
warning@^4.0.2, warning@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3"
|
||||
integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==
|
||||
|
|
Loading…
Reference in New Issue
Block a user