Generate realistic sample data
This commit is contained in:
13
src/App.tsx
13
src/App.tsx
@@ -8,7 +8,7 @@ import Legend from "./components/Legend";
|
||||
import QRCode from "./components/QRCode";
|
||||
import { WaffleChart } from "./components/WaffleChart";
|
||||
|
||||
import { fetchGoogleSheet } from "./lib/parser";
|
||||
import { getSampleData } from "./lib/data";
|
||||
import "./styles/App.scss";
|
||||
|
||||
function App() {
|
||||
@@ -18,9 +18,9 @@ function App() {
|
||||
});
|
||||
const responseQuery = useQuery({
|
||||
queryKey: ["responses"],
|
||||
queryFn: fetchGoogleSheet,
|
||||
// queryFn: getSampleData,
|
||||
refetchInterval: 5 * 1000, // Refresh every 5 seconds
|
||||
// queryFn: fetchGoogleSheet,
|
||||
queryFn: getSampleData,
|
||||
refetchInterval: 1 * 1000, // Refresh every 5 seconds
|
||||
});
|
||||
|
||||
if (metadataQuery.isPending || responseQuery.isPending)
|
||||
@@ -29,19 +29,16 @@ function App() {
|
||||
return <div>Error loading data</div>;
|
||||
|
||||
// Sort responses by timestamp to easily find the latest response
|
||||
const responses = responseQuery.data.sort(
|
||||
const responses = [...responseQuery.data].sort(
|
||||
(a, b) => a.timestamp - b.timestamp
|
||||
);
|
||||
const categoryMetadata = metadataQuery.data;
|
||||
|
||||
if (!responses.length) return null;
|
||||
|
||||
// Group data by question (outside the component)
|
||||
const questionGroups = Array.from(
|
||||
d3.group(responses, (d) => d.question).entries()
|
||||
);
|
||||
|
||||
// Create scales
|
||||
return (
|
||||
<div className="layout">
|
||||
<div className="chart-container">
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
import { fetchCategoryMetadata } from "./metadata";
|
||||
import { ResponseData } from "./parser";
|
||||
|
||||
export function getSampleData(): Promise<ResponseData[]> {
|
||||
const questions = [
|
||||
"Service Quality",
|
||||
"Value for Money",
|
||||
"Ease of Use",
|
||||
"Recommendation",
|
||||
"Overall Satisfaction",
|
||||
"Customer Support",
|
||||
"Product Features",
|
||||
];
|
||||
function randInt(min: number, max: number): number {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
export async function getSampleData(): Promise<ResponseData[]> {
|
||||
// Use the actual categories
|
||||
const questions = (await fetchCategoryMetadata()).map(
|
||||
(metadata) => metadata.category
|
||||
);
|
||||
const sampleData: ResponseData[] = [];
|
||||
let id = 1;
|
||||
questions.forEach((question) => {
|
||||
const numResponses = Math.floor(Math.random() * 50) + 30;
|
||||
for (let i = 0; i < numResponses; i++) {
|
||||
const response = Math.floor(Math.random() * 5);
|
||||
const numResponses = randInt(10, 20);
|
||||
for (let i = 0; i < numResponses; i++) {
|
||||
questions.forEach((question) => {
|
||||
const response = randInt(0, 4); // Likert scale response (0-4)
|
||||
sampleData.push({
|
||||
timestamp: id++,
|
||||
position: "",
|
||||
timestamp: i, // Group all responses by the same timestamp to mimic Google Forms behavior
|
||||
question: question,
|
||||
response: response,
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
// Simulate a delay to mimic fetching actual data
|
||||
return new Promise<ResponseData[]>((resolve) => {
|
||||
setTimeout(() => resolve(sampleData), 500);
|
||||
|
||||
@@ -22,7 +22,6 @@ const url = `https://docs.google.com/spreadsheets/d/${sheet_id}/gviz/tq?tqx=out:
|
||||
|
||||
export interface ResponseData {
|
||||
timestamp: number;
|
||||
position: string;
|
||||
question: string;
|
||||
response: number;
|
||||
}
|
||||
@@ -40,7 +39,6 @@ export function parseCSV(csv: string): ResponseData[] {
|
||||
});
|
||||
return Object.entries(responses).flatMap(([category, response]) => ({
|
||||
timestamp: new Date(row["Timestamp"]).getTime(),
|
||||
position: row["Position"],
|
||||
question: category,
|
||||
response: response,
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user