formatting-insight-axes

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Formatting insight axes

格式化 insight 轴

PostHog renders insights with a built-in axis formatter. Use it instead of contorting the query or a literal prefix/postfix to fake units.
The two insight kinds configure it in different places:
  • TrendsQuery —
    trendsFilter.aggregationAxisFormat
    (this page, below)
  • SQL insights (
    DataVisualizationNode
    ) — per-column
    settings.formatting
    (see SQL insights)
PostHog 使用内置的轴格式化器渲染 insights。请使用它,而不是通过扭曲查询或使用字面前缀/后缀来伪造单位。
两种 insight 类型在不同位置配置:
  • TrendsQuery —
    trendsFilter.aggregationAxisFormat
    (本页下方)
  • SQL insights(
    DataVisualizationNode
    )— 按列的
    settings.formatting
    (参见 SQL insights)

The anti-pattern

反模式

If you are reaching for any of these, stop and pick a format below first:
  • formula: "A / 60"
    with
    aggregationAxisPostfix: " mins"
    — manual seconds -> minutes
  • formula: "A / 1000"
    with
    aggregationAxisPostfix: " s"
    — manual ms -> seconds
  • formula: "A * 100"
    with
    aggregationAxisPostfix: "%"
    — manual ratio -> percent
  • aggregationAxisPostfix: "ms"
    /
    "s"
    /
    "min"
    /
    "hr"
    on raw values
These freeze the unit at one scale. The built-in formatter picks a friendly unit per value (1.5s, 2m 12s, 1h 4m) and keeps the underlying series numerically correct for further math, breakdowns, and alerts.
如果你准备使用以下任何一种,请停止并先选择下面的格式:
  • formula: "A / 60"
    搭配
    aggregationAxisPostfix: " mins"
    — 手动将秒转换为分钟
  • formula: "A / 1000"
    搭配
    aggregationAxisPostfix: " s"
    — 手动将毫秒转换为秒
  • formula: "A * 100"
    搭配
    aggregationAxisPostfix: "%"
    — 手动将比率转换为百分比
  • 在原始值上使用
    aggregationAxisPostfix: "ms"
    /
    "s"
    /
    "min"
    /
    "hr"
这些做法将单位固定在一个刻度上。内置格式化器会根据每个值选择友好的单位(1.5s、2m 12s、1h 4m),并保持底层序列在数值上正确,以便后续计算、下钻和告警。

Available formats

可用格式

Set
trendsFilter.aggregationAxisFormat
on the TrendsQuery:
ValueUse when the series is...Renders as
numeric
(default)
a plain count
1,234
duration
seconds (any scale)
45s
,
2m 12s
,
1h 4m
duration_ms
milliseconds
850ms
,
1.5s
,
1m 4s
percentage
already 0-100
47.3%
percentage_scaled
a ratio 0-1
47.3%
currency
money in the project's base currency
$1,234.56
(or local code)
short
large counts you want compacted
1.2K
,
3.4M
Companion fields on
trendsFilter
:
  • aggregationAxisPrefix
    — literal prefix (e.g.
    "$"
    ) when you need a symbol pinned to a specific currency or unit, regardless of project settings
  • aggregationAxisPostfix
    — literal suffix; reserve for genuine units the format can't express (e.g.
    " req"
    ,
    " events"
    ), never for
    "mins"
    /
    "s"
    /
    "%"
    — the percentage formats already append the
    %
    sign, so a
    "%"
    postfix renders
    50%%
  • decimalPlaces
    — cap decimals (1 or 2 is usually right for currency / ratios)
在 TrendsQuery 上设置
trendsFilter.aggregationAxisFormat
:
值当序列是...渲染为
numeric
(默认)
普通计数
1,234
duration
秒(任意量级)
45s
,
2m 12s
,
1h 4m
duration_ms
毫秒
850ms
,
1.5s
,
1m 4s
percentage
已经是 0-100
47.3%
percentage_scaled
0-1 的比率
47.3%
currency
项目基础货币中的金额
$1,234.56
(或本地代码)
short
需要紧凑显示的大数字
1.2K
,
3.4M
trendsFilter
上的伴随字段:
  • aggregationAxisPrefix
    — 字面前缀(例如
    "$"
    ),当你需要固定符号到特定货币或单位时使用,无论项目设置如何
  • aggregationAxisPostfix
    — 字面后缀;留给格式无法表达的真实单位(例如
    " req"
    、
    " events"
    ),切勿用于
    "mins"
    /
    "s"
    /
    "%"
    — 百分比格式已经附加了
    %
    符号,所以
    "%"
    后缀会渲染为
    50%%
  • decimalPlaces
    — 限制小数位数(货币/比率通常 1 或 2 位即可)

