Skip to content

Commit

Permalink
feat(insights): add area chart (closes #7372) (#12869)
Browse files Browse the repository at this point in the history
* add area chart display type

* refactor(line-graph): use chartjs scriptable to dash lines for incomplete data

* add initial implementation of stacked area chart

* implement missing data for area charts

* fix icon

* add storybook examples

* disable compare to previous for area charts

* improve comments

* refactor show compare filter
  • Loading branch information
thmsobrmlr authored and neilkakkar committed Nov 28, 2022
1 parent ead03a8 commit 7e0524a
Show file tree
Hide file tree
Showing 13 changed files with 2,124 additions and 47 deletions.
4 changes: 4 additions & 0 deletions frontend/src/lib/components/Cards/InsightCard/InsightCard.tsx
Expand Up @@ -81,6 +81,10 @@ const displayMap: Record<
className: 'graph',
element: ActionsLineGraph,
},
ActionsAreaGraph: {
className: 'graph',
element: ActionsLineGraph,
},
ActionsBar: {
className: 'bar',
element: ActionsLineGraph,
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/lib/components/ChartFilter/ChartFilter.tsx
Expand Up @@ -4,6 +4,7 @@ import {
IconShowChart,
IconCumulativeChart,
IconBarChart,
IconAreaChart,
Icon123,
IconPieChart,
IconTableChart,
Expand Down Expand Up @@ -80,6 +81,10 @@ export function ChartFilter({ filters, onChange, disabled }: ChartFilterProps):
label: <Label icon={<IconBarChart />}>Bar</Label>,
disabled: barDisabled,
},
{
value: ChartDisplayType.ActionsAreaGraph,
label: <Label icon={<IconAreaChart />}>Area</Label>,
},
],
},
{
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/lib/components/icons.stories.tsx
Expand Up @@ -26,7 +26,7 @@ export default {
[Related Figma area](https://www.figma.com/file/Y9G24U4r04nEjIDGIEGuKI/PostHog-Design-System-One?node-id=3139%3A1388)
Lemon Icons are generally Material Icons with some matching in-house additions.
Lemon Icons are generally [Material Icons](https://fonts.google.com/icons) with some matching in-house additions.
All should be based on a 24px (1.5rem) square viewbox, with icon contents fitting into a 20px (1.25rem) or smaller square.
When adding new icons from Figma please make sure to:
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/lib/components/icons.tsx
Expand Up @@ -581,6 +581,18 @@ export function IconBarChart(props: SvgIconProps): JSX.Element {
)
}

/** Material Design Area Chart icon. */
export function IconAreaChart(props: SvgIconProps): JSX.Element {
return (
<SvgIcon fill="none" width="1em" height="1em" viewBox="0 0 24 24" {...props}>
<path
d="M3 20V7l4 3 5-7 5 4h4v13Zm5-3 4-5.5 7 5.45V9h-2.7l-3.9-3.125-4.95 6.95L5 11v3.6Z"
fill="currentColor"
/>
</SvgIcon>
)
}

/** Material Design Pie Chart icon. */
export function IconPieChart(props: SvgIconProps): JSX.Element {
return (
Expand Down
21 changes: 12 additions & 9 deletions frontend/src/scenes/insights/InsightDisplayConfig.tsx
Expand Up @@ -24,8 +24,8 @@ import {
isRetentionFilter,
isStickinessFilter,
isTrendsFilter,
isAreaChartDisplay,
} from 'scenes/insights/sharedUtils'

interface InsightDisplayConfigProps {
filters: FilterType
activeView: InsightType
Expand Down Expand Up @@ -55,13 +55,16 @@ const showDateFilter = {
[`${InsightType.PATHS}`]: true,
}

const showComparePrevious = {
[`${InsightType.TRENDS}`]: true,
[`${InsightType.STICKINESS}`]: true,
[`${InsightType.LIFECYCLE}`]: false,
[`${InsightType.FUNNELS}`]: false,
[`${InsightType.RETENTION}`]: false,
[`${InsightType.PATHS}`]: false,
const showCompareFilter = function (filters: Partial<FilterType>): boolean {
if (isTrendsFilter(filters)) {
return !isAreaChartDisplay(filters)
}

if (isStickinessFilter(filters)) {
return true
}

return false
}

const isFunnelEmpty = (filters: FilterType): boolean => {
Expand Down Expand Up @@ -133,7 +136,7 @@ export function InsightDisplayConfig({ filters, disableTable }: InsightDisplayCo
</ConfigFilter>
)}

{filters.insight && showComparePrevious[filters.insight] && (
{showCompareFilter(filters) && (
<ConfigFilter>
<CompareFilter />
</ConfigFilter>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/scenes/insights/Insights.stories.tsx
Expand Up @@ -26,6 +26,8 @@ export const TrendsBar = createInsightScene(require('./__mocks__/trendsBar.json'
export const TrendsBarBreakdown = createInsightScene(require('./__mocks__/trendsBarBreakdown.json'))
export const TrendsValue = createInsightScene(require('./__mocks__/trendsValue.json'))
export const TrendsValueBreakdown = createInsightScene(require('./__mocks__/trendsValueBreakdown.json'))
export const TrendsArea = createInsightScene(require('./__mocks__/trendsArea.json'))
export const TrendsAreaBreakdown = createInsightScene(require('./__mocks__/trendsAreaBreakdown.json'))
export const TrendsNumber = createInsightScene(require('./__mocks__/trendsNumber.json'))
export const TrendsTable = createInsightScene(require('./__mocks__/trendsTable.json'))
export const TrendsTableBreakdown = createInsightScene(require('./__mocks__/trendsTableBreakdown.json'))
Expand Down
197 changes: 197 additions & 0 deletions frontend/src/scenes/insights/__mocks__/trendsArea.json
@@ -0,0 +1,197 @@
{
"id": 18,
"short_id": "Khitkwur",
"name": "",
"derived_name": "Pageview count",
"filters": {
"events": [{ "id": "$pageview", "name": "$pageview", "type": "events", "order": 0 }],
"actions": [],
"display": "ActionsAreaGraph",
"insight": "TRENDS",
"interval": "day",
"properties": [],
"filter_test_accounts": false,
"date_from": "-7d"
},
"filters_hash": "cache_b6d0b194beb8fdc574de3857c4d3de4e",
"order": null,
"deleted": false,
"dashboards": [],
"last_refresh": null,
"refreshing": false,
"result": [
{
"action": {
"id": "$pageview",
"type": "events",
"order": 0,
"name": "$pageview",
"custom_name": null,
"math": null,
"math_property": null,
"math_group_type_index": null,
"properties": {}
},
"label": "$pageview",
"count": 2275.0,
"data": [297.0, 296.0, -282.0, -262.0, 320.0, 290.0, 332.0, 196.0],
"labels": [
"14-Nov-2022",
"15-Nov-2022",
"16-Nov-2022",
"17-Nov-2022",
"18-Nov-2022",
"19-Nov-2022",
"20-Nov-2022",
"21-Nov-2022"
],
"days": [
"2022-11-14",
"2022-11-15",
"2022-11-16",
"2022-11-17",
"2022-11-18",
"2022-11-19",
"2022-11-20",
"2022-11-21"
],
"persons_urls": [
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-14T00:00:00Z",
"date_to": "2022-11-14T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-14T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-14T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-15T00:00:00Z",
"date_to": "2022-11-15T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-15T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-15T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-16T00:00:00Z",
"date_to": "2022-11-16T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-16T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-16T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-17T00:00:00Z",
"date_to": "2022-11-17T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-17T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-17T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-18T00:00:00Z",
"date_to": "2022-11-18T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-18T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-18T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-19T00:00:00Z",
"date_to": "2022-11-19T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-19T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-19T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-20T00:00:00Z",
"date_to": "2022-11-20T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-20T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-20T00%3A00%3A00%2B00%3A00&entity_order=0"
},
{
"filter": {
"entity_id": "$pageview",
"entity_type": "events",
"entity_math": null,
"date_from": "2022-11-21T00:00:00Z",
"date_to": "2022-11-21T00:00:00Z",
"entity_order": 0
},
"url": "api/projects/2/persons/trends/?breakdown_attribution_type=first_touch&breakdown_normalize_url=False&date_from=2022-11-21T00%3A00%3A00%2B00%3A00&display=ActionsAreaGraph&events=%5B%7B%22id%22%3A+%22%24pageview%22%2C+%22type%22%3A+%22events%22%2C+%22order%22%3A+0%2C+%22name%22%3A+%22%24pageview%22%2C+%22custom_name%22%3A+null%2C+%22math%22%3A+null%2C+%22math_property%22%3A+null%2C+%22math_group_type_index%22%3A+null%2C+%22properties%22%3A+%7B%7D%7D%5D&insight=TRENDS&interval=day&smoothing_intervals=1&entity_id=%24pageview&entity_type=events&date_to=2022-11-21T00%3A00%3A00%2B00%3A00&entity_order=0"
}
],
"filter": {
"breakdown_attribution_type": "first_touch",
"breakdown_normalize_url": false,
"date_from": "-7d",
"display": "ActionsAreaGraph",
"events": [
{
"id": "$pageview",
"type": "events",
"order": 0,
"name": "$pageview",
"custom_name": null,
"math": null,
"math_property": null,
"math_group_type_index": null,
"properties": {}
}
],
"insight": "TRENDS",
"interval": "day",
"smoothing_intervals": 1
}
}
],
"created_at": "2022-11-22T12:41:01.902911Z",
"created_by": {
"id": 2,
"uuid": "01849a3b-733c-0000-a2a3-11540809ae0b",
"distinct_id": "EgJxebsiPyI2oROvcrs80YvlCFWc9HSVbQTIMyuFXE5",
"first_name": "Employee 427",
"email": "test@posthog.com"
},
"description": "",
"updated_at": "2022-11-22T12:41:01.902938Z",
"favorited": false,
"saved": true,
"last_modified_at": "2022-11-22T12:41:01.902158Z",
"last_modified_by": {
"id": 2,
"uuid": "01849a3b-733c-0000-a2a3-11540809ae0b",
"distinct_id": "EgJxebsiPyI2oROvcrs80YvlCFWc9HSVbQTIMyuFXE5",
"first_name": "Employee 427",
"email": "test@posthog.com"
},
"is_sample": false,
"effective_restriction_level": 21,
"effective_privilege_level": 37,
"timezone": null,
"tags": []
}

0 comments on commit 7e0524a

Please sign in to comment.