change(ui): example cards with data

This commit is contained in:
Shekar Siri 2024-06-27 17:49:02 +02:00
parent 808526251e
commit 29287c7e4d
17 changed files with 479 additions and 275 deletions

View file

@ -1 +0,0 @@
export { default } from './CustomMetriLineChart';

View file

@ -1,7 +1,7 @@
import React from 'react'
import { Styles } from '../../common';
import { ResponsiveContainer, XAxis, YAxis, CartesianGrid, Tooltip } from 'recharts';
import { LineChart, Line, Legend } from 'recharts';
import {Styles} from '../../common';
import {ResponsiveContainer, XAxis, YAxis, CartesianGrid, Tooltip} from 'recharts';
import {LineChart, Line, Legend} from 'recharts';
interface Props {
data: any;
@ -9,46 +9,56 @@ interface Props {
// seriesMap: any;
colors: any;
onClick?: (event, index) => void;
yaxis?: any;
label?: string;
}
function CustomMetriLineChart(props: Props) {
const { data = { chart: [], namesMap: [] }, params, colors, onClick = () => null } = props;
function CustomMetricLineChart(props: Props) {
const {
data = {chart: [], namesMap: []},
params,
colors,
onClick = () => null,
yaxis = {...Styles.yaxis},
label = 'Number of Sessions'
} = props;
return (
<ResponsiveContainer height={ 240 } width="100%">
<ResponsiveContainer height={240} width="100%">
<LineChart
data={ data.chart }
data={data.chart}
margin={Styles.chartMargins}
// syncId={ showSync ? "domainsErrors_4xx" : undefined }
onClick={onClick}
// isAnimationActive={ false }
>
<CartesianGrid strokeDasharray="3 3" vertical={ false } stroke="#EEEEEE" />
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#EEEEEE"/>
<XAxis
{...Styles.xaxis}
dataKey="time"
interval={params.density/7}
interval={params.density / 7}
/>
<YAxis
{...Styles.yaxis}
<YAxis
{...yaxis}
allowDecimals={false}
tickFormatter={val => Styles.tickFormatter(val)}
label={{
label={{
...Styles.axisLabelLeft,
value: "Number of Sessions"
value: label || "Number of Sessions"
}}
/>
<Legend />
<Legend/>
<Tooltip {...Styles.tooltip} />
{ Array.isArray(data.namesMap) && data.namesMap.map((key, index) => (
{Array.isArray(data.namesMap) && data.namesMap.map((key, index) => (
<Line
key={key}
name={key}
type="monotone"
dataKey={key}
stroke={colors[index]}
fillOpacity={ 1 }
strokeWidth={ 2 }
strokeOpacity={ 0.6 }
fillOpacity={1}
strokeWidth={2}
strokeOpacity={0.6}
// fill="url(#colorCount)"
dot={false}
/>
@ -58,4 +68,4 @@ function CustomMetriLineChart(props: Props) {
)
}
export default CustomMetriLineChart
export default CustomMetricLineChart

View file

@ -0,0 +1 @@
export { default } from './CustomMetricLineChart';

View file

@ -46,30 +46,28 @@ const cols = [
interface Props {
data: any
metric?: any
isTemplate?: boolean
}
function CallWithErrors(props: Props) {
const { data, metric } = props;
const { data } = props;
const [search, setSearch] = React.useState('')
const test = (value = '', serach: any) => getRE(serach, 'i').test(value);
const _data = search ? metric.data.chart.filter((i: any) => test(i.urlHostpath, search)) : metric.data.chart;
const _data = search ? data.chart.filter((i: any) => test(i.urlHostpath, search)) : data.chart;
const write = ({ target: { name, value } }: any) => {
setSearch(value)
};
return (
<NoContent
size="small"
title={NO_METRIC_DATA}
show={ metric.data.chart.length === 0 }
show={ data.chart.length === 0 }
style={{ height: '240px'}}
>
<div style={{ height: '240px'}}>
<div className={ cn(stl.topActions, 'py-3 flex text-right')}>
<input disabled={metric.data.chart.length === 0} className={stl.searchField} name="search" placeholder="Filter by Path" onChange={write} />
<input disabled={data.chart.length === 0} className={stl.searchField} name="search" placeholder="Filter by Path" onChange={write} />
</div>
<Table
small

View file

@ -1,55 +1,24 @@
import ExampleFunnel from "./Examples/Funnel";
import ExamplePath from "./Examples/Path";
import ExampleTrend from "./Examples/Trend";
import Trend from "./Examples/Trend";
import PerfBreakdown from "./Examples/PerfBreakdown";
import BarChartCard from "./Examples/BarChart";
import SlowestDomain from "./Examples/SlowestDomain";
import ByBrowser from "./Examples/SessionsBy/ByBrowser";
import BySystem from "./Examples/SessionsBy/BySystem";
import ByCountry from "./Examples/SessionsBy/ByCountry";
import ByUrl from "./Examples/SessionsBy/ByUrl";
import {
ERRORS,
FUNNEL, INSIGHTS,
PERFORMANCE,
RESOURCE_MONITORING,
TABLE,
TIMESERIES,
USER_PATH,
WEB_VITALS
} from "App/constants/card";
import {ERRORS, FUNNEL, INSIGHTS, PERFORMANCE, TABLE, TIMESERIES, USER_PATH, WEB_VITALS} from "App/constants/card";
import {FilterKey} from "Types/filter/filterType";
import {Activity, BarChart, TableCellsMerge, TrendingUp} from "lucide-react";
import WebVital from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/WebVital";
import Trend from "./Examples/Trend";
import Bars from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/Bars";
import ByIssues from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByIssues";
import InsightsExample from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/InsightsExample";
import ByUser from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/SessionsBy/ByUser";
// const TYPE = {
// FUNNEL: 'funnel',
// PATH_FINDER: 'path-finder',
// TREND: 'trend',
// SESSIONS_BY: 'sessions-by',
// BREAKDOWN: 'breakdown',
// SLOWEST_DOMAIN: 'slowest-domain',
// SESSIONS_BY_ERRORS: 'sessions-by-errors',
// SESSIONS_BY_ISSUES: 'sessions-by-issues',
// SESSIONS_BY_BROWSER: 'sessions-by-browser',
// SESSIONS_BY_SYSTEM: 'sessions-by-system',
// SESSIONS_BY_COUNTRY: 'sessions-by-country',
// SESSIONS_BY_URL: 'sessions-by-url',
//
//
// ERRORS_JS: 'js-errors',
// ERRORS_BY_ORIGIN: 'errors-by-origin',
// ERRORS_BY_DOMAIN: 'errors-by-domain',
// ERRORS_BY_TYPE: 'errors-by-type',
// CALLS_WITH_ERRORS: 'calls-with-errors',
// ERRORS_4XX: '4xx-errors',
// ERRORS_5XX: '5xx-errors',
// }
import BarChartCard from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/BarChart";
import AreaChartCard from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/AreaChartCard";
import CallsWithErrorsExample
from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/CallsWithErrorsExample";
export const CARD_CATEGORY = {
PRODUCT_ANALYTICS: 'product-analytics',
@ -87,6 +56,7 @@ export const CARD_LIST: CardType[] = [
category: CARD_CATEGORIES[0].key,
example: ExampleFunnel,
width: 4,
height: 356,
data: {
stages: [
{
@ -126,6 +96,13 @@ export const CARD_LIST: CardType[] = [
cardType: TIMESERIES,
metricOf: 'sessionCount',
category: CARD_CATEGORIES[0].key,
data: {
chart: generateTimeSeriesData(),
label: "Number of Sessions",
namesMap: [
"Series 1"
]
},
example: ExampleTrend,
},
@ -155,7 +132,14 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.CPU,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "CPU Load (%)",
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -164,7 +148,13 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.CRASHES,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -173,7 +163,14 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.FPS,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "Frames Per Second",
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -182,7 +179,14 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.PAGES_DOM_BUILD_TIME,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "DOM Build Time (ms)",
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -191,7 +195,15 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.MEMORY_CONSUMPTION,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "JS Heap Size (MB)",
unit: 'mb',
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -200,7 +212,14 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.PAGES_RESPONSE_TIME,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "Page Response Time (ms)",
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -209,7 +228,14 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.PAGES_RESPONSE_TIME_DISTRIBUTION,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
label: "Number of Calls",
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -218,7 +244,13 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.RESOURCES_VS_VISUALLY_COMPLETE,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateBarChartDate(),
namesMap: [
"Series 1"
]
},
example: BarChartCard,
},
{
@ -227,6 +259,7 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.SESSIONS_PER_BROWSER,
category: CARD_CATEGORIES[1].key,
data: generateRandomBarsData(),
example: Bars,
},
@ -236,6 +269,7 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.SLOWEST_DOMAINS,
category: CARD_CATEGORIES[1].key,
data: generateRandomBarsData(),
example: Bars,
},
@ -245,7 +279,13 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.SPEED_LOCATION,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -254,7 +294,13 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.TIME_TO_RENDER,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
{
@ -263,7 +309,13 @@ export const CARD_LIST: CardType[] = [
cardType: PERFORMANCE,
metricOf: FilterKey.IMPACTED_SESSIONS_BY_SLOW_PAGES,
category: CARD_CATEGORIES[1].key,
example: Trend,
data: {
chart: generateAreaData(),
namesMap: [
"Series 1"
]
},
example: AreaChartCard,
},
@ -326,7 +378,10 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.IMPACTED_SESSIONS_BY_JS_ERRORS,
category: CARD_CATEGORIES[3].key,
example: PerfBreakdown,
data: {
chart: generateBarChartDate(),
},
example: BarChartCard,
},
{
title: 'Errors by Origin',
@ -334,7 +389,10 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.RESOURCES_BY_PARTY,
category: CARD_CATEGORIES[3].key,
example: PerfBreakdown,
data: {
chart: generateBarChartDate(),
},
example: BarChartCard,
},
{
title: 'Errors by Domain',
@ -351,7 +409,10 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.ERRORS_PER_TYPE,
category: CARD_CATEGORIES[3].key,
example: PerfBreakdown,
data: {
chart: generateBarChartDate(),
},
example: BarChartCard,
},
{
title: 'Calls with Errors',
@ -359,7 +420,33 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.CALLS_ERRORS,
category: CARD_CATEGORIES[3].key,
example: PerfBreakdown,
width: 4,
data: {
chart: [
{
"method": "GET",
"urlHostpath": 'https://openreplay.com',
"allRequests": 1333,
"4xx": 1333,
"5xx": 0
},
{
"method": "POST",
"urlHostpath": 'https://company.domain.com',
"allRequests": 10,
"4xx": 10,
"5xx": 0
},
{
"method": "PUT",
"urlHostpath": 'https://example.com',
"allRequests": 3,
"4xx": 3,
"5xx": 0
}
],
},
example: CallsWithErrorsExample,
},
{
@ -368,7 +455,14 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.DOMAINS_ERRORS_4XX,
category: CARD_CATEGORIES[3].key,
example: Trend,
data: {
chart: generateTimeSeriesData(),
label: "Number of Errors",
namesMap: [
"Series 1"
]
},
example: ExampleTrend,
},
{
@ -377,7 +471,14 @@ export const CARD_LIST: CardType[] = [
cardType: ERRORS,
metricOf: FilterKey.DOMAINS_ERRORS_5XX,
category: CARD_CATEGORIES[3].key,
example: Trend,
data: {
chart: generateTimeSeriesData(),
label: "Number of Errors",
namesMap: [
"Series 1"
]
},
example: ExampleTrend,
},
@ -615,3 +716,46 @@ function generateWebVitalData(): { value: number, chart: { timestamp: number, va
unit: "%"
};
}
function generateTimeSeriesData(): any[] {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"];
const pointsPerMonth = 3; // Number of points for each month
const data = months.flatMap((month, monthIndex) =>
Array.from({length: pointsPerMonth}, (_, pointIndex) => ({
time: month,
"Series 1": Math.floor(Math.random() * 90),
timestamp: Date.now() + (monthIndex * pointsPerMonth + pointIndex) * 86400000
}))
);
return data;
}
function generateAreaData(): any[] {
const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"];
const pointsPerMonth = 3; // Number of points for each month
const data = months.flatMap((month, monthIndex) =>
Array.from({length: pointsPerMonth}, (_, pointIndex) => ({
time: month,
"value": Math.floor(Math.random() * 90),
timestamp: Date.now() + (monthIndex * pointsPerMonth + pointIndex) * 86400000
}))
);
return data;
}
function generateRandomValue(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function generateBarChartDate(): any[] {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul'];
return months.map(month => ({
time: month,
value: generateRandomValue(1000, 5000),
}));
}

View file

@ -0,0 +1,82 @@
import React from 'react';
import {NoContent} from 'UI';
import {
AreaChart, Area,
CartesianGrid, Tooltip,
ResponsiveContainer,
XAxis, YAxis
} from 'recharts';
import {NO_METRIC_DATA} from 'App/constants/messages'
import {AvgLabel, Styles} from "Components/Dashboard/Widgets/common";
import ExCard from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/ExCard";
interface Props {
title: string;
type: string;
onCard: (card: string) => void;
onClick?: any;
data?: any,
}
// interface Props {
// data: any,
// label?: string
// }
function AreaChartCard(props: Props) {
const {data} = props;
const gradientDef = Styles.gradientDef();
return (
<ExCard
{...props}
title={
<div className={'flex items-center gap-2'}>
<div>{props.title}</div>
</div>
}
>
<NoContent
size="small"
title={NO_METRIC_DATA}
show={data?.chart.length === 0}
>
<>
{/*<div className="flex items-center justify-end mb-3">*/}
{/* <AvgLabel text="Avg" className="ml-3" count={data?.value}/>*/}
{/*</div>*/}
<ResponsiveContainer height={207} width="100%">
<AreaChart
data={data?.chart}
margin={Styles.chartMargins}
>
{gradientDef}
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#EEEEEE"/>
<XAxis {...Styles.xaxis} dataKey="time" interval={3}/>
<YAxis
{...Styles.yaxis}
allowDecimals={false}
tickFormatter={val => Styles.tickFormatter(val)}
label={{...Styles.axisLabelLeft, value: data?.label}}
/>
<Tooltip {...Styles.tooltip} />
<Area
name="Avg"
type="monotone"
dataKey="value"
stroke={Styles.strokeColor}
fillOpacity={1}
strokeWidth={2}
strokeOpacity={0.8}
fill={'url(#colorCount)'}
/>
</AreaChart>
</ResponsiveContainer>
</>
</NoContent>
</ExCard>
);
}
export default AreaChartCard;

View file

@ -6,64 +6,60 @@ import {PERFORMANCE} from "App/constants/card";
import {Bar, BarChart, CartesianGrid, Legend, Rectangle, ResponsiveContainer, Tooltip, XAxis, YAxis} from "recharts";
import {Styles} from "Components/Dashboard/Widgets/common";
const _data = [
{
name: 'Jan',
uv: 4000,
pv: 2400,
},
{
name: 'Feb',
uv: 3000,
pv: 1398,
},
{
name: 'Mar',
uv: 2000,
pv: 9800,
},
{
name: 'Apr',
uv: 2780,
pv: 3908,
},
{
name: 'May',
uv: 1890,
pv: 4800,
},
{
name: 'Jun',
uv: 2390,
pv: 3800,
},
{
name: 'Jul',
uv: 3490,
pv: 4300,
},
];
interface Props {
title: string;
type: string;
onCard: (card: string) => void;
onClick?: any;
data?: any,
}
function BarChartCard(props: any) {
function BarChartCard(props: Props) {
return (
<ExCard
{...props}
>
<ResponsiveContainer width="100%" height="100%">
{/*<ResponsiveContainer width="100%" height="100%">*/}
{/* <BarChart*/}
{/* width={400}*/}
{/* height={280}*/}
{/* data={_data}*/}
{/* margin={Styles.chartMargins}*/}
{/* >*/}
{/* /!*<CartesianGrid strokeDasharray="3 3"/>*!/*/}
{/* <CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#EEEEEE"/>*/}
{/* <XAxis {...Styles.xaxis} dataKey="name"/>*/}
{/* <YAxis {...Styles.yaxis} />*/}
{/* <Tooltip/>*/}
{/* <Legend/>*/}
{/* <Bar dataKey="pv" fill="#8884d8" activeBar={<Rectangle fill="pink" stroke="blue"/>}/>*/}
{/* /!*<Bar dataKey="uv" fill="#82ca9d" activeBar={<Rectangle fill="gold" stroke="purple"/>}/>*!/*/}
{/* </BarChart>*/}
{/*</ResponsiveContainer>*/}
<ResponsiveContainer height={240} width="100%">
<BarChart
width={400}
height={280}
data={_data}
data={props.data?.chart}
margin={Styles.chartMargins}
>
{/*<CartesianGrid strokeDasharray="3 3"/>*/}
<CartesianGrid strokeDasharray="3 3" vertical={false} stroke="#EEEEEE"/>
<XAxis {...Styles.xaxis} dataKey="name"/>
<YAxis {...Styles.yaxis} />
<Tooltip {...Styles.tooltip} />
<XAxis
{...Styles.xaxis}
dataKey="time"
// interval={21}
/>
<YAxis
{...Styles.yaxis}
tickFormatter={val => Styles.tickFormatter(val)}
label={{...Styles.axisLabelLeft, value: "Number of Errors"}}
allowDecimals={false}
/>
<Legend/>
<Bar dataKey="pv" fill="#8884d8" activeBar={<Rectangle fill="pink" stroke="blue"/>}/>
{/*<Bar dataKey="uv" fill="#82ca9d" activeBar={<Rectangle fill="gold" stroke="purple"/>}/>*/}
<Tooltip {...Styles.tooltip} />
<Bar minPointSize={1} name={<span className="float">One</span>}
dataKey="value" stackId="a" fill={Styles.colors[0]}/>
{/*<Bar name={<span className="float">3<sup>rd</sup> Party</span>} dataKey="thirdParty" stackId="a"*/}
{/* fill={Styles.colors[2]}/>*/}
</BarChart>
</ResponsiveContainer>
</ExCard>

View file

@ -0,0 +1,23 @@
import React from 'react';
import ExCard from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/ExCard";
import CallWithErrors from "Components/Dashboard/Widgets/PredefinedWidgets/CallWithErrors";
interface Props {
title: string;
type: string;
onCard: (card: string) => void;
onClick?: any;
data?: any,
}
function CallsWithErrorsExample(props: Props) {
return (
<ExCard
{...props}
>
<CallWithErrors data={props.data}/>
</ExCard>
);
}
export default CallsWithErrorsExample;

View file

@ -13,17 +13,18 @@ function ExCard({
onCard: (card: string) => void;
height?: number;
}) {
return (
<div
className={'rounded-lg overflow-hidden border border-transparent p-4 bg-white hover:border-blue hover:shadow-sm'}
style={{width: '100%', minHeight: height || 286}}
>
<div className={'font-medium text-lg'}>{title}</div>
<div className={'flex flex-col gap-2 mt-2 cursor-pointer'}
style={{minHeight: height ? height - 50 : 236,}}
onClick={() => onCard(type)}>{children}</div>
</div>
);
console.log(type)
return (
<div
className={'rounded-lg overflow-hidden border border-transparent p-4 bg-white hover:border-blue hover:shadow-sm'}
style={{width: '100%', height: height || 286}}
>
<div className={'font-medium text-lg'}>{title}</div>
<div className={'flex flex-col gap-2 mt-2 cursor-pointer'}
style={{height: height ? height - 50 : 236}}
onClick={() => onCard(type)}>{children}</div>
</div>
);
}
export default ExCard

View file

@ -1,52 +1,53 @@
import React from 'react';
import { Icon } from 'UI';
import {Avatar, Icon} from 'UI';
import ExCard from '../ExCard';
import ByComponent from './Component';
import {hashString} from "Types/session/session";
function ByUser(props: any) {
const rows = [
{
label: 'Demo User',
progress: 85,
value: '2.5K',
icon: <Icon name={'color/chrome'} size={26} />,
},
{
label: 'Admin User',
progress: 25,
value: '405',
icon: <Icon name={'color/edge'} size={26} />,
},
{
label: 'Management User',
progress: 5,
value: '302',
icon: <Icon name={'color/safari'} size={26} />,
},
{
label: 'Sales User',
progress: 3,
value: '194',
icon: <Icon name={'color/firefox'} size={26} />,
},
{
label: 'Marketing User',
progress: 1,
value: '57',
icon: <Icon name={'color/opera'} size={26} />,
},
];
const rows = [
{
label: 'Demo User',
progress: 85,
value: '2.5K',
icon: <Avatar seed={hashString("a")}/>,
},
{
label: 'Admin User',
progress: 25,
value: '405',
icon: <Avatar seed={hashString("b")}/>,
},
{
label: 'Management User',
progress: 5,
value: '302',
icon: <Avatar seed={hashString("c")}/>,
},
{
label: 'Sales User',
progress: 3,
value: '194',
icon: <Avatar seed={hashString("d")}/>,
},
{
label: 'Marketing User',
progress: 1,
value: '57',
icon: <Avatar seed={hashString("e")}/>,
},
];
const lineWidth = 200;
return (
<ByComponent
{...props}
rows={rows}
lineWidth={lineWidth}
/>
);
const lineWidth = 200;
return (
<ByComponent
{...props}
rows={rows}
lineWidth={lineWidth}
/>
);
}
export default ByUser;

View file

@ -1,96 +1,43 @@
import { Segmented } from 'antd';
import React from 'react';
import ExCard from './ExCard';
import AreaChartCard from "Components/Dashboard/components/DashboardList/NewDashModal/Examples/AreaChartCard";
import CustomMetricLineChart from "Components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricLineChart";
import {Styles} from "Components/Dashboard/Widgets/common";
function ExampleTrend(props: any) {
const rows = [50, 40, 30, 20, 10];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May'];
interface Props {
title: string;
type: string;
onCard: (card: string) => void;
onClick?: any;
data?: any,
}
const [isMulti, setIsMulti] = React.useState(false);
return (
<ExCard
{...props}
// onCard={onCard}
// type={'trend' + (isMulti ? '-multi' : '-single')}
title={
<div className={'flex items-center gap-2'}>
<div>{props.title}</div>
<div className={'font-normal'}>
<Segmented
options={[
{ label: 'Single-Series', value: 'single' },
{ label: 'Multi-Series', value: 'multi' },
]}
onChange={(v) => setIsMulti(v === 'multi')}
size='small'
/>
</div>
</div>
}
>
<div className={'relative'}>
<div className={'flex flex-col gap-4'}>
{rows.map((r) => (
<div className={'flex items-center gap-2'}>
<div className={'text-gray-dark'}>{r}K</div>
<div className="border-t border-dotted border-gray-lighter w-full"></div>
</div>
))}
</div>
<div className={'ml-4 flex items-center justify-around w-full'}>
{months.map((m) => (
<div className={'text-gray-dark'}>{m}</div>
))}
</div>
<div style={{ position: 'absolute', top: 50, left: 50 }}>
<svg
width="310"
height="65"
viewBox="0 0 310 65"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1 55.3477L12.3778 48.184C23.7556 41.0204 46.5111 26.6931 69.2667 16.6138C92.0222 6.53442 114.778 0.703032 137.533 1.58821C160.289 2.47339 183.044 10.0751 205.8 18.5821C228.556 27.0891 251.311 36.5013 274.067 34.6878C296.822 32.8743 319.578 19.8351 342.333 12.8615C365.089 5.88789 387.844 4.97992 410.6 13.8627C433.356 22.7454 456.111 41.4189 478.867 51.0086C501.622 60.5983 524.378 61.1042 547.133 60.1189C569.889 59.1335 592.644 56.6569 615.4 51.4908C638.156 46.3247 660.911 38.4691 683.667 33.0755C706.422 27.6819 729.178 24.7502 751.933 18.4788C774.689 12.2073 797.444 2.59602 820.2 4.96937C842.956 7.34271 865.711 21.7007 888.467 24.9543C911.222 28.2078 933.978 20.357 956.733 24.9861C979.489 29.6152 1002.24 46.7243 1013.62 55.2788L1025 63.8333"
stroke="#394EFF"
strokeWidth="2"
strokeLinecap="round"
function ExampleTrend(props: Props) {
return (
<ExCard
{...props}
title={
<div className={'flex items-center gap-2'}>
<div>{props.title}</div>
</div>
}
>
{/*<AreaChartCard data={props.data} label={props.data?.label}/>*/}
<CustomMetricLineChart
data={props.data}
colors={Styles.customMetricColors}
params={{
density: 21,
}}
yaxis={
{...Styles.yaxis, domain: [0, 100]}
}
label={props.data?.label}
onClick={props.onClick}
/>
</svg>
</div>
{isMulti ? (
<div style={{ position: 'absolute', top: 50, left: 50 }}>
<svg
width="310"
height="66"
viewBox="0 0 310 66"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1028 60.5095L1016.64 55.3116C1005.28 50.1137 982.569 19.7179 959.854 12.4043C937.138 5.09082 914.423 0.85959 891.708 1.50187C868.992 2.14416 846.277 7.65995 823.561 13.8326C800.846 20.0052 778.131 46.8346 755.415 45.5188C732.7 44.2029 709.984 34.7417 687.269 29.6817C664.554 24.6217 641.838 23.9629 619.123 30.4082C596.407 36.8535 573.692 50.4029 550.977 57.3611C528.261 64.3193 505.546 64.6864 482.83 63.9714C460.115 63.2565 437.4 61.4595 414.684 57.711C391.969 53.9625 369.253 48.2625 346.538 44.3489C323.823 40.4353 301.107 38.3081 278.392 33.7576C255.676 29.207 232.961 22.2331 210.246 23.9552C187.53 25.6773 164.815 36.0954 142.099 38.4562C119.384 40.8169 96.6686 35.1204 73.9532 38.4793C51.2378 41.8381 16.7156 44.2524 5.35794 50.4595L-5.99987 56.6666"
stroke="#24959A"
strokeWidth="2"
strokeLinecap="round"
/>
</svg>
</div>
) : null}
</div>
<div className={'flex gap-4 justify-center hidden'}>
<div className={'flex gap-2 items-center'}>
<div className={'w-4 h-4 rounded-full bg-main'} />
<div>Series 1</div>
</div>
<div className={'flex gap-2 items-center'}>
<div className={'w-4 h-4 rounded-full bg-tealx'} />
<div>Series 2</div>
</div>
</div>
</ExCard>
);
</ExCard>
);
}
export default ExampleTrend;

View file

@ -22,6 +22,7 @@ const SelectCard: React.FC<SelectCardProps> = (props: SelectCardProps) => {
const [libraryQuery, setLibraryQuery] = React.useState<string>('');
const handleCardSelection = (card: string) => {
metricStore.init();
const selectedCard = CARD_LIST.find((c) => c.key === card) as CardType;
const cardData: any = {

View file

@ -1,5 +1,5 @@
import React, {useState, useRef, useEffect} from 'react';
import CustomMetriLineChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetriLineChart';
import CustomMetricLineChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricLineChart';
import CustomMetricPercentage from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricPercentage';
import CustomMetricTable from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricTable';
import CustomMetricPieChart from 'App/components/Dashboard/Widgets/CustomMetricsWidgets/CustomMetricPieChart';
@ -141,7 +141,7 @@ function WidgetChart(props: Props) {
if (metricType === TIMESERIES) {
if (viewType === 'lineChart') {
return (
<CustomMetriLineChart
<CustomMetricLineChart
data={data}
colors={colors}
params={params}
@ -236,7 +236,7 @@ function WidgetChart(props: Props) {
if (metricType === RETENTION) {
if (viewType === 'trend') {
return (
<CustomMetriLineChart
<CustomMetricLineChart
data={data}
colors={colors}
params={params}

View file

@ -52,7 +52,7 @@ function WidgetPredefinedChart(props: Props) {
case FilterKey.DOMAINS_ERRORS_5XX:
return <CallsErrors5xx data={data} metric={metric} />
case FilterKey.CALLS_ERRORS:
return <CallWithErrors isTemplate={isTemplate} data={data} metric={metric} />
return <CallWithErrors isTemplate={isTemplate} data={data} />
// PERFORMANCE
case FilterKey.IMPACTED_SESSIONS_BY_SLOW_PAGES:

View file

@ -1,6 +1,7 @@
import {Icon} from "UI";
import {Avatar, Icon} from "UI";
import React from "react";
import * as Flags from "country-flag-icons/react/3x2";
import {hashString} from "Types/session/session";
interface IconProvider {
getIcon(name: string): React.ReactNode;
@ -108,7 +109,7 @@ class OsIconProvider implements IconProvider {
class UserIconProvider implements IconProvider {
getIcon(name: string): React.ReactNode {
return <Icon name="user" size={24}/>
return <Avatar seed={hashString(name)}/>
}
}

View file

@ -128,7 +128,7 @@ export default class Filter {
addFunnelDefaultFilters() {
this.filters = []
this.addFilter({...filtersMap[FilterKey.CLICK], value: [''], operator: 'onAny'})
this.addFilter({...filtersMap[FilterKey.LOCATION], value: [''], operator: 'isAny'})
this.addFilter({...filtersMap[FilterKey.CLICK], value: [''], operator: 'onAny'})
}
}

View file

@ -41,7 +41,7 @@ export function sortEvents(a: Record<string, any>, b: Record<string, any>) {
return aTs - bTs;
}
function hashString(s: string): number {
export function hashString(s: string): number {
let mul = 1;
let hash = 0;
for (let i = 0; i < s.length; i++) {