Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a "Calendar view" #732

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open

Conversation

justin-jiajia
Copy link
Contributor

image

Implement #338 .

@justin-jiajia justin-jiajia marked this pull request as ready for review January 10, 2025 01:58
@muety muety self-requested a review January 10, 2025 16:36
Copy link
Owner

@muety muety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for this, great contribution!

Regarding the overall implementation, I'd probably suggest a slightly different approach. You current implementation comes with a few drawbacks:

  • "Duplicate" logic to aggregate durations
  • Inefficient, because operating on raw heartbeats for each request instead of leveraging pre-aggregated summaries
  • Not respected custom mapping or project aliases

To overcome these (and thus also improve performance), I'd probably utilize the already existing summary computation logic. I'd (very roughly speaking) do approximately this:

  • Use SplitRangeByDays (search code for examples), to break down the requested interval into single days
  • Use SummaryService.Aliased() (just like in many other places throughout Wakapi) to fetch fetch summaries for each day
  • Construct the DailyProjectStat view model from an array of summaries, i.e. introduce methods func NewDailyProjectStats(summaries []*models.Summaries) []*DailyProjectStat { ... } or something, e.g. similar to here.

views/summary.tpl.html Outdated Show resolved Hide resolved
models/summary.go Outdated Show resolved Hide resolved
services/summary.go Outdated Show resolved Hide resolved
services/summary.go Outdated Show resolved Hide resolved
@justin-jiajia justin-jiajia requested a review from muety January 14, 2025 10:00
Copy link
Owner

@muety muety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for implementing my change requests!

Do you think we should limit the calendar view component to a maximum number of days? Because when choosing a very large – if not All Time – interval, the chart becomes unreadable and super inefficient (blocked my browser tab for almost 30 seconds). Would love to hear your thoughts on that.

image

services/summary.go Outdated Show resolved Hide resolved
services/summary.go Outdated Show resolved Hide resolved
@justin-jiajia justin-jiajia requested a review from muety January 16, 2025 13:23
@justin-jiajia
Copy link
Contributor Author

Thank you for pointing out my problems in architecture. I've changed my codes to let them:

  • fetch 1 summary for each single day using FetchSummaryForDailyProjectStats(params *models.SummaryParams) ([]*models.Summary, error)
  • construct a DailyProjectViewModel from the summaries fetched below using NewDailyProjectStats(summaries []*models.Summary) []*DailyProjectViewModel

So: the "presentation layer", including the router & handler, present the data to the user directly without really calculating them, while the "service layer" calculates them and store them to the database.

