pdehaan / repo-health-report

Issue tracker stats for repos.
https://repo-health-report.now.sh/
Mozilla Public License 2.0
3 stars 0 forks source link

WIP: calendar view #7

Open pdehaan opened 4 years ago

pdehaan commented 4 years ago

This takes a JSON file as input (to avoid using GitHub API and does its best to loop over the past X days and figure out an open/closed rate.

const data = require("./blurts-server.json");

const DAY_IN_MS = 24 * 60 * 60 * 1000;

const stats = getRecentStats(data.issues);
console.log(JSON.stringify(stats, null, 2));

function getRecentStats(issues = [], durationDays = 30) {
  const now = new Date();
  const since = new Date(
    Date.UTC(
      now.getFullYear(),
      now.getMonth(),
      now.getDate() - Math.abs(durationDays)
    )
  );
  return {
    daily: $dailyIssueStats(issues, since, now),
    recentOpenedIssues: $recentOpenedIssues(issues, since),
    recentClosedIssues: $recentClosedIssues(issues, since),
  };
}

function $recentClosedIssues(issues, since) {
  return issues
    .filter(
      (issue) =>
        Date.parse(issue.closed_at) >= since && issue.state === "closed"
    )
    .map((issue) => issue.number);
}

function $recentOpenedIssues(issues, since) {
  return issues
    .filter(
      (issue) => Date.parse(issue.created_at) >= since && issue.state === "open"
    )
    .map((issue) => issue.number);
}

function $dailyIssueStats(issues, since, now = new Date()) {
  const daily = [];
  for (
    let start_time = since.getTime();
    start_time <= now.getTime();
    start_time += DAY_IN_MS
  ) {
    const end_time = start_time + DAY_IN_MS;
    const openIssues = data.issues
      .filter((issue) => {
        const created_at = Date.parse(issue.created_at);
        const closed_at = issue.closed_at ? Date.parse(issue.closed_at) : now;
        return created_at <= end_time && closed_at >= start_time;
      })
      .map((issue) => issue.number).length;

    const newIssues = data.issues
      .filter((issue) => {
        const created_at = Date.parse(issue.created_at);
        return created_at >= start_time && created_at < end_time;
      })
      .map((issue) => issue.number).length;

    const closedIssues = data.issues
      .filter((issue) => {
        const closed_at = Date.parse(issue.closed_at);
        return closed_at >= start_time && closed_at < end_time;
      })
      .map((issue) => issue.number).length;

    daily.push({
      startTime: new Date(start_time),
      endTime: new Date(end_time),
      openIssues,
      newIssues,
      closedIssues,
    });
  }
  return daily;
}

OUTPUT

{
  "daily": [
    {
      "startTime": "2020-03-04T00:00:00.000Z",
      "endTime": "2020-03-05T00:00:00.000Z",
      "openIssues": 190,
      "newIssues": 0,
      "closedIssues": 0
    },
    ...
    {
      "startTime": "2020-04-03T00:00:00.000Z",
      "endTime": "2020-04-04T00:00:00.000Z",
      "openIssues": 210,
      "newIssues": 0,
      "closedIssues": 0
    }
  ],
  "recentOpenedIssues": [
    1630,
    1629,
    1628,
    ...
  ],
  "recentClosedIssues": [
    ...
    1569,
    1498,
    1469
  ]
}

Possibly good enough to get us to somewhere that we can chart using chart.js or whatever library works. I used chartjs on covid-canada and it was easy to hot-link to a hosting thing, but probably suboptimal approach.

pdehaan commented 4 years ago

Possibly best to start with a chart that we want to try and generate and work backwards to figure out how to generate the data in the best format, and know the best data.

I'm thinking either a 30 day line chart of open bug count. And possibly a bar chart of daily open/closed counts.