muety/wakapi

GitHub-like activity chart

muety opened this issue · 6 comments

muety commented

Add an activity chart similar to the one on every GitHub user's profile page. It should show a cell for every day in a year whose background color (blue?) gets increasingly dark the more activity a user had on that specific day in relation to all other days.

muety commented

Would go well with a new endpoint that returns coding time for each day within a range.

muety commented

I'd like to render the chart on the back-end side.

  • Option 1: Use github-contributions-canvas as a small, stand-alone microservice. Downside: Wakapi can't just be shipped as a single binary anymore. ❌
  • Option 2: Translate HTML 5 canvas code from github-contributions-canvas into Go using tfriedel6/canvas. Downside: Requires to add heavy-weight library. ❌
  • Option 3: Write some Go code to create raw SVG code by hand that resembles the contribution chart. Advantage: no external libraries needed; chart is in vector format, not a rendered image. ✅

Here's a small example I drew up in Inkscape. Looks fairly straightforward.

1

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   width="42.013622mm"
   height="21.209536mm"
   viewBox="0 0 42.013622 21.209535"
   version="1.1"
   id="svg5"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs2" />
  <g
     id="layer1"
     transform="translate(-7.754659,-11.136787)">
    <rect
       style="fill:#40c463;fill-opacity:1;stroke:#40c463;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846"
       width="9.5111551"
       height="9.6786003"
       x="39.860123"
       y="22.270721" />
    <rect
       style="fill:#40c463;fill-opacity:1;stroke:#40c463;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-1"
       width="9.5111551"
       height="9.6786003"
       x="8.1516609"
       y="11.533787" />
    <rect
       style="fill:#9be9a8;fill-opacity:1;stroke:#9be9a8;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-2"
       width="9.5111551"
       height="9.6786003"
       x="8.151659"
       y="22.270721" />
    <rect
       style="fill:#216e39;fill-opacity:1;stroke:#216e39;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-7"
       width="9.5111551"
       height="9.6786003"
       x="18.721149"
       y="11.533787" />
    <rect
       style="fill:#9be9a8;fill-opacity:1;stroke:#9be9a8;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-72"
       width="9.5111551"
       height="9.6786003"
       x="29.290638"
       y="11.533787" />
    <rect
       style="fill:#ebedf0;fill-opacity:1;stroke:#ebedf0;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-72-7"
       width="9.5111551"
       height="9.6786003"
       x="39.860126"
       y="11.533787" />
    <rect
       style="fill:#ebedf0;fill-opacity:1;stroke:#ebedf0;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-72-7-2"
       width="9.5111551"
       height="9.6786003"
       x="18.721149"
       y="22.270721" />
    <rect
       style="fill:#ebedf0;fill-opacity:1;stroke:#ebedf0;stroke-width:0.794;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
       id="rect846-72-7-6"
       width="9.5111551"
       height="9.6786003"
       x="29.290638"
       y="22.270721" />
  </g>
</svg>
muety commented

This is what one of the columns from GitHub's actual, official contribution chart looks like:

<g transform="translate(224, 0)">
      <rect width="10" height="10" x="-2" y="0" class="ContributionCalendar-day" rx="2" ry="2" data-count="33" data-date="2021-11-28" data-level="4"></rect>
      <rect width="10" height="10" x="-2" y="13" class="ContributionCalendar-day" rx="2" ry="2" data-count="6" data-date="2021-11-29" data-level="1"></rect>
      <rect width="10" height="10" x="-2" y="26" class="ContributionCalendar-day" rx="2" ry="2" data-count="5" data-date="2021-11-30" data-level="1"></rect>
      <rect width="10" height="10" x="-2" y="39" class="ContributionCalendar-day" rx="2" ry="2" data-count="0" data-date="2021-12-01" data-level="0"></rect>
      <rect width="10" height="10" x="-2" y="52" class="ContributionCalendar-day" rx="2" ry="2" data-count="2" data-date="2021-12-02" data-level="1"></rect>
      <rect width="10" height="10" x="-2" y="65" class="ContributionCalendar-day" rx="2" ry="2" data-count="4" data-date="2021-12-03" data-level="1"></rect>
      <rect width="10" height="10" x="-2" y="78" class="ContributionCalendar-day" rx="2" ry="2" data-count="4" data-date="2021-12-04" data-level="1"></rect>
</g>
muety commented

Themes / colors are defined here: https://github.com/sallar/github-contributions-canvas/blob/master/src/themes.ts.

Colors are chosen according to an intensity between 0 and 4. Intensity seems to be calculated by simply normalizing the contributions count range to [0, 4], i.e.:

intensity(x) = round(4 / (max(counts) - min(counts)) * (x - max(counts)) + 4)

WakaTime uses this intensity range for activity charts when displaying time instead of commits:

Screenshot 2023-09-19 at 10 24 46 PM
  • Under 1 hr #EBEDF0
  • 1-3 hrs #B4C7D9
  • 4-8 hrs #8BAAC5
  • 9-10 hrs #527DA4
  • 11-12 hrs #36526C
  • 13+ hrs #000000