0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-21 13:39:22 +01:00

refactor(product-analytics): lineGraphLogic.ts to tooltip-data.ts (#19815)

This commit is contained in:
Michael Matloka 2024-01-17 21:28:10 +01:00 committed by GitHub
parent e6e2a5e1e3
commit 2ad53ef79e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 77 additions and 80 deletions

View File

@ -55,7 +55,7 @@ module.exports = {
// let's save the humans time and let the machines do the work
// "never" means if the prop does not need the curly braces, they will be removed/errored
// see https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-brace-presence.md
"react/jsx-curly-brace-presence": ['error', { "props": "never", "children": "never", "propElementValues": "always" }],
'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never', propElementValues: 'always' }],
'no-console': ['error', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'no-only-tests/no-only-tests': 'error',

View File

@ -38,7 +38,7 @@ const config: StorybookConfig = {
framework: {
name: '@storybook/react-webpack5',
options: { builder: { useSWC: true } }
options: { builder: { useSWC: true } },
},
docs: {

View File

@ -43,8 +43,8 @@ module.exports = {
'scss/at-rule-no-unknown': [
true,
{
'ignoreAtRules': ['tailwind']
}
ignoreAtRules: ['tailwind'],
},
],
'scss/operator-no-newline-after': null, // Doesn't always play well with prettier
'scss/at-extend-no-missing-placeholder': null,

View File

@ -2,27 +2,27 @@
// replaces ts-json-schema-generator -f tsconfig.json --path 'frontend/src/queries/schema.ts' --no-type-check > frontend/src/queries/schema.json
import fs from "fs";
import stableStringify from "safe-stable-stringify";
import tsj from "ts-json-schema-generator";
import fs from 'fs'
import stableStringify from 'safe-stable-stringify'
import tsj from 'ts-json-schema-generator'
/** @type {import('ts-json-schema-generator/dist/src/Config').Config} */
const config = {
...tsj.DEFAULT_CONFIG,
path: "frontend/src/queries/schema.ts",
tsconfig: "tsconfig.json",
discriminatorType: "open-api",
path: 'frontend/src/queries/schema.ts',
tsconfig: 'tsconfig.json',
discriminatorType: 'open-api',
skipTypeCheck: true,
};
}
const output_path = "frontend/src/queries/schema.json";
const output_path = 'frontend/src/queries/schema.json'
const schema = tsj.createGenerator(config).createSchema(config.type);
const stringify = config.sortProps ? stableStringify : JSON.stringify;
const schemaString = (config.minify ? stringify(schema) : stringify(schema, null, 2));
const schema = tsj.createGenerator(config).createSchema(config.type)
const stringify = config.sortProps ? stableStringify : JSON.stringify
const schemaString = config.minify ? stringify(schema) : stringify(schema, null, 2)
fs.writeFile(output_path, schemaString, (err) => {
if (err) {
throw err;
throw err
}
});
})

View File

@ -83,7 +83,17 @@ export function renderColumn(
object[value[i]] = value[i + 1]
}
if ('results' in object && Array.isArray(object.results)) {
return <Sparkline data={object.results} />
// TODO: If results aren't an array of numbers, show a helpful message on using sparkline()
return (
<Sparkline
data={[
{
name: key.includes('__hogql_chart_type') ? 'Data' : key,
values: object.results.map((v: any) => Number(v)),
},
]}
/>
)
}
}

View File

