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(insights): add % of total option to line, bar and area trend insights (fixes #13728, #11276) #16699

Merged
merged 21 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
44e5cfc
show percentage stack view for bar graph
Arun-chaitanya Jul 20, 2023
ad8baa0
add percent stack view for bar graph
Arun-chaitanya Jul 20, 2023
febcb4f
Merge branch 'PostHog:master' into master
Arun-chaitanya Jul 21, 2023
d9533ec
constant datalabel when stacked100 is enabled
Arun-chaitanya Jul 21, 2023
b143b61
ternary operation instead of if else
Arun-chaitanya Jul 21, 2023
20acc84
Merge branch 'PostHog:master' into master
Arun-chaitanya Jul 23, 2023
6d2b738
adding percentStackView to Line and area graph
Arun-chaitanya Jul 23, 2023
9564947
Y-axis label, hiding unitsBox for percentStackView
Arun-chaitanya Jul 23, 2023
60a247a
removing from stickiness graph
Arun-chaitanya Jul 23, 2023
d60f811
PR comment related changes
Arun-chaitanya Jul 26, 2023
7e8a513
renaming formatYAxisLabel to formatPercentStackAxisValue
Arun-chaitanya Jul 26, 2023
022abaa
renaming to formatPercentStackAxisValue
Arun-chaitanya Jul 26, 2023
ccee100
persisting the checkbox value after saving insight
Arun-chaitanya Jul 26, 2023
c2e1f08
passing true false to checkbox
Arun-chaitanya Jul 26, 2023
ed84b5d
line graph stacked not working bug solved
Arun-chaitanya Jul 27, 2023
214b507
review amendmends
thmsobrmlr Jul 28, 2023
1cc2889
Merge branch 'master' into Arun-chaitanya/master
thmsobrmlr Jul 28, 2023
3540866
update schema
thmsobrmlr Jul 28, 2023
650fe0b
update visual regression tests
thmsobrmlr Jul 28, 2023
27cfe97
update more snapshots
thmsobrmlr Jul 28, 2023
e000cab
update more snapshots
thmsobrmlr Jul 29, 2023
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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-area-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-area.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-bar-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-bar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-line-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified frontend/__snapshots__/scenes-app-insights--trends-line.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions frontend/src/lib/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ export const NON_VALUES_ON_SERIES_DISPLAY_TYPES = [
ChartDisplayType.WorldMap,
ChartDisplayType.BoldNumber,
]

/** Display types for which a percent stack view is available. */
export const PERCENT_STACK_VIEW_DISPLAY_TYPE = [
ChartDisplayType.ActionsBar,
ChartDisplayType.ActionsLineGraph,
ChartDisplayType.ActionsAreaGraph,
]
Arun-chaitanya marked this conversation as resolved.
Show resolved Hide resolved

export enum OrganizationMembershipLevel {
Member = 1,
Admin = 8,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ export const filtersToQueryNode = (filters: Partial<FilterType>): InsightQueryNo
shown_as: filters.shown_as,
display: filters.display,
show_values_on_series: filters.show_values_on_series,
show_percent_stack_view: filters.show_percent_stack_view,
})
}

Expand Down
13 changes: 12 additions & 1 deletion frontend/src/queries/nodes/InsightViz/InsightDisplayConfig.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { ChartFilter } from 'lib/components/ChartFilter'
import { FunnelDisplayLayoutPicker } from 'scenes/insights/views/Funnels/FunnelDisplayLayoutPicker'
import { FunnelBinsPicker } from 'scenes/insights/views/Funnels/FunnelBinsPicker'
import { ValueOnSeriesFilter } from 'scenes/insights/EditorFilters/ValueOnSeriesFilter'
import { PercentStackView } from 'scenes/insights/EditorFilters/PercentStackView'
import { trendsDataLogic } from 'scenes/trends/trendsDataLogic'

