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

Feature: add cohort retention chart, convert js to ts, add types, small fixes, move function comments to jsdocs #36

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

FranjoMindek
Copy link
Contributor

@FranjoMindek FranjoMindek commented Mar 20, 2025

Adds cohort retention chart

Converted js files to ts files
Added missing types because of above
Fixed some bugs that existed because of above
Converted function comments to JSDoc via LLM

Closes: #33

@FranjoMindek FranjoMindek self-assigned this Mar 20, 2025
@@ -0,0 +1,115 @@
/**
* Interpolates between multiple colors, returning an array of evenly spaced colors
* @param {string[]} colors - Array of hex color codes to interpolate between
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Autogenerated by LLM, I've checked logic and it seems fine.

import * as logger from "winston";

logger.remove(logger.transports.Console);
logger.add(new logger.transports.Console(), { colorize: true });
Copy link
Contributor Author

@FranjoMindek FranjoMindek Mar 20, 2025

Choose a reason for hiding this comment

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

{ colorize: true } threw an error because add function accepts only 1 param

@@ -0,0 +1,123 @@
import moment from "../../moment";
Copy link
Contributor Author

@FranjoMindek FranjoMindek Mar 20, 2025

Choose a reason for hiding this comment

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

This file did everything related to periods, so I've renamed it from common

@FranjoMindek FranjoMindek changed the title Feature: add cohort retention chart, convert js to ts, add types, small fixes, move comments to to jsdocs Feature: add cohort retention chart, convert js to ts, add types, small fixes, move function comments to jsdocs Mar 20, 2025
Copy link
Member

@Martinsos Martinsos left a comment

Choose a reason for hiding this comment

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

@FranjoMindek nice to see this coming to life!

The biggest issue with this PR is its size and scope of changes. Except for adding this new chart, you also added types, reformatted comments and renamed files that are not directly related to this change.

I started reviewing, but soon realized it will take a lot of time to just figure out what really changed and what didn't.

I suggest that you break this PR into two or more PRs, where each one is focused on one "theme". E.g. the first one might be general refactor where you introduce the types and rename files and similar. In taht one for example you can, if you know that most of the code didn't relaly change, comment in Github only on the parts that did change, so I can review it much faster. The other PR can build on top of this one and implement the actual chart.

WHat is also tricky is when you do changes + also rename the file, it seems Github didn't have great time here doing diff so it just marked old files as deleted and new files as completely new -> again, that makes it quite hard to review. I would probably actually make the first PR that just does the renaming, nothing else or at least minimal changes, and only then the second PR that makes further refactors -> that way diffs will be reasonable and it will be much easier to review.

You can make these PRs rebased one on top of another.

The comments I made so far you can then address in the relevant PR once you create it.

@@ -1,5 +1,5 @@
node_modules/
.env
.env*
Copy link
Member

Choose a reason for hiding this comment

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

I would call this too aggresive. It will also trigger on stuff like .envision for example (made that up) and that was not your intention.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was introduced by vault dotenv. Didn't see it as problematic but you're right.

return chart.toURL();
}

export function buildChartBase(data: ChartData, title: string) {
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't feel like the best name. What is "chart base"? How would you explain that term? That is not a common term, so I can't really know what to expect from it, and also there are no comments on top of function that would define what function promises to return. So the only way for me is to check the implementation and try to guess the intention from it. On the other hand, somebody can come in the future and modify what this function does following their own interpretation of that intention, which is different, therefore changing the expected behaviour and causing issues in the places where it is used.
TLDR: better name and/or function header comments explaining what it does in enough details that consuemr of this function can somewhat rely on it.

title: string,
) {
const chart = buildChartBase(data, title)
.cht("bvs") // Type: lines or vertical bars? Could also be other things.
Copy link
Member

Choose a reason for hiding this comment

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

Old comment, not correct here any more (there are no lines here any more, only vertical bars).

@@ -0,0 +1,50 @@
import ImageCharts from "image-charts";
import { interpolateColors } from "./reports/colors";
import { ChartData } from "./types";
Copy link
Member

Choose a reason for hiding this comment

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

I am not a fan of separting types into separate files, never done it in wahtever language I work in. Sometimes, rarely, there can be a good reason for it, but that is rare. Types are a part of domain same as the rest of the code, and shouldn't be split unneccesarily.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can reorder it to be more domain oriented.

) {
const chart = buildChartBase(data, title)
.cht("bvs") // Type: lines or vertical bars? Could also be other things.
.chco(
Copy link
Member

Choose a reason for hiding this comment

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

functions of IMage Charts are quite badly names so it is hard to figure what th ey do. That is why I was providing so many comments, so reader can undersatnd what is happeing without having to go consult the ImageChart docs immedaitely.
Would be great if you provided similar comments here, because right now I don't know what this does wihtout consulting the docs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, forgot to change this one. It's just type. But it was done messily previously.

Comment on lines +28 to +50
return new ImageCharts()
.chtt(title)
.chd(
"a:" +
Object.values(data.series)
.map((s) => s.join(","))
.join("|"),
) // Data series.
.chl(
Object.values(data.series)
.map((s) => s.map((v) => v ?? undefined).join("|"))
.join("|"),
) // Value labels on bars.
.chlps("font.size,12")
.chdl(Object.keys(data.series).join("|")) // Legend (per series)
.chdlp("b") // Position of legend. 'b' is for bottom.
.chxl("0:|" + data.periodEnds.join("|")) // X axis labels.
.chxs("0,s,min45max45") // On x-axis (0), skip some labels (s) and use 45 degress angle (min45max45).
.chs("700x400") // Size.
.chg("20,20") // Solid or dotted grid lines.
.chma("0,50,50") // Margins.
.chxt("x,y"); // Axes to show.
}
Copy link
Member

Choose a reason for hiding this comment

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

Since file changed the name, we get this not at all useful diff that shows everyting as one big change. Can you confirm that there was no changes in this block of code so I don't have to go through it line by line and compare? Or if there were changes, can you point me to them?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mostly pointed out logic changes with my comments.
Only changes was that .cht("bvs") now explictly says it's type for analytics chart, rather than using ternary operator which was always false. Rest is the same.

@@ -50,12 +59,12 @@ function showReportInCLI(report) {
}
}
if (metric.chart) {
console.log("- Chart: ", metric.chart.toURL());
console.log("- Chart: ", metric.chart);
Copy link
Member

Choose a reason for hiding this comment

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

Why is toURL not needed any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function was named build...ImageUrl, but it was returning an chart object, rather than imageUrl, which is misleading.
Everywhere where the chart object was used it was just converted to imageUrl though.
I just made the function return imageUrl as it's name states.

Copy link
Member

Choose a reason for hiding this comment

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

Then probably we should also rename that field to metric.chartImageUrl!

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.

Add a chart that shows cohort retention
2 participants