]> git.otsuka.systems Git - cotsuka.github.io/commitdiff
fix and simplify rating distribution chart
authorCameron Otsuka <cameron@otsuka.haus>
Mon, 16 Mar 2026 23:46:13 +0000 (16:46 -0700)
committerCameron Otsuka <cameron@otsuka.haus>
Mon, 16 Mar 2026 23:46:13 +0000 (16:46 -0700)
src/components/ratingdistribution.astro [new file with mode: 0644]
src/components/ratingdistribution/component.astro [deleted file]
src/pages/reviews/index.astro

diff --git a/src/components/ratingdistribution.astro b/src/components/ratingdistribution.astro
new file mode 100644 (file)
index 0000000..8ce1ecb
--- /dev/null
@@ -0,0 +1,66 @@
+---
+import { getCollection } from 'astro:content';
+
+const reviews = await getCollection('reviews');
+const ratings = [1, 2, 3, 4, 5] as const;
+const counts = [0, 0, 0, 0, 0];
+
+for (const { data } of reviews) {
+  counts[data.rating - 1]++;
+}
+
+const maxCount = Math.max(...counts, 1);
+
+const chartData = ratings.map((rating, index) => ({
+  name: rating,
+  count: counts[index],
+  percent: (counts[index] / maxCount) * 100,
+}));
+---
+
+<ul class="rating-distribution">
+  {
+    chartData.map((entry) => (
+      <li class="rating-column">
+        <div class="rating-bar">
+          <span class="rating-bar-fill" style={`height: ${entry.percent}%`} />
+        </div>
+        <span class="rating-label">{entry.name}</span>
+      </li>
+    ))
+  }
+</ul>
+
+<style>
+  .rating-distribution {
+    list-style: none;
+    padding-inline-start: 0;
+    display: grid;
+    grid-template-columns: repeat(5, minmax(0, 1fr));
+    gap: clamp(1rem, 2vw, 2rem);
+    align-items: end;
+  }
+
+  .rating-column {
+    display: grid;
+    grid-template-rows: 1fr auto;
+  }
+
+  .rating-bar {
+    display: flex;
+    align-items: end;
+    width: 100%;
+    height: clamp(4rem, 24vw, 8rem);
+    border: 1px solid var(--color-text);
+    overflow: hidden;
+  }
+
+  .rating-bar-fill {
+    width: 100%;
+    background-color: var(--color-text);
+  }
+
+  .rating-label {
+    justify-self: center;
+  }
+</style>
diff --git a/src/components/ratingdistribution/component.astro b/src/components/ratingdistribution/component.astro
deleted file mode 100644 (file)
index 4379d06..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
----
-import { getCollection } from 'astro:content';
-
-const reviews = await getCollection('reviews');
-
-const ratingCounts: Record<number, number> = {
-  1: 0,
-  2: 0,
-  3: 0,
-  4: 0,
-  5: 0,
-};
-
-reviews.forEach((review) => {
-  ratingCounts[review.data.rating]++;
-});
-
-const maxCount = Math.max(...Object.values(ratingCounts), 1);
-
-const chartData = Object.entries(ratingCounts).map(([rating, count]) => ({
-  name: rating,
-  count,
-}));
----
-
-<ul class="rating-distribution" aria-label="Rating distribution">
-  {
-    chartData.map((entry) => (
-      <li class="rating-column">
-        <span class="rating-count">{entry.count}</span>
-        <meter
-          class="rating-meter"
-          min="0"
-          max={maxCount}
-          value={entry.count}
-          aria-label={`${entry.name} stars: ${entry.count} reviews`}
-        >
-          {entry.count} of {maxCount}
-        </meter>
-        <span class="rating-label">{entry.name}</span>
-      </li>
-    ))
-  }
-</ul>
-
-<style>
-  .rating-distribution {
-    list-style: none;
-    padding: 0;
-    display: grid;
-    grid-template-columns: repeat(5, minmax(0, 1fr));
-    color: var(--color-text);
-    font-family: var(--font-sans);
-  }
-
-  .rating-column {
-    display: grid;
-    grid-template-rows: auto auto auto;
-    gap: 0.5rem;
-    justify-items: center;
-  }
-
-  .rating-count {
-    font-style: italic;
-  }
-
-  .rating-label {
-    font-weight: 600;
-  }
-
-  .rating-meter {
-    display: block;
-    width: 4rem;
-    height: 8rem;
-    margin: 0;
-    padding: 0;
-    writing-mode: vertical-lr;
-    -moz-orient: vertical;
-    appearance: none;
-    border: 1px solid var(--color-text);
-    background: color-mix(in srgb, var(--color-text) 20%, var(--color-bg));
-    overflow: hidden;
-  }
-
-  .rating-meter::-webkit-meter-bar {
-    background: color-mix(in srgb, var(--color-text) 20%, var(--color-bg));
-  }
-
-  .rating-meter::-webkit-meter-optimum-value,
-  .rating-meter::-webkit-meter-suboptimum-value,
-  .rating-meter::-webkit-meter-even-less-good-value {
-    background: var(--color-text);
-  }
-
-  .rating-meter::-moz-meter-bar {
-    background: var(--color-text);
-  }
-</style>
index ca19c526e23101747924c3a954e4984016cdcde4..875a7dca2f6ccbb68fd04f2a43f773cb1e8ffa82 100644 (file)
@@ -1,7 +1,7 @@
 ---
 import { getCollection } from 'astro:content';
 import Base from '@layouts/base.astro';
-import RatingDistribution from '@components/ratingdistribution/component.astro';
+import RatingDistribution from '@components/ratingdistribution.astro';
 import Rating from '@components/ui/rating.astro';
 import sortByDate from '@utils/sortByDate';
 import generateContentUrl from '@utils/generateContentUrl';