mirror of
https://github.com/openmhz/trunk-server.git
synced 2026-11-12 16:57:39 -05:00
activity charts!
This commit is contained in:
@@ -9,6 +9,11 @@
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@visx/axis": "^3.1.0",
|
||||
"@visx/curve": "^3.0.0",
|
||||
"@visx/group": "^3.0.0",
|
||||
"@visx/scale": "^3.0.0",
|
||||
"@visx/shape": "^3.0.0",
|
||||
"axios": "1.2.1",
|
||||
"date-fns": "2.29.3",
|
||||
"ejs": "3.1.8",
|
||||
|
||||
69
frontend/src/Call/Activity.js
Normal file
69
frontend/src/Call/Activity.js
Normal file
@@ -0,0 +1,69 @@
|
||||
import React, { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from "react";
|
||||
import { Link, useLocation, useParams, useNavigate } from 'react-router-dom';
|
||||
import FilterModal from "./components/FilterModal";
|
||||
import GroupModal from "./components/GroupModal";
|
||||
import CalendarModal from "./components/CalendarModal";
|
||||
import CallPlayer from "./CallPlayer";
|
||||
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { setFilter, setDateFilter } from "../features/callPlayer/callPlayerSlice";
|
||||
|
||||
import { useGetStatsQuery,useGetTalkgroupsQuery } from '../features/api/apiSlice'
|
||||
import ActivityChart from "./ActivityChart";
|
||||
import { selectSystem } from "../features/systems/systemsSlice";
|
||||
import {
|
||||
Container,
|
||||
Label,
|
||||
Rail,
|
||||
Sticky,
|
||||
Menu,
|
||||
Icon,
|
||||
Sidebar,
|
||||
Header
|
||||
|
||||
} from "semantic-ui-react";
|
||||
import "./CallPlayer.css";
|
||||
import queryString from '../query-string';
|
||||
import io from 'socket.io-client';
|
||||
import { useCallLink } from "./components/CallLinks";
|
||||
|
||||
|
||||
function Activity(props) {
|
||||
const { shortName } = useParams();
|
||||
const { data: statsData, isSuccess: isStatsSuccess } = useGetStatsQuery(shortName);
|
||||
const { data: talkgroupData, isSuccess: isTalkgroupsSuccess } = useGetTalkgroupsQuery(shortName);
|
||||
|
||||
const talkgroupStats = useMemo(() => {
|
||||
if (statsData ) {
|
||||
const result =[]
|
||||
for (const tgNum in statsData.talkgroupStats) {
|
||||
let tg = tgNum;
|
||||
if (talkgroupData && talkgroupData.talkgroups[tgNum] !== undefined) {
|
||||
tg = talkgroupData.talkgroups[tgNum].description;
|
||||
}
|
||||
result.push(<ActivityChart key={tgNum} tg={tg} data={statsData.talkgroupStats[tgNum].callCountHistory} />);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
}, [statsData, talkgroupData]);
|
||||
|
||||
|
||||
return (
|
||||
<Container style={{ marginTop: "65px"}}>
|
||||
<Header as="h2">Talkgroup Activity</Header>
|
||||
{
|
||||
talkgroupStats.map( chart => {
|
||||
return chart
|
||||
})
|
||||
}
|
||||
|
||||
</Container>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default Activity;
|
||||
102
frontend/src/Call/ActivityChart.js
Normal file
102
frontend/src/Call/ActivityChart.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import React from "react";
|
||||
import { Group } from '@visx/group';
|
||||
import { curveStep} from '@visx/curve';
|
||||
import { LinePath } from '@visx/shape';
|
||||
import { scaleLinear, scaleTime } from '@visx/scale';
|
||||
import { timeParse, timeFormat } from 'd3-time-format';
|
||||
import { AxisBottom, AxisLeft } from '@visx/axis';
|
||||
import { Loader } from "semantic-ui-react";
|
||||
import {
|
||||
Header
|
||||
} from "semantic-ui-react";
|
||||
|
||||
function ActivityChart(props) {
|
||||
|
||||
if (!props.data) {
|
||||
return (
|
||||
<Loader size='large'>Loading</Loader>
|
||||
)
|
||||
}
|
||||
|
||||
var callTotals = [];
|
||||
|
||||
|
||||
const now = new Date();
|
||||
var maxDate = now;
|
||||
var minDate = now;
|
||||
var minValue = 0;
|
||||
var maxValue = 0;
|
||||
var MS_PER_MINUTE = 60000;
|
||||
|
||||
for (let j = 0; j < props.data.length; j++) {
|
||||
let spotsBack = j;//statistic.callTotals.length - j;
|
||||
let time = new Date(now - spotsBack * 15 * MS_PER_MINUTE);
|
||||
if (time < minDate) minDate = time;
|
||||
if (props.data[j] > maxValue)
|
||||
maxValue = props.data[j];
|
||||
callTotals.push({ y: props.data[j], x: time });
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Define the graph dimensions and margins
|
||||
const width = 500; //props.width;
|
||||
const height = 250;
|
||||
const margin = { top: 20, bottom: 40, left: 40, right: 20 };
|
||||
const parseDate = timeParse("%Y%m%d");
|
||||
const format = timeFormat("%b %d");
|
||||
const formatDate = (date) => format(parseDate(date));
|
||||
const parseTime = timeParse('%Y-%m-%dT%H:%M:%S.%LZ');
|
||||
|
||||
// Then we'll create some bounds
|
||||
const xMax = width - margin.left - margin.right;
|
||||
const yMax = height - margin.top - margin.bottom;
|
||||
|
||||
var xScale, yScale;
|
||||
|
||||
// We'll use some mock data from `@vx/mock-data` for this.
|
||||
// scales
|
||||
xScale = scaleTime({
|
||||
range: [0, xMax],
|
||||
domain: [minDate, maxDate],
|
||||
tickFormat: () => (val) => formatDate(val)
|
||||
});
|
||||
yScale = scaleLinear({
|
||||
range: [yMax, 0],
|
||||
domain: [0, maxValue],
|
||||
});
|
||||
|
||||
const handleClick = (event) => {
|
||||
console.log('You clicked on:', event);
|
||||
};
|
||||
// accessors
|
||||
const x = d => xScale(d.x);
|
||||
const y = d => yScale(d.y);
|
||||
return (
|
||||
<div style={{float: 'left'}}>
|
||||
<Header as='h3'>{props.tg}</Header>
|
||||
<svg width={width} height={height}>
|
||||
<Group left={margin.left} top={margin.top}>
|
||||
<AxisBottom top={yMax} scale={xScale} numTicks={width > 520 ? 10 : 5} />
|
||||
<AxisLeft scale={yScale} />
|
||||
<LinePath
|
||||
data={callTotals}
|
||||
x={x}
|
||||
y={y}
|
||||
onClick={handleClick}
|
||||
strokeWidth={2}
|
||||
stroke="blue"
|
||||
curve={curveStep}
|
||||
/>
|
||||
</Group>
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ActivityChart;
|
||||
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import React, { useEffect, useLayoutEffect, useState, useRef, useCallback, useMemo } from "react";
|
||||
import React, { useEffect, useLayoutEffect, useState, useRef, useMemo } from "react";
|
||||
import { Link, useLocation, useParams, useNavigate } from 'react-router-dom';
|
||||
import FilterModal from "./components/FilterModal";
|
||||
import GroupModal from "./components/GroupModal";
|
||||
import CalendarModal from "./components/CalendarModal";
|
||||
import CallPlayer from "./CallPlayer";
|
||||
import Activity from "./Activity";
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { setFilter, setDateFilter } from "../features/callPlayer/callPlayerSlice";
|
||||
import { getCalls, addCall, getOlderCalls, getNewerCalls } from "../features/calls/callsSlice";
|
||||
import { useGetGroupsQuery, useGetSystemsQuery, } from '../features/api/apiSlice'
|
||||
import { selectSystem } from "../features/systems/systemsSlice";
|
||||
import {
|
||||
Container,
|
||||
Label,
|
||||
Rail,
|
||||
Sticky,
|
||||
Menu,
|
||||
Icon,
|
||||
Sidebar
|
||||
@@ -21,7 +19,6 @@ import {
|
||||
import "./CallPlayer.css";
|
||||
import queryString from '../query-string';
|
||||
import io from 'socket.io-client';
|
||||
import { useCallLink } from "./components/CallLinks";
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +40,7 @@ function Calls(props) {
|
||||
const [filterVisible, setFilterVisible] = useState(false);
|
||||
const [groupVisible, setGroupVisible] = useState(false);
|
||||
const [calendarVisible, setCalendarVisible] = useState(false);
|
||||
const [activityVisible, setActivityVisible] = useState(false);
|
||||
const [isConnected, setIsConnected] = useState(socket.connected);
|
||||
const [selectCallId, setSelectCallId] = useState(false);
|
||||
const [live, setLive] = useState(true);
|
||||
@@ -85,6 +83,7 @@ function Calls(props) {
|
||||
const handleSidebarToggle = () => setSidebarOpened(!sidebarOpened);
|
||||
const handleFilterToggle = () => setFilterVisible(!filterVisible);
|
||||
const handleCalendarToggle = () => setCalendarVisible(!calendarVisible);
|
||||
const handleActivityToggle = () => setActivityVisible(!activityVisible);
|
||||
|
||||
const getFilterDescription = () => {
|
||||
let filter = { type: 'all', code: "", filterStarred: false };
|
||||
@@ -400,6 +399,10 @@ function Calls(props) {
|
||||
{system && system.name}
|
||||
</Container>
|
||||
<Menu.Menu position="right">
|
||||
<Menu.Item name='atcivity-btn' onClick={handleActivityToggle} active={activityVisible}>
|
||||
<Icon name="line graph" />
|
||||
<span >Activity</span>
|
||||
</Menu.Item>
|
||||
<Menu.Item name='archive-btn' onClick={handleCalendarToggle} active={!live}>
|
||||
<Icon name="calendar" />
|
||||
<span className="desktop-only">
|
||||
@@ -416,7 +419,10 @@ function Calls(props) {
|
||||
</Menu.Item>
|
||||
</Menu.Menu>
|
||||
</Menu>
|
||||
<CallPlayer callsData={callsData} selectCallId={selectCallId} handleNewer={handleNewer} handleOlder={handleOlder} />
|
||||
{activityVisible
|
||||
? <Activity />
|
||||
: <CallPlayer callsData={callsData} selectCallId={selectCallId} handleNewer={handleNewer} handleOlder={handleOlder} />
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ export const apiSlice = createApi({
|
||||
// The URL for the request is '/fakeApi/posts'
|
||||
query: (shortName) => ({ url: `/${shortName}/talkgroups` })
|
||||
}),
|
||||
getStats: builder.query({
|
||||
// The URL for the request is '/fakeApi/posts'
|
||||
query: (shortName) => ({ url: `/${shortName}/stats` })
|
||||
}),
|
||||
addNewEvent: builder.mutation({
|
||||
query: initialEvent => ({
|
||||
url: '/events',
|
||||
@@ -56,4 +60,4 @@ export const apiSlice = createApi({
|
||||
})
|
||||
|
||||
// Export the auto-generated hook for the `getPosts` query endpoint
|
||||
export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery, useGetEventsQuery, useGetEventQuery, useAddNewEventMutation } = apiSlice
|
||||
export const { useGetGroupsQuery, useGetSystemsQuery, useGetTalkgroupsQuery, useGetStatsQuery, useGetEventsQuery, useGetEventQuery, useAddNewEventMutation } = apiSlice
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
const now = new Date();
|
||||
const now = new Date().getTime();
|
||||
const initialState = {
|
||||
isWaiting: false,
|
||||
shortName: "",
|
||||
|
||||
@@ -54,7 +54,7 @@ export const { selectAll: selectAllCalls, selectById: selectCallById } = callsAd
|
||||
return selectCallsData(state) ?? initialState
|
||||
})
|
||||
*/
|
||||
const now = new Date();
|
||||
const now = new Date().getTime();
|
||||
|
||||
export const callsAdapter = createEntityAdapter({
|
||||
selectId: (call) => call._id,
|
||||
@@ -177,7 +177,7 @@ export const getCalls = createAsyncThunk(
|
||||
'calls/getOlderCalls',
|
||||
async({},{getState, requestId} ) => {
|
||||
const {loading,oldestCallTime, newestCallTime} = getState().calls;
|
||||
const url = buildCallUrl(getState,"older",oldestCallTime.getTime());
|
||||
const url = buildCallUrl(getState,"older",oldestCallTime);
|
||||
const res = await fetch(url).then(
|
||||
(data) => data.json()
|
||||
)
|
||||
@@ -188,7 +188,7 @@ export const getCalls = createAsyncThunk(
|
||||
'calls/getNewerCalls',
|
||||
async({},{getState, requestId} ) => {
|
||||
const {loading,oldestCallTime, newestCallTime} = getState().calls;
|
||||
const url = buildCallUrl(getState,"newer",newestCallTime.getTime());
|
||||
const url = buildCallUrl(getState,"newer",newestCallTime);
|
||||
const res = await fetch(url).then(
|
||||
(data) => data.json()
|
||||
)
|
||||
@@ -223,8 +223,8 @@ export const callsSlice = createSlice({
|
||||
const firstTime = state.data.entities[first].time;
|
||||
const last = state.data.ids[state.data.ids.length-1];
|
||||
const lastTime = state.data.entities[last].time;
|
||||
state.newestCallTime = new Date(firstTime)
|
||||
state.oldestCallTime = new Date(lastTime)
|
||||
state.newestCallTime = new Date(firstTime).getTime();
|
||||
state.oldestCallTime = new Date(lastTime).getTime();
|
||||
}
|
||||
},
|
||||
[getOlderCalls.pending]: (state) => {
|
||||
@@ -242,8 +242,8 @@ export const callsSlice = createSlice({
|
||||
const firstTime = state.data.entities[first].time;
|
||||
const last = state.data.ids[state.data.ids.length-1];
|
||||
const lastTime = state.data.entities[last].time;
|
||||
state.newestCallTime = new Date(firstTime)
|
||||
state.oldestCallTime = new Date(lastTime)
|
||||
state.newestCallTime = new Date(firstTime).getTime();
|
||||
state.oldestCallTime = new Date(lastTime).getTime();
|
||||
}
|
||||
},
|
||||
[getNewerCalls.pending]: (state) => {
|
||||
@@ -261,8 +261,8 @@ export const callsSlice = createSlice({
|
||||
const firstTime = state.data.entities[first].time;
|
||||
const last = state.data.ids[state.data.ids.length-1];
|
||||
const lastTime = state.data.entities[last].time;
|
||||
state.newestCallTime = new Date(firstTime)
|
||||
state.oldestCallTime = new Date(lastTime)
|
||||
state.newestCallTime = new Date(firstTime).getTime();
|
||||
state.oldestCallTime = new Date(lastTime).getTime();
|
||||
}
|
||||
},
|
||||
[addStar.fulfilled]: (state, {payload}) => {
|
||||
|
||||
@@ -2674,6 +2674,47 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/d3-color@*":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.0.tgz#6594da178ded6c7c3842f3cc0ac84b156f12f2d4"
|
||||
integrity sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==
|
||||
|
||||
"@types/d3-interpolate@^3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.1.tgz#e7d17fa4a5830ad56fe22ce3b4fac8541a9572dc"
|
||||
integrity sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==
|
||||
dependencies:
|
||||
"@types/d3-color" "*"
|
||||
|
||||
"@types/d3-path@^1", "@types/d3-path@^1.0.8":
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c"
|
||||
integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==
|
||||
|
||||
"@types/d3-scale@^4.0.2":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.3.tgz#7a5780e934e52b6f63ad9c24b105e33dd58102b5"
|
||||
integrity sha512-PATBiMCpvHJSMtZAMEhc2WyL+hnzarKzI6wAHYjhsonjWJYGq5BXTzQjv4l8m2jO183/4wZ90rKvSeT7o72xNQ==
|
||||
dependencies:
|
||||
"@types/d3-time" "*"
|
||||
|
||||
"@types/d3-shape@^1.3.1":
|
||||
version "1.3.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.8.tgz#c3c15ec7436b4ce24e38de517586850f1fea8e89"
|
||||
integrity sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg==
|
||||
dependencies:
|
||||
"@types/d3-path" "^1"
|
||||
|
||||
"@types/d3-time@*":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.0.tgz#e1ac0f3e9e195135361fa1a1d62f795d87e6e819"
|
||||
integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==
|
||||
|
||||
"@types/d3-time@^2.0.0":
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.1.tgz#743fdc821c81f86537cbfece07093ac39b4bc342"
|
||||
integrity sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==
|
||||
|
||||
"@types/eslint-scope@^3.7.3":
|
||||
version "3.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16"
|
||||
@@ -2788,6 +2829,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
|
||||
|
||||
"@types/lodash@^4.14.172":
|
||||
version "4.14.192"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.192.tgz#5790406361a2852d332d41635d927f1600811285"
|
||||
integrity sha512-km+Vyn3BYm5ytMO13k9KTp27O75rbQ0NFw+U//g+PX7VZyjCioXaRFisqSIJRECljcTv73G3i6BpglNGHgUQ5A==
|
||||
|
||||
"@types/mime@*":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
|
||||
@@ -3039,6 +3085,84 @@
|
||||
"@typescript-eslint/types" "5.47.0"
|
||||
eslint-visitor-keys "^3.3.0"
|
||||
|
||||
"@visx/axis@^3.1.0":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-3.1.0.tgz#775b221e5abfdec25304c607eeae8cda1a8bade6"
|
||||
integrity sha512-JDj/1VYx0JO0pHFtwoFtYcnqdoZFh/dpHImEl169S5nTslSFlIoNTXA/ekpBP6ELkEZ59gmF1X5k29x6MFBwCA==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
"@visx/group" "3.0.0"
|
||||
"@visx/point" "3.0.1"
|
||||
"@visx/scale" "3.0.0"
|
||||
"@visx/shape" "3.0.0"
|
||||
"@visx/text" "3.0.0"
|
||||
classnames "^2.3.1"
|
||||
prop-types "^15.6.0"
|
||||
|
||||
"@visx/curve@3.0.0", "@visx/curve@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-3.0.0.tgz#c54568472e00a38483c58cf52e4a6ddb2887c2d4"
|
||||
integrity sha512-kvHJDLBeczTQ87ZExSTfRxej06l6o6UiQ0NHf9+xpAin06y6Qk1ThOHHWJTGM6KGzwlu7jEauJGHwZs6nMhDvA==
|
||||
dependencies:
|
||||
"@types/d3-shape" "^1.3.1"
|
||||
d3-shape "^1.0.6"
|
||||
|
||||
"@visx/group@3.0.0", "@visx/group@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/group/-/group-3.0.0.tgz#e7f9752599bcc7e141ff5317a2a9a502577ab8df"
|
||||
integrity sha512-SFjXhTMcsaVAb1/TVL1KM5vn8gQTIVgSx0ATdDl4BJSFp2ym1lO8LY4jpV4SFweaHnWxVwrrfGLTn5QsYnvmjQ==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
classnames "^2.3.1"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
"@visx/point@3.0.1":
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@visx/point/-/point-3.0.1.tgz#77587ddaabf6f3023f09f8a0ce33a2c27c9d64c8"
|
||||
integrity sha512-S5WOBMgEP2xHcgs3A2BFB2vwzrk0tMmn3PGZAbQJ+lu4HlnalDP72klUnxLTH8xclNNvpUHtHM5eLIJXyHx6Pw==
|
||||
|
||||
"@visx/scale@3.0.0", "@visx/scale@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-3.0.0.tgz#727123f0c930d3346a4473e926831c45997e0312"
|
||||
integrity sha512-WSf+wrxZEvu5TPGfGTafzzX1MbogbIxfD9ZKM9p7xfw65v23G0dNMy4bqVBUbOJigONoQkIZyqQ+gz5AJ/ioIg==
|
||||
dependencies:
|
||||
"@types/d3-interpolate" "^3.0.1"
|
||||
"@types/d3-scale" "^4.0.2"
|
||||
"@types/d3-time" "^2.0.0"
|
||||
d3-interpolate "^3.0.1"
|
||||
d3-scale "^4.0.2"
|
||||
d3-time "^2.1.1"
|
||||
|
||||
"@visx/shape@3.0.0", "@visx/shape@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-3.0.0.tgz#a1d4bd0e12cc94c164252f175997932a09c24652"
|
||||
integrity sha512-t6lpP9bIA1vwChDwiOUWl92ro29XF/M8IVNWRA0pm4LGxGGTACvxG3Agfcdi3JprahUVqPpnRCwuR36PDanq3Q==
|
||||
dependencies:
|
||||
"@types/d3-path" "^1.0.8"
|
||||
"@types/d3-shape" "^1.3.1"
|
||||
"@types/lodash" "^4.14.172"
|
||||
"@types/react" "*"
|
||||
"@visx/curve" "3.0.0"
|
||||
"@visx/group" "3.0.0"
|
||||
"@visx/scale" "3.0.0"
|
||||
classnames "^2.3.1"
|
||||
d3-path "^1.0.5"
|
||||
d3-shape "^1.2.0"
|
||||
lodash "^4.17.21"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
"@visx/text@3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/text/-/text-3.0.0.tgz#9099c3605027b9ab4c54bde97518a648136c3629"
|
||||
integrity sha512-LW6v5T/gpd9RGw83/ScXncYc6IlcfzXTpaN8WbbxLRI65gdvSqrykwAMR0cbpQmzoVFuZXljqOf0QslHGnBg1w==
|
||||
dependencies:
|
||||
"@types/lodash" "^4.14.172"
|
||||
"@types/react" "*"
|
||||
classnames "^2.3.1"
|
||||
lodash "^4.17.21"
|
||||
prop-types "^15.7.2"
|
||||
reduce-css-calc "^1.3.0"
|
||||
|
||||
"@webassemblyjs/ast@1.11.1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
|
||||
@@ -3630,6 +3754,11 @@ babel-preset-react-app@^10.0.1:
|
||||
babel-plugin-macros "^3.1.0"
|
||||
babel-plugin-transform-react-remove-prop-types "^0.4.24"
|
||||
|
||||
balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
integrity sha512-STw03mQKnGUYtoNjmowo4F2cRmIIxYEGiMsjjwla/u5P1lxadj/05WkNaFjNiKTgJkj8KiXbgAiRTmcQRwQNtg==
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
@@ -3913,7 +4042,7 @@ cjs-module-lexer@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
|
||||
integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==
|
||||
|
||||
classnames@^2.2.6:
|
||||
classnames@^2.2.6, classnames@^2.3.1:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924"
|
||||
integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==
|
||||
@@ -4344,6 +4473,81 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
|
||||
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
|
||||
|
||||
d3-array@2:
|
||||
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-array@2 - 3", "d3-array@2.10.0 - 3":
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.3.tgz#39f1f4954e4a09ff69ac597c2d61906b04e84740"
|
||||
integrity sha512-JRHwbQQ84XuAESWhvIPaUV4/1UYTBOLiOPGWqgFDHZS1D5QN9c57FbH3QpEnQMYiOXNzKUQyGTZf+EVO7RT5TQ==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
"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-format@1 - 3":
|
||||
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-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1:
|
||||
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-path@1, d3-path@^1.0.5:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
|
||||
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
|
||||
|
||||
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-shape@^1.0.6, d3-shape@^1.2.0:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
|
||||
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
|
||||
dependencies:
|
||||
d3-path "1"
|
||||
|
||||
"d3-time-format@2 - 4":
|
||||
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@2.1.1 - 3":
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7"
|
||||
integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==
|
||||
dependencies:
|
||||
d3-array "2 - 3"
|
||||
|
||||
d3-time@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
|
||||
integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==
|
||||
dependencies:
|
||||
d3-array "2"
|
||||
|
||||
damerau-levenshtein@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7"
|
||||
@@ -5911,6 +6115,16 @@ internal-slot@^1.0.3:
|
||||
has "^1.0.3"
|
||||
side-channel "^1.0.4"
|
||||
|
||||
"internmap@1 - 2":
|
||||
version "2.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==
|
||||
|
||||
ip@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
|
||||
@@ -7072,6 +7286,11 @@ makeerror@1.0.12:
|
||||
dependencies:
|
||||
tmpl "1.0.5"
|
||||
|
||||
math-expression-evaluator@^1.2.14:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.4.0.tgz#3d66031117fbb7b9715ea6c9c68c2cd2eebd37e2"
|
||||
integrity sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==
|
||||
|
||||
mdn-data@2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
@@ -8288,7 +8507,7 @@ prompts@^2.0.1, prompts@^2.4.2:
|
||||
kleur "^3.0.3"
|
||||
sisteransi "^1.0.5"
|
||||
|
||||
prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
|
||||
version "15.8.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||
@@ -8638,6 +8857,22 @@ redent@^3.0.0:
|
||||
indent-string "^4.0.0"
|
||||
strip-indent "^3.0.0"
|
||||
|
||||
reduce-css-calc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
|
||||
integrity sha512-0dVfwYVOlf/LBA2ec4OwQ6p3X9mYxn/wOl2xTcLwjnPYrkgEfPx3VI4eGCH3rQLlPISG5v9I9bkZosKsNRTRKA==
|
||||
dependencies:
|
||||
balanced-match "^0.4.2"
|
||||
math-expression-evaluator "^1.2.14"
|
||||
reduce-function-call "^1.0.1"
|
||||
|
||||
reduce-function-call@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f"
|
||||
integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
redux-thunk@2.4.2, redux-thunk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"
|
||||
|
||||
Reference in New Issue
Block a user