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

feat: granularity new analytics changes #2017

Merged
merged 15 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/components/Graphs/LineGraph/LineGraphUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let getLineGraphOptions = (lineGraphOptions: lineGraphPayload) => {
let {categories, data, title, tooltipFormatter, yAxisMaxValue} = lineGraphOptions

let stepInterval = Js.Math.max_int(
Js.Math.ceil_int(categories->Array.length->Int.toFloat /. 20.0),
Js.Math.ceil_int(categories->Array.length->Int.toFloat /. 13.0),
1,
)

Expand Down
53 changes: 34 additions & 19 deletions src/screens/NewAnalytics/NewAnalyticsHelper.res
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ module TabSwitch = {
| Table => ("bg-white", "text-grey-dark", "table-view")
}

<div className="border border-gray-outline flex w-fit rounded-lg cursor-pointer">
<div className="border border-gray-outline flex w-fit rounded-lg cursor-pointer h-fit">
<div
className={`rounded-l-lg pl-3 pr-2 pt-2 pb-1 ${icon1Bg}`} onClick={_ => setViewType(Graph)}>
className={`rounded-l-lg pl-3 pr-2 pt-2 pb-0.5 ${icon1Bg}`}
onClick={_ => setViewType(Graph)}>
<Icon className={icon1Color} name={icon1Name} size=25 />
</div>
<div className="h-full border-l border-gray-outline" />
<div
className={`rounded-r-lg pl-3 pr-2 pt-2 pb-1 ${icon2Bg}`} onClick={_ => setViewType(Table)}>
<div className={`rounded-r-lg pl-3 pr-2 pt-2 ${icon2Bg}`} onClick={_ => setViewType(Table)}>
<Icon className={icon2Color} name=icon2Name size=25 />
</div>
</div>
Expand All @@ -65,7 +65,12 @@ module TabSwitch = {
module Tabs = {
open NewAnalyticsTypes
@react.component
let make = (~option: optionType, ~setOption: optionType => unit, ~options: array<optionType>) => {
let make = (
~option: optionType,
~setOption: optionType => unit,
~options: array<optionType>,
~showSingleTab=true,
) => {
let getStyle = (value: string, index) => {
let textStyle =
value === option.value
Expand All @@ -74,24 +79,34 @@ module Tabs = {

let borderStyle = index === 0 ? "" : "border-l"

let borderRadius =
index === 0 ? "rounded-l-lg" : index === options->Array.length - 1 ? "rounded-r-lg" : ""
let borderRadius = if options->Array.length == 1 {
"rounded-lg"
} else if index === 0 {
"rounded-l-lg"
} else if index === options->Array.length - 1 {
"rounded-r-lg"
} else {
""
}

`${textStyle} ${borderStyle} ${borderRadius}`
}

<div className="border border-gray-outline flex w-fit rounded-lg cursor-pointer text-sm ">
{options
->Array.mapWithIndex((tabValue, index) =>
<div
key={index->Int.toString}
className={`px-3 py-2 ${tabValue.value->getStyle(index)} selection:bg-white`}
onClick={_ => setOption(tabValue)}>
{tabValue.label->React.string}
</div>
)
->React.array}
</div>
<RenderIf condition={showSingleTab || options->Array.length > 1}>
<div
className="border border-gray-outline flex w-fit rounded-lg cursor-pointer text-sm h-fit">
{options
->Array.mapWithIndex((tabValue, index) =>
<div
key={index->Int.toString}
className={`px-3 py-2 ${tabValue.value->getStyle(index)} selection:bg-white`}
onClick={_ => setOption(tabValue)}>
{tabValue.label->React.string}
</div>
)
->React.array}
</div>
</RenderIf>
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/screens/NewAnalytics/NewAnalyticsTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type metrics = [
]
type granularity = [
| #G_ONEDAY
| #G_ONEHOUR
| #G_THIRTYMIN
| #G_FIFTEENMIN
]

type requestBodyConfig = {
Expand Down
161 changes: 112 additions & 49 deletions src/screens/NewAnalytics/NewAnalyticsUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,6 @@ let sankyRed = "#F7E0E0"
let sankyLightBlue = "#91B7EE"
let sankyLightRed = "#EC6262"

let getBucketSize = granularity => {
switch granularity {
| "hour_wise" => "hour"
| "week_wise" => "week"
| "day_wise" | _ => "day"
}
}

let fillMissingDataPoints = (
~data,
~startDate,
~endDate,
~timeKey="time_bucket",
~defaultValue: JSON.t,
~granularity: string,
) => {
open LogicUtils
let dataDict = Dict.make()
data->Array.forEach(item => {
let time = item->getDictFromJsonObject->getString(timeKey, "")
dataDict->Dict.set(time, item)
})
let dataPoints = Dict.make()
let startingPoint = startDate->DayJs.getDayJsForString
let endingPoint = endDate->DayJs.getDayJsForString
let gap = granularity->getBucketSize
for x in 0 to endingPoint.diff(startingPoint.toString(), gap) {
let newDict = defaultValue->getDictFromJsonObject->Dict.copy
let timeVal = startingPoint.add(x, gap).endOf(gap).format("YYYY-MM-DD 00:00:00")
switch dataDict->Dict.get(timeVal) {
| Some(val) => {
newDict->Dict.set(timeKey, timeVal->JSON.Encode.string)
dataPoints->Dict.set(timeVal, val)
}
| None => {
newDict->Dict.set(timeKey, timeVal->JSON.Encode.string)
dataPoints->Dict.set(timeVal, newDict->JSON.Encode.object)
}
}
}
dataPoints->Dict.valuesToArray
}

open NewAnalyticsTypes
let globalFilter: array<filters> = [#currency]
let globalExcludeValue = [(#all_currencies: defaultFilters :> string)]
Expand Down Expand Up @@ -222,16 +179,31 @@ let isEmptyGraph = (data: JSON.t, key: string) => {
}

let getCategories = (data: JSON.t, index: int, key: string) => {
data
->getArrayFromJson([])
->getValueFromArray(index, []->JSON.Encode.array)
->getArrayFromJson([])
->Array.map(item => {
let options =
data
->getArrayFromJson([])
->getValueFromArray(index, []->JSON.Encode.array)
->getArrayFromJson([])
let isShowTime = options->Array.reduce(false, (flag, item) => {
let value = item->getDictFromJsonObject->getString(key, "NA")
if value->isNonEmptyString && key == "time_bucket" {
let dateObj = value->DayJs.getDayJsForString
dateObj.format("HH") != "00" || flag
} else {
false
}
})

options->Array.map(item => {
let value = item->getDictFromJsonObject->getString(key, "NA")

if value->isNonEmptyString && key == "time_bucket" {
let dateObj = value->DayJs.getDayJsForString
`${dateObj.month()->getMonthName} ${dateObj.format("DD")}`
if isShowTime {
`${dateObj.month()->getMonthName} ${dateObj.format("DD")}, ${dateObj.format("HH:mm")}`
} else {
`${dateObj.month()->getMonthName} ${dateObj.format("DD")}`
}
} else {
value
}
Expand Down Expand Up @@ -499,3 +471,94 @@ let generateFilterObject = (~globalFilters, ~localFilters=None) => {

filters->JSON.Encode.object
}

let getGranularityLabel = option => {
switch option {
| #G_ONEDAY => "Day-wise"
| #G_ONEHOUR => "Hour-wise"
| #G_THIRTYMIN => "30min-wise"
| #G_FIFTEENMIN => "15min-wise"
}
}

let defaulGranularity = {
label: #G_ONEDAY->getGranularityLabel,
value: (#G_ONEDAY: granularity :> string),
}

let getGranularityOptions = (~startTime, ~endTime) => {
let startingPoint = startTime->DayJs.getDayJsForString
let endingPoint = endTime->DayJs.getDayJsForString
let gap = endingPoint.diff(startingPoint.toString(), "hour") // diff between points

let options = if gap < 1 {
[#G_THIRTYMIN, #G_FIFTEENMIN]
} else if gap < 24 {
[#G_ONEHOUR, #G_THIRTYMIN, #G_FIFTEENMIN]
} else if gap < 168 {
[#G_ONEDAY, #G_ONEHOUR]
} else {
[#G_ONEDAY]
}

options->Array.map(option => {
label: option->getGranularityLabel,
value: (option: granularity :> string),
})
}

let getDefaultGranularity = (~startTime, ~endTime) => {
let options = getGranularityOptions(~startTime, ~endTime)
options->Array.get(options->Array.length - 1)->Option.getOr(defaulGranularity)
}

let getGranularityGap = option => {
switch option {
| "G_ONEHOUR" => 60
| "G_THIRTYMIN" => 30
| "G_FIFTEENMIN" => 15
| "G_ONEDAY" | _ => 1440
}
}

let fillMissingDataPoints = (
~data,
~startDate,
~endDate,
~timeKey="time_bucket",
~defaultValue: JSON.t,
~granularity: string,
) => {
let dataDict = Dict.make()
data->Array.forEach(item => {
let time = item->getDictFromJsonObject->getString(timeKey, "")
dataDict->Dict.set(time, item)
})
let dataPoints = Dict.make()
let startingPoint = startDate->DayJs.getDayJsForString
let startingPoint = startingPoint.format("YYYY-MM-DD HH:00:00")->DayJs.getDayJsForString
let endingPoint = endDate->DayJs.getDayJsForString
let gap = "minute"
let devider = granularity->getGranularityGap
let limit =
(endingPoint.diff(startingPoint.toString(), gap)->Int.toFloat /. devider->Int.toFloat)
->Math.floor
->Float.toInt

for x in 0 to limit {
let newDict = defaultValue->getDictFromJsonObject->Dict.copy
let timeVal = startingPoint.add(x * devider, gap).format("YYYY-MM-DD HH:mm:ss")
switch dataDict->Dict.get(timeVal) {
| Some(val) => {
newDict->Dict.set(timeKey, timeVal->JSON.Encode.string)
dataPoints->Dict.set(timeVal, val)
}
| None => {
newDict->Dict.set(timeKey, timeVal->JSON.Encode.string)
dataPoints->Dict.set(timeVal, newDict->JSON.Encode.object)
}
}
}

dataPoints->Dict.valuesToArray
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ let make = (
JSON.Encode.array([])
)
let (selectedMetric, setSelectedMetric) = React.useState(_ => defaultMetric)
let (granularity, setGranularity) = React.useState(_ => defaulGranularity)
let (viewType, setViewType) = React.useState(_ => Graph)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
Expand All @@ -160,6 +159,10 @@ let make = (
let comparison = filterValueJson->getString("comparison", "")->DateRangeUtils.comparisonMapprer
let currency = filterValueJson->getString((#currency: filters :> string), "")

let (granularity, setGranularity) = React.useState(_ =>
getDefaultGranularity(~startTime=startTimeVal, ~endTime=endTimeVal)
)

let getRefundsProcessed = async () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ let make = (
JSON.Encode.array([])
)

let (granularity, setGranularity) = React.useState(_ => defaulGranularity)
let {filterValueJson} = React.useContext(FilterContext.filterContext)
let startTimeVal = filterValueJson->getString("startTime", "")
let endTimeVal = filterValueJson->getString("endTime", "")
Expand All @@ -66,6 +65,10 @@ let make = (
let comparison = filterValueJson->getString("comparison", "")->DateRangeUtils.comparisonMapprer
let currency = filterValueJson->getString((#currency: filters :> string), "")

let (granularity, setGranularity) = React.useState(_ =>
getDefaultGranularity(~startTime=startTimeVal, ~endTime=endTimeVal)
)

let getPaymentsSuccessRate = async () => {
setScreenState(_ => PageLoaderWrapper.Loading)
try {
Expand Down
Loading
Loading