interface InsightDisplayConfigProps {
disableTable: boolean
Expand All @@ -28,6 +30,7 @@ export function InsightDisplayConfig({ disableTable }: InsightDisplayConfigProps
disableDateRange,
showCompare,
showValueOnSeries,
showPercentStackView,
showUnit,
showChart,
showInterval,
Expand All @@ -38,6 +41,8 @@ export function InsightDisplayConfig({ disableTable }: InsightDisplayConfigProps
showFunnelBins,
} = useValues(insightDisplayConfigLogic(insightProps))

const { showPercentStackView: isPercentStackViewOn } = useValues(trendsDataLogic(insightProps))
Arun-chaitanya marked this conversation as resolved.
Show resolved Hide resolved

return (
<div className="flex justify-between items-center flex-wrap" data-attr="insight-filters">
<div className="flex items-center space-x-2 flex-wrap my-2 gap-y-2">
Expand Down Expand Up @@ -83,9 +88,15 @@ export function InsightDisplayConfig({ disableTable }: InsightDisplayConfigProps
<ValueOnSeriesFilter />
</ConfigFilter>
)}

{showPercentStackView && (
<ConfigFilter>
<PercentStackView />
</ConfigFilter>
)}
</div>
<div className="flex items-center space-x-4 flex-wrap my-2 grow justify-end">
{showUnit && (
{!isPercentStackViewOn && showUnit && (
<ConfigFilter>
<UnitPicker />
</ConfigFilter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export const insightDisplayConfigLogic = kea<insightDisplayConfigLogicType>([
'isStickiness',
'isLifecycle',
'supportsDisplay',
'supportsPercentStackView as showPercentStackView',
'display',
'breakdown',
'trendsFilter',
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/queries/nodes/InsightViz/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ export const getShowValueOnSeries = (query: InsightQueryNode): boolean | undefin
}
}

export const getShowPercentStackView = (query: InsightQueryNode): boolean | undefined => {
if (isTrendsQuery(query)) {
return query.trendsFilter?.show_percent_stack_view
} else {
return undefined
}
}

export const getCachedResults = (
cachedInsight: Partial<InsightModel> | undefined | null,
query: InsightQueryNode
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/queries/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2020,6 +2020,9 @@
"show_legend": {
"type": "boolean"
},
"show_percent_stack_view": {
"type": "boolean"
},
"show_values_on_series": {
"type": "boolean"
},
Expand Down
22 changes: 22 additions & 0 deletions frontend/src/scenes/insights/EditorFilters/PercentStackView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useActions, useValues } from 'kea'
import { LemonCheckbox } from 'lib/lemon-ui/LemonCheckbox'
import { insightLogic } from '../insightLogic'
import { trendsDataLogic } from 'scenes/trends/trendsDataLogic'

export function PercentStackView(): JSX.Element {
const { insightProps } = useValues(insightLogic)
const { showPercentStackView } = useValues(trendsDataLogic(insightProps))
const { updateInsightFilter } = useActions(trendsDataLogic(insightProps))

return (
<LemonCheckbox
checked={!!showPercentStackView}
onChange={(checked) => {
updateInsightFilter({ show_percent_stack_view: checked })
}}
label={<span className="font-normal">Show as % of total</span>}
bordered
size="small"
/>
)
}
13 changes: 13 additions & 0 deletions frontend/src/scenes/insights/aggregationAxisFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ export const formatAggregationAxisValue = (
}`
}

export const formatPercentStackAxisValue = (
trendsFilter: TrendsFilter | null | undefined | Partial<TrendsFilterType>,
value: number | string,
isPercentStackView: boolean
): string => {
if (isPercentStackView) {
value = Number(value)
return percentage(value / 100)
} else {
return formatAggregationAxisValue(trendsFilter, value)
}
}

export const axisLabel = (chartDisplayType: ChartDisplayType | null | undefined): string => {
switch (chartDisplayType) {
case ChartDisplayType.ActionsLineGraph:
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/scenes/insights/insightVizDataLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
isStickinessQuery,
isTrendsQuery,
} from '~/queries/utils'
import { NON_TIME_SERIES_DISPLAY_TYPES } from 'lib/constants'
import { NON_TIME_SERIES_DISPLAY_TYPES, PERCENT_STACK_VIEW_DISPLAY_TYPE } from 'lib/constants'
import {
getBreakdown,
getCompare,
Expand All @@ -37,6 +37,7 @@ import {
getInterval,
getSeries,
getShownAs,
getShowPercentStackView,
getShowValueOnSeries,
} from '~/queries/nodes/InsightViz/utils'
import { DISPLAY_TYPES_WITHOUT_LEGEND } from 'lib/components/InsightLegend/utils'
Expand Down Expand Up @@ -104,6 +105,12 @@ export const insightVizDataLogic = kea<insightVizDataLogicType>([
isTrendsLike: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isLifecycleQuery(q) || isStickinessQuery(q)],
supportsDisplay: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isStickinessQuery(q)],
supportsCompare: [(s) => [s.querySource], (q) => isTrendsQuery(q) || isStickinessQuery(q)],
supportsPercentStackView: [
(s) => [s.querySource, s.display],
(q, display) =>
isTrendsQuery(q) &&
PERCENT_STACK_VIEW_DISPLAY_TYPE.includes(display || ChartDisplayType.ActionsLineGraph),
],

dateRange: [(s) => [s.querySource], (q) => (q ? q.dateRange : null)],
breakdown: [(s) => [s.querySource], (q) => (q ? getBreakdown(q) : null)],
Expand All @@ -116,6 +123,7 @@ export const insightVizDataLogic = kea<insightVizDataLogicType>([
samplingFactor: [(s) => [s.querySource], (q) => (q ? q.samplingFactor : null)],
shownAs: [(s) => [s.querySource], (q) => (q ? getShownAs(q) : null)],
showValueOnSeries: [(s) => [s.querySource], (q) => (q ? getShowValueOnSeries(q) : null)],
showPercentStackView: [(s) => [s.querySource], (q) => (q ? getShowPercentStackView(q) : null)],

insightFilter: [(s) => [s.querySource], (q) => (q ? filterForQuery(q) : null)],
trendsFilter: [(s) => [s.querySource], (q) => (isTrendsQuery(q) ? q.trendsFilter : null)],
Expand Down
27 changes: 26 additions & 1 deletion frontend/src/scenes/insights/utils/cleanFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import {
} from '~/types'
import { deepCleanFunnelExclusionEvents, getClampedStepRangeFilter, isStepsUndefined } from 'scenes/funnels/funnelUtils'
import { getDefaultEventName } from 'lib/utils/getAppContext'
import { BIN_COUNT_AUTO, NON_VALUES_ON_SERIES_DISPLAY_TYPES, RETENTION_FIRST_TIME, ShownAsValue } from 'lib/constants'
import {
BIN_COUNT_AUTO,
NON_VALUES_ON_SERIES_DISPLAY_TYPES,
PERCENT_STACK_VIEW_DISPLAY_TYPE,
RETENTION_FIRST_TIME,
ShownAsValue,
} from 'lib/constants'
import { autocorrectInterval } from 'lib/utils'
import { DEFAULT_STEP_LIMIT } from 'scenes/paths/pathsDataLogic'
import { smoothingOptions } from 'lib/components/SmoothingFilter/smoothings'
Expand Down Expand Up @@ -311,6 +317,9 @@ export function cleanFilters(
? { hidden_legend_keys: filters.hidden_legend_keys }
: {}),
...(filters.show_values_on_series ? { show_values_on_series: filters.show_values_on_series } : {}),
...(isTrendsFilter(filters) && filters?.show_percent_stack_view
? { show_percent_stack_view: filters.show_percent_stack_view }
: {}),
...commonFilters,
}

Expand All @@ -330,6 +339,22 @@ export function cleanFilters(
trendLikeFilter.show_values_on_series = true
}

if (
'show_percent_stack_view' in trendLikeFilter &&
!!trendLikeFilter.display &&
!PERCENT_STACK_VIEW_DISPLAY_TYPE.includes(trendLikeFilter.display)
) {
delete trendLikeFilter.show_percent_stack_view
}

if (
!!trendLikeFilter.display &&
trendLikeFilter.display === ChartDisplayType.ActionsPie &&
trendLikeFilter.show_percent_stack_view === undefined
) {
trendLikeFilter.show_percent_stack_view = true
}

cleanBreakdownParams(trendLikeFilter, filters)

// TODO: Deprecated; should be removed once backend is updated
Expand Down
29 changes: 21 additions & 8 deletions frontend/src/scenes/insights/views/LineGraph/LineGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,15 @@ import { lineGraphLogic } from 'scenes/insights/views/LineGraph/lineGraphLogic'
import { TooltipConfig } from 'scenes/insights/InsightTooltip/insightTooltipUtils'
import { groupsModel } from '~/models/groupsModel'
import { ErrorBoundary } from '~/layout/ErrorBoundary'
import { formatAggregationAxisValue } from 'scenes/insights/aggregationAxisFormat'
import { formatPercentStackAxisValue } from 'scenes/insights/aggregationAxisFormat'
import { insightLogic } from 'scenes/insights/insightLogic'
import { useResizeObserver } from 'lib/hooks/useResizeObserver'
import { PieChart } from 'scenes/insights/views/LineGraph/PieChart'
import { themeLogic } from '~/layout/navigation-3000/themeLogic'
import { SeriesLetter } from 'lib/components/SeriesGlyph'
import { TrendsFilter } from '~/queries/schema'
import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic'
import ChartjsPluginStacked100, { ExtendedChartData } from 'chartjs-plugin-stacked100'

export function ensureTooltipElement(): HTMLElement {
let tooltipEl = document.getElementById('InsightTooltipWrapper')
Expand Down Expand Up @@ -211,6 +212,8 @@ export interface LineGraphProps {
formula?: string | null
compare?: boolean | null
showValueOnSeries?: boolean | null
showPercentStackView?: boolean | null
supportsPercentStackView?: boolean
}

export const LineGraph = (props: LineGraphProps): JSX.Element => {
Expand Down Expand Up @@ -239,6 +242,8 @@ export function LineGraph_({
trendsFilter,
formula,
showValueOnSeries,
showPercentStackView,
supportsPercentStackView,
}: LineGraphProps): JSX.Element {
let datasets = _datasets

Expand All @@ -265,6 +270,7 @@ export function LineGraph_({

const isBar = [GraphType.Bar, GraphType.HorizontalBar, GraphType.Histogram].includes(type)
const isBackgroundBasedGraphType = [GraphType.Bar, GraphType.HorizontalBar].includes(type)
const isPercentStackView = !!supportsPercentStackView && !!showPercentStackView
const showAnnotations = isTrends && !isHorizontal
const shouldAutoResize = isHorizontal && !inCardView

Expand Down Expand Up @@ -371,6 +377,7 @@ export function LineGraph_({
},
},
plugins: {
stacked100: { enable: isPercentStackView, precision: 1 },
datalabels: {
color: 'white',
anchor: (context) => {
Expand All @@ -384,7 +391,12 @@ export function LineGraph_({
const datum = context.dataset.data[context.dataIndex]
return showValueOnSeries === true && typeof datum === 'number' && datum !== 0 ? 'auto' : false
},
formatter: (value: number) => formatAggregationAxisValue(trendsFilter, value),
formatter: (value: number, context) => {
const data = context.chart.data as ExtendedChartData
const { datasetIndex, dataIndex } = context
const percentageValue = data.calculatedData?.[datasetIndex][dataIndex]
return formatPercentStackAxisValue(trendsFilter, percentageValue || value, isPercentStackView)
},
borderWidth: 2,
borderRadius: 4,
borderColor: 'white',
Expand Down Expand Up @@ -449,7 +461,8 @@ export function LineGraph_({
}}
renderCount={
tooltipConfig?.renderCount ||
((value: number): string => formatAggregationAxisValue(trendsFilter, value))
((value: number): string =>
formatPercentStackAxisValue(trendsFilter, value, isPercentStackView))
}
entitiesAsColumnsOverride={formula ? false : undefined}
hideInspectActorsSection={!onClick || !showPersonsModal}
Expand Down Expand Up @@ -534,7 +547,7 @@ export function LineGraph_({
precision,
color: colors.axisLabel as string,
callback: (value) => {
return formatAggregationAxisValue(trendsFilter, value)
return formatPercentStackAxisValue(trendsFilter, value, isPercentStackView)
},
},
},
Expand All @@ -555,12 +568,12 @@ export function LineGraph_({
y: {
beginAtZero: true,
display: true,
stacked: isArea,
stacked: showPercentStackView || isArea,
ticks: {
precision,
...tickOptions,
callback: (value) => {
return formatAggregationAxisValue(trendsFilter, value)
return formatPercentStackAxisValue(trendsFilter, value, isPercentStackView)
},
},
grid: {
Expand All @@ -577,7 +590,7 @@ export function LineGraph_({
...tickOptions,
precision,
callback: (value) => {
return formatAggregationAxisValue(trendsFilter, value)
return formatPercentStackAxisValue(trendsFilter, value, isPercentStackView)
},
},
},
Expand Down Expand Up @@ -614,7 +627,7 @@ export function LineGraph_({
}
options.indexAxis = 'y'
}

Chart.register(ChartjsPluginStacked100)
const newChart = new Chart(canvasRef.current?.getContext('2d') as ChartItem, {
type: (isBar ? GraphType.Bar : type) as ChartType,
data: { labels, datasets },
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/scenes/trends/trendsDataLogic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export const trendsDataLogic = kea<trendsDataLogicType>([
'breakdown',
'shownAs',
'showValueOnSeries',
'showPercentStackView',
'supportsPercentStackView',
'trendsFilter',
'lifecycleFilter',
'isTrends',
Expand All @@ -37,7 +39,7 @@ export const trendsDataLogic = kea<trendsDataLogicType>([
'hasLegend',
],
],
actions: [insightVizDataLogic(props), ['setInsightData']],
actions: [insightVizDataLogic(props), ['setInsightData', 'updateInsightFilter']],
})),

actions({
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/scenes/trends/viz/ActionsLineGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export function ActionsLineGraph({
interval,
shownAs,
showValueOnSeries,
showPercentStackView,
supportsPercentStackView,
trendsFilter,
isLifecycle,
isStickiness,
Expand All @@ -46,6 +48,8 @@ export function ActionsLineGraph({
trendsFilter={trendsFilter}
formula={formula}
showValueOnSeries={showValueOnSeries}
showPercentStackView={showPercentStackView}
supportsPercentStackView={supportsPercentStackView}
tooltip={
isLifecycle
? {
Expand Down
1 change: 1 addition & 0 deletions frontend/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1655,6 +1655,7 @@ export interface TrendsFilterType extends FilterType {
shown_as?: ShownAsValue
display?: ChartDisplayType
show_values_on_series?: boolean
show_percent_stack_view?: boolean
breakdown_histogram_bin_count?: number // trends breakdown histogram bin count
}
export interface StickinessFilterType extends FilterType {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"chartjs-adapter-dayjs-3": "^1.2.3",
"chartjs-plugin-crosshair": "^1.2.0",
"chartjs-plugin-datalabels": "^2.2.0",
"chartjs-plugin-stacked100": "^1.4.0",
"chokidar": "^3.5.3",
"clsx": "^1.1.1",
"core-js": "3.15.2",
Expand Down
Loading