I'm just a student and it's my first time to take part in the contribution of such a enormous project. Sorry for breaking the coding rules :-(

models/view/summary.go Outdated Show resolved Hide resolved
@muety
Copy link
Owner

muety commented Jan 17, 2025

I'm just a student and it's my first time to take part in the contribution of such a enormous project. Sorry for breaking the coding rules :-(

No worries, dude! Getting into a new code base is hard, even more so with a maintainer who is quite opinionated about architecture and code style... I'm happy to guide you the way through Wakapi's code. Perhaps you'll even become keen to contribute on a regular basis once you're familiar with it.

Copy link
Owner

@muety muety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found another two issue (maybe related):

  1. It looks like either the date shown below the vertical bars is wrong (off by -1 day). If I choose "Today" (today is Jan 17th), the chart will show 2025/01/16. Similarly, if I choose "Yesterday", the chart will instead show 2025/01/15 (the day before yesterday).
  2. The chart seems to omit the last day of the chosen interval. If I select "Past 7 Days", I'll end up with only six vertical bars, while the last one (today) is missing.

Also, can you please comment on my comment above regarding very large or very small intervals? I think the chart looks weird for less than three days or so and for more than 30 days (despite rendering the entire page unresponsive).

static/assets/js/summary.js Outdated Show resolved Hide resolved
@@ -41,6 +43,19 @@ func (h *SummaryHandler) RegisterRoutes(router chi.Router) {
router.Mount("/summary", r)
}

func (h *SummaryHandler) FetchSummaryForDailyProjectStats(params *models.SummaryParams) ([]*models.Summary, error) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor one: make this a private method (lower-case) and move it below all public methods. Also, please stick to Go code style convention of having camel-case variables (e.g. cur_summary -> curSummary).

models/view/summary.go Outdated Show resolved Hide resolved
@justin-jiajia
Copy link
Contributor Author

Found another two issue (maybe related):

  1. It looks like either the date shown below the vertical bars is wrong (off by -1 day). If I choose "Today" (today is Jan 17th), the chart will show 2025/01/16. Similarly, if I choose "Yesterday", the chart will instead show 2025/01/15 (the day before yesterday).
  2. The chart seems to omit the last day of the chosen interval. If I select "Past 7 Days", I'll end up with only six vertical bars, while the last one (today) is missing.

Also, can you please comment on my comment above regarding very large or very small intervals? I think the chart looks weird for less than three days or so and for more than 30 days (despite rendering the entire page unresponsive).

I'm sorry but I'm unable to reproduce both of these problems under CST(UTC+8). Here's my screenshot for the 'past 7 days'.

image

Could you please provide me with your timezone & wakapiData.dailyStats in the source of the summary?

@justin-jiajia
Copy link
Contributor Author

Thanks for implementing my change requests!

Do you think we should limit the calendar view component to a maximum number of days? Because when choosing a very large – if not All Time – interval, the chart becomes unreadable and super inefficient (blocked my browser tab for almost 30 seconds). Would love to hear your thoughts on that.

image

Yes. The problem is especially serious when the network to the database is slow. Or, in another word, server-side calculation also costs lots of time.

I've temporary limited the interval to (3days, 31days). However, if the user coded only 3 days in the past 3 month, the calendar view won't show up, either. This may lead to a worse user experience.

BTW, shall we us Time Cartesian Axis for the chart?

@muety muety self-requested a review January 22, 2025 21:05
Copy link
Owner

@muety muety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please provide me with your timezone & wakapiData.dailyStats in the source of the summary?

Never mind, I think it was an issue related to my test data. Tried again and seems to be working fine.


However, if the user coded only 3 days in the past 3 month, the calendar view won't show up, either.

Yes, I think that's not optimal. There should always be exactly as many vertical bars as there are days in the selected interval, otherwise users are going to be confused. To account for that, you could (a) either change your view model from [{date: '' project: '', duration: 0}] to a nested structure like [{ date: '', projects: [ { name: '', duration: 0 } ] }] to ensure one entry per day is present or, (b) fill missing dates front-end sided (probably a hassle) or, in the worst case (c) add a "dummy" project null (or so) to empty days.


BTW, shall we us Time Cartesian Axis for the chart?

Not very familiar with Chart.js, but sounds useful 👍


Btw., for whatever reason the activity chart isn't showing up anymore on your branch. Can you reproduce that and, if yes, fix it?

image

@justin-jiajia
Copy link
Contributor Author

justin-jiajia commented Jan 23, 2025

Could you please provide me with your timezone & wakapiData.dailyStats in the source of the summary?

Never mind, I think it was an issue related to my test data. Tried again and seems to be working fine.

I tried to fix another issue caused by time zones and this problem was resolved by the way. I didn’t realize it :)

However, if the user coded only 3 days in the past 3 month, the calendar view won't show up, either.

Yes, I think that's not optimal. There should always be exactly as many vertical bars as there are days in the selected interval, otherwise users are going to be confused. To account for that, you could (a) either change your view model from [{date: '' project: '', duration: 0}] to a nested structure like [{ date: '', projects: [ { name: '', duration: 0 } ] }] to ensure one entry per day is present or, (b) fill missing dates front-end sided (probably a hassle) or, in the worst case (c) add a "dummy" project null (or so) to empty days.

BTW, shall we us Time Cartesian Axis for the chart?

Not very familiar with Chart.js, but sounds useful 👍

Sorry for my vague expression. I wanted to say that Time Cartesian Axis does fix the missing vertical bars that were missing if the user didn’t code then. Here is an example.

Specifically, the axis make “Data spread according to the amount of time between data points”, providing a more simple approach of achieving the desired result. However, the time scale requires both a date library and a corresponding adapter to be present (see the link to the document above), which means that an extra JavaScript dependence will be added, drawing the size of the codebase.

Btw., for whatever reason the activity chart isn't showing up anymore on your branch. Can you reproduce that and, if yes, fix it?

image

Will try to fix if I can reproduce.

@muety
Copy link
Owner

muety commented Jan 23, 2025

I wanted to say that Time Cartesian Axis does fix the missing vertical bars

Perfect!

@justin-jiajia
Copy link
Contributor Author

Considering the Time Cartesian Axis requires 2 extra JavaScript dependence, I implement the function using your (a) plan.

Btw., for whatever reason the activity chart isn't showing up anymore on your branch. Can you reproduce that and, if yes, fix it?

To test the function, some test data is required. However, my network connection to the production database server is extremely slow, so the svg chart isn't showing at any pages. So, BTW, is there a CLI commend to generate some fake data?

@justin-jiajia justin-jiajia marked this pull request as draft January 23, 2025 14:12
@justin-jiajia
Copy link
Contributor Author

Forget to modify the rule of "no data". Will fix tomorrow.

@muety
Copy link
Owner

muety commented Jan 23, 2025

So, BTW, is there a CLI commend to generate some fake data?

You can use sample_data.py. Requires to install a bunch of Python dependencies though.

@justin-jiajia
Copy link
Contributor Author

justin-jiajia commented Jan 24, 2025 via email

@muety
Copy link
Owner

muety commented Jan 26, 2025

Let me know when you're ready for another round of review ✌️.

@justin-jiajia justin-jiajia marked this pull request as ready for review January 27, 2025 13:05
@justin-jiajia justin-jiajia requested a review from muety January 27, 2025 13:05
@justin-jiajia
Copy link
Contributor Author

justin-jiajia commented Jan 27, 2025

The No data rule changed.


Btw., for whatever reason the activity chart isn't showing up anymore on your branch. Can you reproduce that and, if yes, fix it?

It was really weird. The data seemed to be stored to the activityChartSvg of the PetiteVue instance. However, for certain reason it was not rendered in the page. I tested even with ${ activityChartSvg } alongside the svg and it wasn't rendered either.

So I came up with testing the page with only ${ activityChartSvg } left on the page (the mount param were also deleted, with a v-scope added on the its parent). Surprisingly, it worked! So I committed them as a workaround. I'm not sure whether or not it's a bug of PetiteVue.


It's uncomfortable for me to look at so much space in the right of the page. Could you please fix it? (I'm not familiar with the grids system frontend)

Copy link
Owner

@muety muety left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your HTML was messed up, meaning your opening and closing divs didn't match. Please revert the last commit and instead apply the changes from the attached patch.

fix_activity_chart.patch

Nevertheless, things still don't look perfectly right. Besides there being no margin before your chart the logic still doesn't seem to be correct. See attached screencast.

Screencast.From.2025-01-31.10-23-37.mp4

@justin-jiajia
Copy link
Contributor Author

justin-jiajia commented Jan 31, 2025 via email

@muety
Copy link
Owner

muety commented Jan 31, 2025

Sorry, fixed the link!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants