mirror of
https://github.com/umami-software/umami.git
synced 2026-02-04 12:47:13 +01:00
MySQL query optimization. Added loading component.
This commit is contained in:
parent
a7e7469d22
commit
ccb98f836f
13 changed files with 158 additions and 109 deletions
13
components/common/Loading.js
Normal file
13
components/common/Loading.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import styles from './Loading.module.css';
|
||||
|
||||
export default function Loading({ className }) {
|
||||
return (
|
||||
<div className={classNames(styles.loading, className)}>
|
||||
<div />
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
41
components/common/Loading.module.css
Normal file
41
components/common/Loading.module.css
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
@keyframes blink {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.loading div {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 100%;
|
||||
background: var(--gray400);
|
||||
animation: blink 1.4s infinite;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.loading div + div {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.loading div:nth-child(2) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
.loading div:nth-child(3) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
}
|
||||
|
||||
.container .content {
|
||||
position: relative;
|
||||
border-left: 1px solid var(--gray300);
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ export default function BarChart({
|
|||
|
||||
options.scales.xAxes[0].time.unit = unit;
|
||||
options.scales.xAxes[0].ticks.callback = renderLabel;
|
||||
options.animation.duration = animationDuration;
|
||||
|
||||
onUpdate(chart.current);
|
||||
};
|
||||
|
|
@ -133,7 +134,7 @@ export default function BarChart({
|
|||
updateChart();
|
||||
}
|
||||
}
|
||||
}, [datasets]);
|
||||
}, [datasets, unit, animationDuration]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export default function EventsChart({ websiteId, startDate, endDate, unit }) {
|
|||
unit,
|
||||
tz: getTimezone(),
|
||||
});
|
||||
console.log({ data });
|
||||
|
||||
const map = data.reduce((obj, { x, t, y }) => {
|
||||
if (!obj[x]) {
|
||||
obj[x] = [];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { get } from 'lib/web';
|
|||
import { percentFilter } from 'lib/filters';
|
||||
import { formatNumber, formatLongNumber } from 'lib/format';
|
||||
import styles from './MetricsTable.module.css';
|
||||
import Loading from '../common/Loading';
|
||||
|
||||
export default function MetricsTable({
|
||||
title,
|
||||
|
|
@ -79,35 +80,37 @@ export default function MetricsTable({
|
|||
}
|
||||
}, [websiteId, startDate, endDate, type]);
|
||||
|
||||
if (!data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classNames(styles.container, className)}>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
{headerComponent}
|
||||
<div className={styles.metric} onClick={handleSetFormat}>
|
||||
{metric}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.body}>
|
||||
{limit
|
||||
? rankings.map(row => getRow(row))
|
||||
: data?.length > 0 && (
|
||||
<FixedSizeList height={500} itemCount={rankings.length} itemSize={30}>
|
||||
{Row}
|
||||
</FixedSizeList>
|
||||
{data ? (
|
||||
<>
|
||||
<div className={styles.header}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
{headerComponent}
|
||||
<div className={styles.metric} onClick={handleSetFormat}>
|
||||
{metric}
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.body}>
|
||||
{limit
|
||||
? rankings.map(row => getRow(row))
|
||||
: data?.length > 0 && (
|
||||
<FixedSizeList height={500} itemCount={rankings.length} itemSize={30}>
|
||||
{Row}
|
||||
</FixedSizeList>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
{limit && data.length > limit && (
|
||||
<Button icon={<Arrow />} size="xsmall" onClick={() => onExpand(type)}>
|
||||
<div>More</div>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<div className={styles.footer}>
|
||||
{limit && data.length > limit && (
|
||||
<Button icon={<Arrow />} size="xsmall" onClick={() => onExpand(type)}>
|
||||
<div>More</div>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<Loading />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import React from 'react';
|
||||
import CheckVisible from 'components/helpers/CheckVisible';
|
||||
import BarChart from './BarChart';
|
||||
|
||||
export default function PageviewsChart({ websiteId, data, unit, className, animationDuration }) {
|
||||
export default function PageviewsChart({ websiteId, data, unit, className }) {
|
||||
const handleUpdate = chart => {
|
||||
const {
|
||||
data: { datasets },
|
||||
options,
|
||||
} = chart;
|
||||
|
||||
datasets[0].data = data.uniques;
|
||||
datasets[1].data = data.pageviews;
|
||||
options.animation.duration = animationDuration;
|
||||
|
||||
chart.update();
|
||||
};
|
||||
|
|
@ -20,30 +19,35 @@ export default function PageviewsChart({ websiteId, data, unit, className, anima
|
|||
}
|
||||
|
||||
return (
|
||||
<BarChart
|
||||
className={className}
|
||||
chartId={websiteId}
|
||||
datasets={[
|
||||
{
|
||||
label: 'unique visitors',
|
||||
data: data.uniques,
|
||||
lineTension: 0,
|
||||
backgroundColor: 'rgb(38, 128, 235, 0.4)',
|
||||
borderColor: 'rgb(13, 102, 208, 0.4)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
{
|
||||
label: 'page views',
|
||||
data: data.pageviews,
|
||||
lineTension: 0,
|
||||
backgroundColor: 'rgb(38, 128, 235, 0.2)',
|
||||
borderColor: 'rgb(13, 102, 208, 0.2)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
]}
|
||||
unit={unit}
|
||||
records={data.pageviews.length}
|
||||
onUpdate={handleUpdate}
|
||||
/>
|
||||
<CheckVisible>
|
||||
{visible => (
|
||||
<BarChart
|
||||
className={className}
|
||||
chartId={websiteId}
|
||||
datasets={[
|
||||
{
|
||||
label: 'unique visitors',
|
||||
data: data.uniques,
|
||||
lineTension: 0,
|
||||
backgroundColor: 'rgb(38, 128, 235, 0.4)',
|
||||
borderColor: 'rgb(13, 102, 208, 0.4)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
{
|
||||
label: 'page views',
|
||||
data: data.pageviews,
|
||||
lineTension: 0,
|
||||
backgroundColor: 'rgb(38, 128, 235, 0.2)',
|
||||
borderColor: 'rgb(13, 102, 208, 0.2)',
|
||||
borderWidth: 1,
|
||||
},
|
||||
]}
|
||||
unit={unit}
|
||||
records={data.pageviews.length}
|
||||
animationDuration={visible ? 300 : 0}
|
||||
onUpdate={handleUpdate}
|
||||
/>
|
||||
)}
|
||||
</CheckVisible>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState, useEffect, useMemo, useRef } from 'react';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import PageviewsChart from './PageviewsChart';
|
||||
import CheckVisible from '../helpers/CheckVisible';
|
||||
import MetricsBar from './MetricsBar';
|
||||
import QuickButtons from './QuickButtons';
|
||||
import DateFilter from '../common/DateFilter';
|
||||
|
|
@ -74,19 +73,10 @@ export default function WebsiteChart({
|
|||
</StickyHeader>
|
||||
</div>
|
||||
<div className="row">
|
||||
<CheckVisible className="col">
|
||||
{visible => (
|
||||
<>
|
||||
<PageviewsChart
|
||||
websiteId={websiteId}
|
||||
data={{ pageviews, uniques }}
|
||||
unit={unit}
|
||||
animationDuration={visible ? 300 : 0}
|
||||
/>
|
||||
<QuickButtons value={value} onChange={handleDateChange} />
|
||||
</>
|
||||
)}
|
||||
</CheckVisible>
|
||||
<div className="col">
|
||||
<PageviewsChart websiteId={websiteId} data={{ pageviews, uniques }} unit={unit} />
|
||||
<QuickButtons value={value} onChange={handleDateChange} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue