Skip to content
Expedify
4 min

Smart Charts

Hand it an array of records and it picks the chart. No prompt, no model, no chart-type argument — it reads the shape of your data and decides. What it can draw, and what it does when it cannot.

Every other node in this module changes something in your CRM. This one draws a picture of it. Give it rows — from a Database Query, a Sheets pull, an API response — and it returns chart JSON: which chart to use, the series to plot, and a summary of what it found.

The interesting part is what it does not ask you. There is no chart-type setting. You do not tell it which column is the axis. It looks at the array, works out which columns are categories, which are dates and which are numbers, and picks accordingly — a bar chart for categories against a metric, a line for anything over time, a pie for parts of a whole.

That decision is made by rules, not by a model. No prompt is sent anywhere, nothing is billed as a completion, and the same data produces the same chart every time. In a path full of AI nodes, this one is worth noticing precisely because it is not one.

One field that matters, six that mostly do not

The defaults are the recommended values. Reach for the rest when a chart comes out wrong, not before.

data_input

What it holds
Data input - supports template variables like {{namespace.response.data}}

max_rows

What it holds
Maximum rows to process Defaults to 10000.

max_categories

What it holds
Maximum categories to show in each chart before grouping rest into 'Others' Defaults to 10.

max_charts

What it holds
Maximum number of charts to generate when multi_chart is enabled Defaults to 5.

auto_aggregate

What it holds
Automatically aggregate large datasets Defaults to true.

multi_chart

What it holds
Generate multiple charts (when off, only generates 1 chart) Defaults to true.

include_summary

What it holds
Include statistical summary with charts Defaults to true.

data_input is the node. It takes a template reference to an array of records from upstream — rows from a query, items from an API response, anything that resolves to a list of objects with the same keys. If that resolves, the node works; if it resolves to something else, nothing else you configure will save it.

Of the other six, two change what you get rather than how it is computed. multi_chart is on by default and produces one chart per categorical column, up to max_charts; turn it off when you want exactly one picture. max_categories caps how many slices or bars appear before the rest are grouped into an Others bucket — which is why a pie chart of fifty stages does not come back with fifty wedges.

A worked example

Monday morning, count the deals in each stage and chart them. The query does the grouping; the chart node does not need to be told that stage is the category and the count is the metric.

The pipeline, once a week

A query, then the chart. Note that nothing in the last node names a column.

Scroll for all 3 steps →

Two things in that diagram carry the lesson. result_format on the query is set to return an array of objects — that is the shape Smart Charts expects, and a query returning anything else gives it nothing to read. And multi_chart is off, because this workflow wants one picture of the pipeline rather than one per column.

What comes back, and who renders it

{{alias.chart_data}}

What you get
The series, ready to plot. This is the field a renderer consumes.

{{alias.chart_type}}

What you get
Which chart it chose — bar, line or pie. Worth logging while you are still learning what it does.

{{alias.chart_config}}

What you get
Axis labels, colours and the rest of the display config.

{{alias.data_summary}}

What you get
Row counts and the column types it detected. The first thing to read when a chart looks wrong.

{{alias.response_components}}

What you get
The chart packaged as a component, for surfaces that take one directly.

This node draws nothing on its own. It produces JSON, and something downstream renders it — a Response Builder pointed at {{alias.chart_data}} puts a live chart in the chat interface. Smart Charts upstream, Response Builder downstream, is the standard pair. A workflow that ends at Smart Charts has computed a chart nobody can see.

What breaks

Nothing chartable. If no column in the array is numeric, categorical or temporal — a list of ids and free-text notes, say — the node returns a NO_CHARTABLE_DATA error rather than an empty chart. That is the honest behaviour, and the fix is upstream: select a column worth counting.

The wrong shape. The commonest failure is not the chart, it is data_input resolving to a single object, a string of JSON, or a wrapper around the array rather than the array itself. data_summary tells you what arrived; read it before adjusting anything else.

A chart of raw rows. Handing over ten thousand unaggregated rows works — auto_aggregate groups them — but the chart it produces is a chart of whatever grouping the node inferred. If you know what you want counted, count it in the query. A GROUP BY upstream produces a better picture than any setting on this node.

This, or a dashboard chart?

A chart in Analytics

When
The picture is a permanent one people go and look at. It is saved, shared, filtered and refreshed on its own.

smart_chart

When
The picture is part of something happening — an answer in a chat, a weekly digest, a reply to a question someone just asked. It exists for one run.

Reach for a dashboard when the same question gets asked every week by the same people. Reach for this node when the question arrived inside a workflow and the answer is better as a picture than as a number.

Try it

  1. Add a Database Query with a GROUP BY — anything that returns a category and a count — and set its result format to an array of objects.
  2. Add a Smart Chart after it and point data_input at the query's output. Run it and read {{alias.chart_type}} to see what it chose.
  3. Change the query to return a date column instead of a category, and run it again. The chart type should change with it — that is the rule engine doing its job.
  4. Now point data_input at a node that returns one record rather than an array, and read the error. It is the failure you will actually hit.

Next: Text Response — the first node in the messaging module, and the simplest way a workflow says something back.

Related lessons