Currency — pick
format
or
prefix
carefully

货币 — 谨慎选择
format
或
prefix

aggregationAxisFormat: "currency"
renders with the project's base currency (set in project settings, defaults to USD). Use it when the underlying values are in that same currency — e.g. revenue events that PostHog auto-converts to the project's base currency.
If the values are pinned to a specific currency regardless of project (e.g.
$ai_total_cost_usd
is always USD, even on a EUR-base project), use
aggregationAxisPrefix: "$"
+
decimalPlaces: 2
so the symbol matches the data. Using
format: "currency"
here would render USD values with
€
on a EUR project.
aggregationAxisFormat: "currency"
使用项目基础货币(在项目设置中设置,默认 USD)渲染。当底层值使用相同货币时使用它——例如 PostHog 自动转换为项目基础货币的收入事件。
如果值与项目设置无关地固定为特定货币(例如
$ai_total_cost_usd
即使在 EUR 基础货币项目中也始终是 USD),请使用
aggregationAxisPrefix: "$"
+
decimalPlaces: 2
,使符号与数据匹配。在这种情况下使用
format: "currency"
会在 EUR 项目上以
€
渲染 USD 值。

When the series is in seconds

当序列以秒为单位时

If the series is in seconds (latency, session length, time-to-first-event, processing time, page load, etc.), silently default to
aggregationAxisFormat: "duration"
. Do not stop to ask — the formatter is non-destructive (the underlying values stay in seconds either way, only the labels change), so picking it is always at least as good as raw seconds.
Only confirm with the user when they have explicitly named a fixed unit they want pinned ("show this in minutes", "graph the average in hours"):
"I can pin the y-axis to minutes by dividing the series by 60, or use PostHog's
duration
formatter which auto-picks seconds / minutes / hours per value —
90s
renders as
1m 30s
and
5400s
as
1h 30m
. Which would you prefer?"
In one-shot MCP contexts where no user is in the loop, just pick
duration
and move on.
如果序列以秒为单位(延迟、会话时长、首次事件时间、处理时间、页面加载等),请静默地默认使用
aggregationAxisFormat: "duration"
。不要停下来询问——格式化器是非破坏性的(底层值无论哪种方式都保持秒,只是标签变化),所以选择它至少与原始秒值一样好。
只有当用户明确指定了想要固定的单位(“以分钟显示”、“以小时绘制平均值”)时才需要与用户确认:
“我可以通过将序列除以 60 将 y 轴固定为分钟,或使用 PostHog 的
duration
格式化器自动为每个值选择秒 / 分钟 / 小时 —
90s
渲染为
1m 30s
,
5400s
渲染为
1h 30m
。您更倾向于哪种?”
在没有用户参与的 MCP 单次上下文中,直接选择
duration
并继续。

Examples

示例

Latency — duration in milliseconds

延迟 — 毫秒持续时间

json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "$pageview",
      "math": "p95",
      "math_property": "$performance_page_loaded"
    }
  ],
  "trendsFilter": {
    "aggregationAxisFormat": "duration_ms"
  }
}
json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "$pageview",
      "math": "p95",
      "math_property": "$performance_page_loaded"
    }
  ],
  "trendsFilter": {
    "aggregationAxisFormat": "duration_ms"
  }
}

Average session length — duration in seconds

平均会话时长 — 秒持续时间

json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "$pageleave",
      "math": "avg",
      "math_property": "$session_duration"
    }
  ],
  "trendsFilter": {
    "aggregationAxisFormat": "duration"
  }
}
json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "$pageleave",
      "math": "avg",
      "math_property": "$session_duration"
    }
  ],
  "trendsFilter": {
    "aggregationAxisFormat": "duration"
  }
}

Revenue — currency in the project's base currency

收入 — 项目基础货币

json
{
  "trendsFilter": {
    "aggregationAxisFormat": "currency",
    "decimalPlaces": 2
  }
}
json
{
  "trendsFilter": {
    "aggregationAxisFormat": "currency",
    "decimalPlaces": 2
  }
}

Fixed-currency value (e.g. LLM cost in USD) — pin the symbol

固定货币值(例如 LLM 成本以 USD 为单位)— 固定符号

json
{
  "trendsFilter": {
    "aggregationAxisPrefix": "$",
    "decimalPlaces": 2
  }
}
json
{
  "trendsFilter": {
    "aggregationAxisPrefix": "$",
    "decimalPlaces": 2
  }
}

Conversion rate — percentage from a 0-1 formula

转化率 — 从 0-1 公式得到百分比

