Skip to content

Waterfall Chart ignores field_display_names and leaks internal __wf_lead field into axis title #65

Description

@soh-tetsu

Summary

On Waterfall charts, field_display_names is ignored and the internal window-transform field __wf_lead leaks into the x-axis title. Line/Bar/Area charts apply field_display_names correctly, so this is Waterfall-template–specific.

Verified against flint-chart@0.3.0 (via flint-chart-mcp@0.3.0). Source refs at main (commit 95b2552).

Repro

compile_chart, backend vegalite:

{
  "chart_spec": {
    "chartType": "Waterfall Chart",
    "encodings": { "x": { "field": "week" }, "y": { "field": "wsu_change" } }
  },
  "field_display_names": { "wsu_change": "WSU weekly change", "week": "Week (Mon, JST)" }
}

Observed: compiled spec has "title": "wsu_change" on the y encoding; the x-axis title renders as week, __wf_lead. Neither display name is applied.

Expected: y-axis title "WSU weekly change", x-axis title "Week (Mon, JST)", no internal field in any title.

The same input on Line / Bar / Area charts applies both display names correctly — so the generic assembler path is fine; only the Waterfall template is affected.

Root cause

packages/flint-js/src/vegalite/templates/waterfall.ts, instantiate():

  1. buildVLEncodings (in vegalite/assemble.ts) already writes the display name onto resolvedEncodings.{x,y}.title. The template destructures ctx.resolvedEncodings but discards those titles, hardcoding the raw field name:

    const { x, y, color, column, row } = ctx.resolvedEncodings;
    // ...
    y: {
        field: "__wf_prev_sum",
        type: "quantitative",
        title: yField,          // ← raw field, ignores y.title (the display name)
        ...
    },
  2. The shared xEnc sets no title, so VL auto-derives it from the field. The connector-rule layer adds x2: { field: "__wf_lead" } (also untitled), and VL concatenates every untitled field on the shared x scale into one axis title → "week, __wf_lead".

Suggested fix

Use the titles the assembler already resolved, and suppress internal fields:

const xTitle = x?.title ?? xField;
const yTitle = y?.title ?? yField;

const xEnc = {
    field: xField,
    type: "ordinal" as const,
    sort: null,
    axis: { labelAngle: -45 },
    title: xTitle,                      // was absent
};

// bar layer:
y: { field: "__wf_prev_sum", type: "quantitative", title: yTitle, /* ... */ },

// connector layer — internal fields must never title the shared axis:
x:  { field: xField,      type: "ordinal", sort: null, bandPosition: 0, title: null },
x2: { field: "__wf_lead", bandPosition: 1, title: null },

General guard: any layer encoding bound to a __wf_* / internal field should set title: null (or axis: { title: null }) so VL never surfaces it.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions