visuddhinanda пре 3 година
родитељ
комит
13e957075b

+ 52 - 0
dashboard/src/components/exp/ExpPie.tsx

@@ -0,0 +1,52 @@
+import { Pie } from "@ant-design/plots";
+
+export interface IPieData {
+  type: string;
+  value: number;
+}
+interface IWidget {
+  data?: IPieData[];
+}
+const Widget = ({ data = [] }: IWidget) => {
+  console.log("pie data", data);
+  const config = {
+    appendPadding: 10,
+    data,
+    angleField: "value",
+    colorField: "type",
+    radius: 1,
+    innerRadius: 0.6,
+    label: {
+      type: "inner",
+      offset: "-50%",
+      content: "{value}",
+      style: {
+        textAlign: "center",
+        fontSize: 14,
+        display: "none",
+      },
+    },
+    interactions: [
+      {
+        type: "element-selected",
+      },
+      {
+        type: "element-active",
+      },
+    ],
+    statistic: {
+      content: {
+        style: {
+          whiteSpace: "pre-wrap",
+          overflow: "hidden",
+          textOverflow: "ellipsis",
+          display: "none",
+        },
+        content: "a",
+      },
+    },
+  };
+  return <Pie {...config} style={{ height: 120 }} />;
+};
+
+export default Widget;

+ 168 - 0
dashboard/src/components/exp/Heatmap.tsx

@@ -0,0 +1,168 @@
+import { useEffect, useState } from "react";
+import { useIntl } from "react-intl";
+import { message, Select, Typography } from "antd";
+
+import { get } from "../../request";
+import { IUserOperationDailyResponse } from "../api/Exp";
+
+interface IOptions {
+  value: string;
+  label: string;
+}
+interface IDailyData {
+  date: string;
+  commits: number;
+  year: number;
+  month: number;
+  day: number;
+  week: number;
+}
+
+interface IWidget {
+  studioName?: string;
+}
+const Widget = ({ studioName }: IWidget) => {
+  const [dailyData, setDailyData] = useState<IDailyData[]>([]);
+  const [year, setYear] = useState<IOptions[]>([]);
+
+  const thisYear = new Date().getFullYear();
+  const [currYear, setCurrYear] = useState<string>(thisYear.toString());
+  const intl = useIntl();
+
+  useEffect(() => {
+    get<IUserOperationDailyResponse>(
+      `/v2/user-operation-daily?view=user-year&studio_name=${studioName}&year=2021`
+    ).then((json) => {
+      if (json.ok) {
+        //找到起止年份
+        if (json.data.rows.length > 0) {
+          const yearStart = new Date(json.data.rows[0].date_int).getFullYear();
+          const yearEnd = new Date(
+            json.data.rows[json.data.rows.length - 1].date_int
+          ).getFullYear();
+          let yearOption: IOptions[] = [];
+          for (let index = yearStart; index <= yearEnd; index++) {
+            yearOption.push({
+              value: index.toString(),
+              label: index.toString(),
+            });
+          }
+          setYear(yearOption);
+        }
+
+        const data = json.data.rows.map((item) => {
+          const date = new Date(item.date_int);
+          const oneJan = new Date(date.getFullYear(), 0, 1);
+          const week = Math.ceil(
+            ((date.getTime() - oneJan.getTime()) / 86400000 +
+              oneJan.getDay() +
+              1) /
+              7
+          );
+
+          return {
+            date:
+              date.getFullYear() +
+              "-" +
+              (date.getMonth() + 1) +
+              "-" +
+              date.getDate(),
+            year: date.getFullYear(),
+            month: date.getMonth() + 1,
+            day: date.getDay(),
+            week: week,
+            commits: item.duration / 1000 / 60,
+          };
+        });
+        console.log("data", data);
+        setDailyData(data);
+      } else {
+        message.error(json.message);
+      }
+    });
+  }, [studioName]);
+
+  const yAxisLabel = new Array(7).fill(1).map((item, id) => {
+    return (
+      <div key={id} style={{ display: "inline-block", width: "5em" }}>
+        <Typography.Text>
+          {intl.formatMessage({ id: `labels.week.${id}` })}
+        </Typography.Text>
+      </div>
+    );
+  });
+  const dayColor = ["#9be9a8", "#40c463", "#30a14e", "#216e39"];
+  const weeks = new Array(54).fill(1);
+  const heatmap = weeks.map((item, week) => {
+    const days = new Array(7).fill(1);
+    return (
+      <div key={week}>
+        {days.map((itemDay, day) => {
+          const time = dailyData.find(
+            (value) =>
+              value.year === parseInt(currYear) &&
+              value.week === week &&
+              value.day === day
+          )?.commits;
+          const color = time
+            ? time > 120
+              ? dayColor[0]
+              : time > 60
+              ? dayColor[1]
+              : time > 30
+              ? dayColor[2]
+              : time > 5
+              ? dayColor[3]
+              : "rgba(0,0,0,0)"
+            : "rgba(0,0,0,0)";
+          return (
+            <div
+              key={day}
+              style={{
+                display: "inline-block",
+                width: 12,
+                height: 12,
+                backgroundColor: `rgba(128,128,128,0.2)`,
+                margin: 0,
+                borderRadius: 2,
+                outline: "1px solid gray",
+              }}
+            >
+              <div
+                style={{
+                  width: 12,
+                  height: 12,
+                  backgroundColor: color,
+                }}
+              ></div>
+            </div>
+          );
+        })}
+      </div>
+    );
+  });
+
+  return (
+    <div style={{ width: 1000 }}>
+      <div style={{ textAlign: "right" }} key="toolbar">
+        <Select
+          defaultValue={thisYear.toString()}
+          style={{ width: 120 }}
+          onChange={(value: string) => {
+            console.log(`selected ${value}`);
+            setCurrYear(value);
+          }}
+          options={year}
+        />
+      </div>
+      <div style={{ display: "flex" }} key="map">
+        <div style={{ width: "5em" }} key="label">
+          {yAxisLabel}
+        </div>
+        {heatmap}
+      </div>
+    </div>
+  );
+};
+
+export default Widget;

+ 11 - 0
dashboard/src/locales/zh-Hans/label.ts

@@ -0,0 +1,11 @@
+const items = {
+  "labels.week.0": "星期日",
+  "labels.week.1": "星期一",
+  "labels.week.2": "星期二",
+  "labels.week.3": "星期三",
+  "labels.week.4": "星期四",
+  "labels.week.5": "星期五",
+  "labels.week.6": "星期六",
+};
+
+export default items;