json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "checkout_completed",
      "math": "dau"
    },
    {
      "kind": "EventsNode",
      "event": "checkout_started",
      "math": "dau"
    }
  ],
  "trendsFilter": {
    "formula": "A / B",
    "aggregationAxisFormat": "percentage_scaled",
    "decimalPlaces": 1
  }
}
json
{
  "kind": "TrendsQuery",
  "series": [
    {
      "kind": "EventsNode",
      "event": "checkout_completed",
      "math": "dau"
    },
    {
      "kind": "EventsNode",
      "event": "checkout_started",
      "math": "dau"
    }
  ],
  "trendsFilter": {
    "formula": "A / B",
    "aggregationAxisFormat": "percentage_scaled",
    "decimalPlaces": 1
  }
}

SQL insights (DataVisualizationNode)

SQL insights (DataVisualizationNode)

SQL insights have no
trendsFilter
. Formatting is per column, on
chartSettings.yAxis[].settings.formatting
for a chart and top-level
tableSettings.columns[].settings.formatting
for a table.
json
{
  "kind": "DataVisualizationNode",
  "source": { "kind": "HogQLQuery", "query": "SELECT week, conversion_rate FROM ..." },
  "display": "ActionsLineGraph",
  "chartSettings": {
    "xAxis": { "column": "week" },
    "yAxis": [
      {
        "column": "conversion_rate",
        "settings": { "formatting": { "style": "percent", "decimalPlaces": 1 } }
      }
    ]
  }
}
style
is
none
,
number
,
short
, or
percent
— no
duration
or
currency
. Express those with
prefix
/
suffix
, or in the SQL itself.
percent
both appends the
%
sign and multiplies the value by 100 (like the trends
percentage_scaled
format; there is no unscaled variant). So feed it a 0-1 ratio and leave
suffix
unset — pick one shape, never a mix:
SQL returns
formatting
Renders
a 0-1 ratio (
a / b
)
{"style": "percent", "decimalPlaces": 1}
47.3%
0-100 (
round(100.0 * a / b, 1)
)
{"style": "number", "suffix": "%", "decimalPlaces": 1}
47.3%
A mix renders broken:
style: "percent"
plus a
"%"
suffix gives
47.3%%
, and
percent
on an already-scaled 0-100 column gives
4730%
. Prefer the ratio form — it keeps the
100.0 *
out of the query, so the stored column stays a plain ratio for anything else that reads it.
SQL insights 没有
trendsFilter
。 格式化是按列的,在
chartSettings.yAxis[].settings.formatting
中用于图表,在
tableSettings.columns[].settings.formatting
中用于表格。
json
{
  "kind": "DataVisualizationNode",
  "source": { "kind": "HogQLQuery", "query": "SELECT week, conversion_rate FROM ..." },
  "display": "ActionsLineGraph",
  "chartSettings": {
    "xAxis": { "column": "week" },
    "yAxis": [
      {
        "column": "conversion_rate",
        "settings": { "formatting": { "style": "percent", "decimalPlaces": 1 } }
      }
    ]
  }
}
style
可以是
none
、
number
、
short
或
percent
— 没有
duration
或
currency
。 可以使用
prefix
/
suffix
,或在 SQL 中自行表达。
percent
既追加
%
符号又将值乘以 100(类似于 trends 的
percentage_scaled
格式;没有未缩放变体)。 因此,请提供 0-1 比率并保持
suffix
未设置 — 只选一种形式,不要混用:
SQL 返回
formatting
渲染
0-1 比率(
a / b
)
{"style": "percent", "decimalPlaces": 1}
47.3%
0-100(
round(100.0 * a / b, 1)
)
{"style": "number", "suffix": "%", "decimalPlaces": 1}
47.3%
混用会渲染错误:
style: "percent"
加上
"%"
后缀会产生
47.3%%
,而在已经是 0-100 的列上使用
percent
会产生
4730%
。 优先采用比率形式 — 它可以将
100.0 *
移出查询,使存储的列保持为纯比率,供其他读取使用。

Updating an existing insight

更新现有 insight

If an insight you are already editing uses one of these anti-patterns — a trends
formula
/
postfix
pair, or a SQL column with both
style: "percent"
and a
"%"
suffix — fix it in the same
posthog:insight-update
call: drop the divide-by-N or
100.0 *
and the literal
%
, and let the format own the unit. Values stay the same, only labels change. Do not scan unrelated insights — fix only the ones you are already touching.
如果你正在编辑的 insight 使用了这些反模式之一 — trends 的
formula
/
postfix
配对,或 SQL 列同时具有
style: "percent"
和
"%"
后缀 — 在相同的
posthog:insight-update
调用中一并修复:删除除以 N 或
100.0 *
以及字面
%
,让格式本身拥有单位。值保持不变,仅标签变化。不要扫描不相关的 insights — 只修复你正在触达的那些。