Added an Alert Level Change Quad Plot Widget
This commit is contained in:
@@ -0,0 +1,84 @@
|
|||||||
|
import VdapApi from '../../hooks/useVdapApi.js';
|
||||||
|
import {Flex, Spinner, Text, Box, Center} from "@chakra-ui/react"; // Adjust path as needed
|
||||||
|
|
||||||
|
|
||||||
|
export default function LlmAlChangesQuadPlot(props) {
|
||||||
|
console.log("3. Quad Plot loaded");
|
||||||
|
let tp_percent = 0;
|
||||||
|
let tn_percent = 0;
|
||||||
|
let fp_percent = 0;
|
||||||
|
let fn_percent = 0;
|
||||||
|
|
||||||
|
// Clean, single-line data fetching
|
||||||
|
const { data: apiData, isLoading, error } = VdapApi('/api/v2/llm_quadrant_plot');
|
||||||
|
|
||||||
|
if (isLoading) return (
|
||||||
|
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center">
|
||||||
|
<Spinner size="xl" color="blue.400" thickness="4px" />
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) return (
|
||||||
|
<Flex w="100%" h="100%" bg="gray.800" borderRadius="md" align="center" justify="center" p={4}>
|
||||||
|
<Text color="red.400">{error}</Text>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (apiData.length === 0) return (
|
||||||
|
<Flex height="100%" width="100%" align="center" justify="center" bg="gray.800" borderRadius="md">
|
||||||
|
<Text color="gray.400">No alert level quad plot data available.</Text>
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
|
||||||
|
if (apiData) {
|
||||||
|
console.log(apiData);
|
||||||
|
tp_percent = ((apiData[0]['tp_count']/apiData[0]['tot_count'])*100).toFixed(2);
|
||||||
|
tn_percent = ((apiData[0]['tn_count']/apiData[0]['tot_count'])*100).toFixed(2);
|
||||||
|
fp_percent = ((apiData[0]['fp_count']/apiData[0]['tot_count'])*100).toFixed(2);
|
||||||
|
fn_percent = ((apiData[0]['fn_count']/apiData[0]['tot_count'])*100).toFixed(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Flex direction="column" w="100%" h="100%" borderRadius="lg">
|
||||||
|
<Flex direction="row" w="100%" bg="gray.800" borderTopRadius="lg" justifyItems="center" alignItems="start" p={2} pb={0} pl={4} justifyContent="end">
|
||||||
|
{/*<Text fontWeight="bold" fontSize="lg" color="white">Alert Level Changes Quad Plot</Text>*/}
|
||||||
|
<Text bg="cyan.200/5" borderRadius="sm" padding="1" fontWeight="normal" fontSize="sm" color="white">All time</Text>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction="column" w="100%" h="100%" bg="gray.800" gap="2" padding="2" borderBottomRadius="lg">
|
||||||
|
<Flex direction="row" w="100%" h="100%" gap="2">
|
||||||
|
<Center bg={`blue.200/${tp_percent % 50}`} w="100%" h="100%" borderRadius="lg" color="white" fontSize="sm" fontWeight="bold">
|
||||||
|
<Flex direction="column" w="100%" h="100%" justifyContent="center" alignItems="center">
|
||||||
|
<Text>True Positive</Text>
|
||||||
|
<Text fontSize="lg"> {tp_percent}% </Text>
|
||||||
|
<Text color="gray.400" fontSize="xs" fontWeight="normal"> {apiData[0]['tp_count']}/{apiData[0]['tot_count']} </Text>
|
||||||
|
</Flex>
|
||||||
|
</Center>
|
||||||
|
<Center bg={`blue.200/${tn_percent % 50}`} w="100%" h="100%" borderRadius="lg" color="white" fontSize="sm" fontWeight="bold">
|
||||||
|
<Flex direction="column" w="100%" h="100%" justifyContent="center" alignItems="center">
|
||||||
|
<Text>True Negative</Text>
|
||||||
|
<Text fontSize="lg"> {tn_percent}% </Text>
|
||||||
|
<Text color="gray.400" fontSize="xs" fontWeight="normal"> {apiData[0]['tn_count']}/{apiData[0]['tot_count']} </Text>
|
||||||
|
</Flex>
|
||||||
|
</Center>
|
||||||
|
</Flex>
|
||||||
|
<Flex direction="row" w="100%" h="100%" gap="2">
|
||||||
|
<Center bg={`blue.200/${fp_percent % 50}`} w="100%" h="100%" borderRadius="lg" color="white" fontSize="sm" fontWeight="bold">
|
||||||
|
<Flex direction="column" w="100%" h="100%" justifyContent="center" alignItems="center">
|
||||||
|
<Text>False Positive</Text>
|
||||||
|
<Text fontSize="lg"> {fp_percent}% </Text>
|
||||||
|
<Text color="gray.400" fontSize="xs" fontWeight="normal"> {apiData[0]['fp_count']}/{apiData[0]['tot_count']} </Text>
|
||||||
|
</Flex>
|
||||||
|
</Center>
|
||||||
|
<Center bg={`blue.200/${fn_percent % 50}`} w="100%" h="100%" borderRadius="lg" color="white" fontSize="sm" fontWeight="bold">
|
||||||
|
<Flex direction="column" w="100%" h="100%" justifyContent="center" alignItems="center">
|
||||||
|
<Text>False Negative</Text>
|
||||||
|
<Text fontSize="lg"> {fn_percent}% </Text>
|
||||||
|
<Text color="gray.400" fontSize="xs" fontWeight="normal"> {apiData[0]['fn_count']}/{apiData[0]['tot_count']} </Text>
|
||||||
|
</Flex>
|
||||||
|
</Center>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Box } from '@chakra-ui/react';
|
||||||
|
import { http, HttpResponse } from 'msw'; // Import MSW
|
||||||
|
import LlmAlChangesQuadPlot from './LlmAlChangesQuadPlot';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
title: 'Dashboard Widgets/LLM AL Changes Quad Plot',
|
||||||
|
component: LlmAlChangesQuadPlot,
|
||||||
|
decorators: [
|
||||||
|
(Story) => (
|
||||||
|
<Box
|
||||||
|
w="100%" maxW="1800px" h="400px"
|
||||||
|
border="2px dashed" borderColor="gray.600" p={2}
|
||||||
|
resize="both" overflow="auto"
|
||||||
|
>
|
||||||
|
<Story />
|
||||||
|
</Box>
|
||||||
|
),
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockData = [
|
||||||
|
{ tp: 50 },
|
||||||
|
{ tn: 250 },
|
||||||
|
{ fp: 10 },
|
||||||
|
{ fn: 5 },
|
||||||
|
{ tot_count: 315}
|
||||||
|
];
|
||||||
|
|
||||||
|
// Scenario LIVE: call our API for real
|
||||||
|
export const LivePopulated = {};
|
||||||
|
|
||||||
|
// Scenario 1: Successful API Call
|
||||||
|
export const Populated = {
|
||||||
|
parameters: {
|
||||||
|
msw: {
|
||||||
|
handlers: [
|
||||||
|
// Intercept the exact URL your component is trying to fetch
|
||||||
|
http.get('*/api/v2/llm_quadrant_plot', () => {
|
||||||
|
// Return a 200 OK with the mock JSON
|
||||||
|
return HttpResponse.json(mockData);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Scenario 2: The 500 Server Crash
|
||||||
|
export const ServerCrash = {
|
||||||
|
parameters: {
|
||||||
|
msw: {
|
||||||
|
handlers: [
|
||||||
|
http.get('*/api/v2/llm_quad_plot', () => {
|
||||||
|
// Return a 500 Error
|
||||||
|
return new HttpResponse(null, { status: 500 });
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Scenario 3: Empty State (API works, but no data returned)
|
||||||
|
export const EmptyData = {
|
||||||
|
parameters: {
|
||||||
|
msw: {
|
||||||
|
handlers: [
|
||||||
|
http.get('*/api/v2/llm_quad_plot', () => {
|
||||||
|
return HttpResponse.json([]);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -85,4 +85,15 @@ export const WIDGET_REGISTRY = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"llm_al_changes_quad_plot": {
|
||||||
|
name: "Alert Level Changes Quad Plot",
|
||||||
|
category: "Computer Science",
|
||||||
|
description: "Percentage of True-Positive, True-Negative, False-Positive, and False-Negative changes in all " +
|
||||||
|
"alert levels.",
|
||||||
|
component: lazy(() => import('../components/Widgets/LlmAlChangesQuadPlot.jsx')),
|
||||||
|
allowedSizes: {
|
||||||
|
small: { w: 3, h: 12 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user