@ -31,8 +31,8 @@ import { insightLogic } from 'scenes/insights/insightLogic'
import { InsightTooltip } from 'scenes/insights/InsightTooltip/InsightTooltip'
import { TooltipConfig } from 'scenes/insights/InsightTooltip/insightTooltipUtils'
import { insightVizDataLogic } from 'scenes/insights/insightVizDataLogic'
import { lineGraphLogic } from 'scenes/insights/views/LineGraph/lineGraphLogic'
import { PieChart } from 'scenes/insights/views/LineGraph/PieChart'
import { createTooltipData } from 'scenes/insights/views/LineGraph/tooltip-data'
import { ErrorBoundary } from '~/layout/ErrorBoundary'
import { themeLogic } from '~/layout/navigation-3000/themeLogic'
@ -278,8 +278,6 @@ export function LineGraph_({
const { insightProps, insight } = useValues(insightLogic)
const { timezone, isTrends } = useValues(insightVizDataLogic(insightProps))
const { createTooltipData } = useValues(lineGraphLogic)
const canvasRef = useRef<HTMLCanvasElement | null>(null)
const [myLineChart, setMyLineChart] = useState<Chart<ChartType, any, string>>()

View File

@ -26,7 +26,7 @@ import {
onChartClick,
onChartHover,
} from 'scenes/insights/views/LineGraph/LineGraph'
import { lineGraphLogic } from 'scenes/insights/views/LineGraph/lineGraphLogic'
import { createTooltipData } from 'scenes/insights/views/LineGraph/tooltip-data'
import { areObjectValuesEmpty } from '~/lib/utils'
import { groupsModel } from '~/models/groupsModel'
@ -84,7 +84,6 @@ export function PieChart({
let datasets = _datasets
const { createTooltipData } = useValues(lineGraphLogic)
const { aggregationLabel } = useValues(groupsModel)
const { highlightSeries } = useActions(insightLogic)
const canvasRef = useRef<HTMLCanvasElement | null>(null)

View File

@ -1,57 +0,0 @@
import { TooltipItem } from 'chart.js'
import { kea, path, selectors } from 'kea'
import { SeriesDatum } from 'scenes/insights/InsightTooltip/insightTooltipUtils'
import { GraphDataset } from '~/types'
import type { lineGraphLogicType } from './lineGraphLogicType'
// TODO: Eventually we should move all state from LineGraph into this logic
export const lineGraphLogic = kea<lineGraphLogicType>([
path(['scenes', 'insights', 'LineGraph', 'lineGraphLogic']),
selectors({
createTooltipData: [
() => [],
() =>
(tooltipDataPoints: TooltipItem<any>[], filterFn: (s: SeriesDatum) => boolean): SeriesDatum[] => {
return tooltipDataPoints
?.map((dp, idx) => {
const pointDataset = (dp?.dataset ?? {}) as GraphDataset
return {
id: idx,
dataIndex: dp.dataIndex,
datasetIndex: dp.datasetIndex,
dotted: !!pointDataset?.dotted,
breakdown_value:
pointDataset?.breakdown_value ??
pointDataset?.breakdownValues?.[dp.dataIndex] ??
undefined,
compare_label:
pointDataset?.compare_label ??
pointDataset?.compareLabels?.[dp.dataIndex] ??
undefined,
action: pointDataset?.action ?? pointDataset?.actions?.[dp.dataIndex] ?? undefined,
label: pointDataset?.label ?? pointDataset.labels?.[dp.dataIndex] ?? undefined,
color: Array.isArray(pointDataset.borderColor)
? pointDataset.borderColor?.[dp.dataIndex]
: pointDataset.borderColor,
count: pointDataset?.data?.[dp.dataIndex] || 0,
filter: pointDataset?.filter ?? {},
}
})
?.sort((a, b) => {
// Sort by descending order and fallback on alphabetic sort
return (
b.count - a.count ||
(a.label === undefined || b.label === undefined ? -1 : a.label.localeCompare(b.label))
)
})
?.filter(filterFn)
?.map((s, id) => ({
...s,
id,
}))
},
],
}),
])

View File

@ -0,0 +1,47 @@
import { TooltipItem } from 'chart.js'
import { SeriesDatum } from 'scenes/insights/InsightTooltip/insightTooltipUtils'
import { GraphDataset } from '~/types'
export function createTooltipData(
tooltipDataPoints: TooltipItem<any>[],
filterFn?: (s: SeriesDatum) => boolean
): SeriesDatum[] {
if (!tooltipDataPoints) {
return []
}
let data = tooltipDataPoints
.map((dp, idx) => {
const pointDataset = (dp?.dataset ?? {}) as GraphDataset
return {
id: idx,
dataIndex: dp.dataIndex,
datasetIndex: dp.datasetIndex,
dotted: !!pointDataset?.dotted,
breakdown_value:
pointDataset?.breakdown_value ?? pointDataset?.breakdownValues?.[dp.dataIndex] ?? undefined,
compare_label: pointDataset?.compare_label ?? pointDataset?.compareLabels?.[dp.dataIndex] ?? undefined,
action: pointDataset?.action ?? pointDataset?.actions?.[dp.dataIndex] ?? undefined,
label: pointDataset?.label ?? pointDataset.labels?.[dp.dataIndex] ?? undefined,
color: Array.isArray(pointDataset.borderColor)
? pointDataset.borderColor?.[dp.dataIndex]
: pointDataset.borderColor,
count: pointDataset?.data?.[dp.dataIndex] || 0,
filter: pointDataset?.filter ?? {},
}
})
.sort((a, b) => {
// Sort by descending order and fallback on alphabetic sort
return (
b.count - a.count ||
(a.label === undefined || b.label === undefined ? -1 : a.label.localeCompare(b.label))
)
})
if (filterFn) {
data = data.filter(filterFn)
}
return data.map((s, id) => ({
...s,
id,
}))
}