cd /news/ai-tools/datachat-free-zero-dependency-java-t… · home › topics › ai-tools › article
[ARTICLE · art-153635] src=github.com ↗ pub= topic=ai-tools verified=true sentiment=↑ positive

DataChat – Free, zero-dependency Java tool ask questions with Claude/Offline AI

DataChat, a single-file Java Swing desktop application with no external dependencies, lets users ask plain-English questions about CSV files and receive an answer plus a chart, using Anthropic's Claude API or a built-in offline rule-based engine. The tool requires Java 17 or newer, runs via `java DataChat.java`, and ships with demo data of 2,317 synthetic financial transactions from January to June 2026; the Claude API key is held in memory only and never written to disk.

read16 min views1 publishedOct 20, 2026
DataChat – Free, zero-dependency Java tool ask questions with Claude/Offline AI
Image: Michielbdejong (auto-discovered)

Ask your CSV questions in plain English and get an answer plus a chart.

No pivot tables, no remembering which formula does what. Load a CSV and type things like:

  • "What's driving the drop in March?"
  • "Chart the financial transactions by region"
  • "Monthly revenue by category, excluding refunded"
  • "Share of revenue by channel as a pie chart"

DataChat is a single-file Java Swing desktop app with no external dependencies. It works with Claude (Anthropic API) for natural-language understanding, and it also ships with a built-in offline engine and demo data so you can try it without an API key.

Requirements: Java 17 or newer (JDK for the commands below).

java DataChat.java

javac DataChat.java
java DataChat

The app opens with demo data already loaded, so you can click an example question straight away.

Either paste your API key into the Claude API key field in the toolbar, or set environment variables before launching:

export ANTHROPIC_API_KEY="sk-ant-..."
export ANTHROPIC_MODEL="claude-sonnet-5-5"   # optional; this is the default
java DataChat.java

The key is held in memory only and is never written to disk. Without a key (or with Offline mode ticked) the built-in rule-based engine answers instead.

Area What it does
Toolbar Two rows. Top: Load CSV... ,Demo data andExport PDF report... (greyed out until you've asked a question). Bottom: Claude API key, model name, Offline mode and the sample-rows privacy toggle
Chat (left) Your questions, the analyst's plain-English answers, the auto-insights for the loaded file, and clickable example questions
Chart tab The chart(s) for the latest answer. Hover for exact values. Save chart as PNG... exports it
Result table tab The exact numbers behind the answer. Save result as CSV... exports them (seeExporting results )
Your data tab A scrollable view of the loaded CSV
How it was computed tab The JSON plan that was executed, how many rows were used, and the computed facts

The status bar shows the loaded file, row and column counts, and which engine is active (Claude or offline).

  • Click Load CSV... , ordrag and drop a.csv ,.tsv or.txt file onto the window.
  • Click Demo data to load (or reload) the built-in sample.

The demo is 2,317 synthetic financial transactions from January to June 2026 with these columns: TransactionID, Date, Region, Category, Channel, Status, Amount.

It contains a deliberate story: March dips because the North region (store closures) and the Hardware category (supply shortage) sell much less. Ask "What's driving the drop in March?" and the analysis should surface exactly those two.

As soon as a file loads, DataChat scans it and posts a short list of things worth a closer look in the chat. Each line ends with an explore link: click it and the full analysis (table, charts and explanation) runs immediately, with no typing.

Insight What triggers it
Biggest drop The largest period-on-period fall in the main measure, if it is at least 10%. Explore runs the driver analysis for exactly those two periods
Biggest rise The same for the largest increase
Over-indexing segment A segment whose share of the measure differs from its share of rows by at least 10 points, for example "Services is 16% of rows but 33% of Total Amount" . When the table has no numeric column it flags a segment that makes up at least half of all rows
Unusual values Values above Q3 + 3 x IQR in the main numeric column (shown only if they are under 5% of rows)
Overall trend The change from the first to the last period, if it is at least 5%
Missing data A column that is at least 20% empty

At most five insights are shown, in that priority order. Details:

  • The "main measure" is the first numeric column whose name looks like money (amount, revenue, sales, price, cost, profit... ), otherwise the first numeric column. With no numeric columns, insights count rows instead.
  • A last month that stops part-way through is ignored when looking for drops, so an incomplete month never shows up as a fake slump.
  • Insights are computed locally, so they never call the API. Clicking explore does use Claude for the explanation if a key is set.
  • The insights are also printed in the PDF report .

Click Export PDF report... (top row of the toolbar, next to Demo data) to save everything you've asked in the current session as a single A4 document. The button is greyed out until you've asked at least one question.

The report contains:

  1. A title block with the dataset name, row and column counts, the date, and the column list.
  2. The Key insights found on load.
  3. For every question, in order: the question, the plain-English answer, how many rows were used and any filters applied, the chart(s), and the result table (first 25 rows).

Notes:

  • a new file starts a fresh session, so the report only covers the current dataset.
  • Charts are embedded as images and tables are real selectable text. Long tables continue across pages with the header repeated.
  • The writer is built into the program (no PDF library), using the standard Helvetica fonts. Characters outside Western European text, such as Chinese, Cyrillic or Arabic, appear as ? .
  • For the complete table behind an answer, use Save result as CSV... .

Open the Result table tab and click Save result as CSV... to save the table behind the latest answer. The button is greyed out until you've asked a question.

  • The suggested file name comes from the answer's title.
  • Numbers are written as plain values (12503.58 , not+12,503.58 ) so they open cleanly in Excel, Numbers or Google Sheets. Percentage columns such as-59.4% stay as text.
  • The file is UTF-8 with a byte-order mark, which Excel needs to display non-ASCII characters correctly, and fields containing commas, quotes or line breaks are quoted.
  • The chart isn't part of the CSV. Use Save chart as PNG... for that.

Type in the box at the bottom of the chat and press Enter (or click Ask). With Claude enabled, follow-ups can build on the previous question, for example "now split that by channel" or "only for North". The last three turns are sent as context.

Ask You get
Chart the financial transactions by region Bar chart of total Amount per Region
Monthly revenue by category Multi-line chart, one line per Category
What's driving the drop in March? Trend chart plus a ranked breakdown of which segments caused the change
Why did revenue rise in May? Same analysis for an increase
Compare February and March Driver analysis between two named periods
Share of revenue by channel as a pie chart Pie chart with percentages
Average amount by category, excluding refunded Filtered average per Category
How many transactions per month? Row counts over time
Revenue by weekday Totals for Mon to Sun
Show amount by region for Q2 Date-filtered totals
Top 5 largest transactions The five biggest rows, as a table
Describe this data Column-by-column overview

DataChat splits the problem so that the language model never has to do arithmetic:

 your question
      |
      v
 1. PLAN      Claude reads the question + a compact schema of your table
              and replies with a small JSON "analysis plan".
      |
      v
 2. EXECUTE   The app runs that plan itself on the FULL dataset
              (filter, group, aggregate, compare), so numbers are exact.
      |
      v
 3. EXPLAIN   Claude writes a short plain-English answer from the
              computed result table; the app draws the chart.

Why this design:

  • Accuracy. Every number comes from Java code running over all your rows, not from a model's estimate.
  • Privacy. Claude sees the schema and the small aggregated result, not your raw rows (seePrivacy ).
  • Transparency. TheHow it was computed tab shows the exact plan that ran, so you can verify the answer.
  • Graceful fallback. If the API call fails, the app falls back to the offline engine and tells you.

For the planning call:

  • The table name, row count and, for each column, its type :NUMBER ,DATE orTEXT .
  • Per column: numeric min, max and mean; date range; or the distinct values of text columns (up to 25, otherwise a few examples).
  • Optionally the first 3 rows (only if Send sample rows to AI is ticked).
  • The last three question/plan pairs, and today's date.

For the explanation call: your question, the executed plan, the computed facts, and at most the first 30 rows of the result table.

Both calls go to https://api.anthropic.com/v1/messages using Java's built-in HttpClient.

Claude (or the offline planner) produces one JSON object. The engine executes it.

{
  "intent": "aggregate",
  "title": "Total Amount by month and Category",
  "metric": "Amount",
  "agg": "sum",
  "x": "Date",
  "bucket": "month",
  "series": "Category",
  "filters": [{ "column": "Status", "op": "!=", "value": "Refunded" }],
  "sort": "none",
  "limit": null,
  "chart": "line"
}
Field Meaning
intent aggregate (group + chart),drivers (explain a change),rows (list individual rows),describe (column overview)
metric Numeric column to measure, or null to count rows
agg sum ,avg ,count ,min ,max ,median
x Column for the x-axis or grouping ( null = one overall number)
bucket For date columns: day ,weekday ,week ,month ,quarter ,year (auto-chosen from the date span if omitted)
series Optional second grouping, drawn as separate colours (max 8 series)
filters column ,op (= ,!= ,> ,< ,>= ,<= ,contains ,in ,not in ) andvalue . Date filters accept partial ISO dates like2026-03
sort /limit Ordering and top-N. Categories default to descending by value; large category sets are capped at 20
chart bar ,line ,pie ,none (omitted means auto)
from /to /direction For drivers : the periods to compare (for example2026-02 ,2026-03 ) and whether to look for adrop or arise

Chart choice when chart is auto: time on the x-axis gives a line (or bars for very few points), categories give bars (horizontal when there are many or the labels are long), and pie is used only when requested with up to 10 positive slices.

If a column name in a plan doesn't match exactly, the engine tries case-insensitive and fuzzy matching, and otherwise reports the available columns.

For questions like "what's driving the drop in March?" the engine:

  1. Buckets the data by period (month by default) and totals the measure for each.
  2. Picks the periods to compare. A single named period is compared with the one before it. If none is named, it finds the largest period-on-period drop (or rise).
  3. For every text column with 2 to 40 distinct values, computes each segment's value in both periods.
  4. Ranks segments by their excess movement : how far they moved beyond what they'd have done if they had followed the overall trend. This stops large, stable segments (such asStatus = Completed , which is most of the data) from topping the list just because they are big.
  5. Also checks two-way combinations (for exampleRegion = North & Category = Hardware ) and keeps only those that moved clearly more (at least 10 percentage points) than both of their parts.
  6. Reports segments that lagged the trend or moved the opposite way, and splits the change into row count vs average value per row .

You get two charts: the trend with both periods highlighted, and a horizontal bar chart of each segment's change (green up, red down). The result table shows each segment's change, percentage change and share of the total change. Shares are computed within each dimension separately, so they can overlap across dimensions.

If the final period in the data stops mid-month, the answer warns that it may be incomplete.

  • Your CSV is read and processed locally . Aggregation, filtering and charting all happen in Java on your machine.
  • Claude only ever receives the schema summary, the aggregated result table (30 rows at most), and, only if you tick "Send sample rows to AI" , the first three data rows.
  • Text-column summaries include distinct values (up to 25 per column), so avoid using Claude with columns whose values are sensitive, or useOffline mode .
  • In Offline mode nothing leaves your machine.

With no API key (or Offline mode ticked), a built-in rule-based planner turns your question into the same JSON plan. It understands:

  • Measures: column names mentioned in the question, plus words likeaverage, median, max, min, how many, count . If you don't name a measure, it picks the most money-like numeric column and says so.
  • Grouping:* by, per, each, across* , column names (and their plurals), and time words such asmonthly, per week, over time, trend, weekday .
  • Filters: category values appearing in the question (North ,Hardware ), exclusions (excluding refunded ,without retail ), and dates (in March ,Q2 ,2026 ).
  • Ranking and charts:* top 5, bottom 3, lowest, best* , andpie / line / bar .
  • Change questions:* drop, fell, decline, rise, why, driving, compare X and Y* .

It's good for exploring and for demos. It is keyword-based, so unusual phrasing and conversational follow-ups work best with Claude enabled.

  • Delimiters are auto-detected: comma, semicolon, tab or pipe. Quoted fields and escaped quotes are supported.

  • Encoding: UTF-8 (BOM handled), with a fallback to Windows-1252 if invalid bytes are found.

  • Numbers: currency symbols, thousands separators and percent signs are stripped ($1,200.50 ,£99 ,12% ), and(20) is read as-20 .

  • European number formats are detected per column:1.234,56 ,12,5 ,1 234,5 € and(300,40) are all read correctly. A value like1.234.567,89 or12,5 counts as European evidence and one like1,234.56 or1,234,567 as US evidence. Values that could be either (1,234 or1.200 on their own) follow the rest of the column, then the rest of the file, and default to US style if there is no evidence anywhere. Dotted dates such as01.03.2026 are still recognised as dates, not numbers. If an ambiguous column is read the wrong way, give it one unambiguous value (for example1.200,00 ) or reformat the file.

  • Dates: auto-detected fromyyyy-MM-dd ,yyyy-MM ,yyyy/MM/dd ,d/M/yyyy (day first is tried before month first),M/d/yyyy ,d-M-yyyy ,d.M.yyyy , andd MMM yyyy /MMM d, yyyy styles. A time portion is ignored.

  • Type detection: a column isNUMBER orDATE if at least 95% of its non-empty values parse. Columns named like IDs (Customer ID ,OrderID ,zip ,phone ) are kept as text so they aren't summed.

  • Blank headers become Column N , and duplicate headers get a numeric suffix.

  • The data is held in memory, so very large files (millions of rows) will need a bigger heap (java -Xmx4g ... ).

  • Only one table at a time. There are no joins across files.

  • Day-first dates are assumed when a column is ambiguous (for example 03/04/2026 with no day above 12).

  • Number columns whose every value is ambiguous (only 1,234 -style or1.200 -style values, in a file with no other evidence) are read as US numbers.

  • Stacked charts and multiple y-axes aren't supported. Multi-series data is drawn as grouped bars or multiple lines.

  • Driver analysis considers text columns (up to 40 distinct values each) and two-way combinations of columns with up to 12 values. Numeric columns aren't used as dimensions.

  • The offline engine can't resolve follow-ups that depend on the previous question.

  • The PDF report uses built-in fonts and only covers Western European characters.

  • A language model can occasionally misread a question. Check the How it was computed tab if an answer surprises you.

Problem Fix
Status bar says offline engine No API key entered, or Offline mode is ticked
Note says Claude's plan could not be used The API returned an error (bad key, wrong model name, no network) or an invalid plan. The message includes the HTTP error. The answer came from the offline engine
I couldn't find a column called ... The plan referenced a column that doesn't exist. Rephrase using the column names listed in the chat
... isn't numeric You asked to sum or average a text or date column. Use a numeric column, or count instead
Dates not recognised Check the Your data tab and theDescribe this data answer to see the detected type. Reformat the column asyyyy-MM-dd
Garbled characters Re-save the file as UTF-8
Out of memory Launch with a larger heap: java -Xmx4g DataChat.java
Numbers read 1000x too small or large A 1.200 or1,234 column was read in the wrong style. SeeEuropean number formats underCSV handling
No auto-insights appear Nothing in the data crossed the thresholds (for example fewer than 3 time periods), or the file has no date or numeric columns. Ask questions as usual
? characters in the PDF The text contains characters outside Western European encodings, which the built-in PDF fonts can't show

Everything lives in DataChat.java, organised as nested classes:

Class Responsibility
DataChat Swing UI: toolbar, chat transcript, tabs, drag and drop, background SwingWorker tasks
DataTable ,Column In-memory table, CSV parsing, type detection ( NUMBER /DATE /TEXT ), schema description for the model
Plan ,Filter The analysis plan, with JSON conversion
Engine Executes a plan: filtering, grouping, aggregation, driver analysis, fact generation
Result ,ChartData Output of the engine: table rows, chart specs, plain-English facts
LocalPlanner Offline natural-language to plan translation, and offline answer text
Claude Anthropic Messages API client plus the planner and explainer system prompts
Json Minimal JSON reader and writer (no libraries)
ChartPanel Java2D chart rendering: bar, horizontal bar, line, pie, with tooltips. Also used to render charts into the PDF
Insights ,Insight The on-load scan: biggest drop and rise, over-indexing segments, outliers, trend and missing data. Each insight carries a ready-made Plan
Pdf ,ReportBuilder Minimal PDF 1.4 writer (text, rules, JPEG images, Flate-compressed pages) and the report layout
DemoData Synthetic transactions generator and example questions
  • New aggregation: add it toAcc.get ,Engine.aggOf andmeasureLabel , and mention it inClaude.PLAN_SYSTEM .
  • New time bucket: add a case inEngine.bucketLabel and the allowed set inEngine.bucketOf .
  • New chart type: add aChartType , a paint method inChartPanel , and a rule inEngine.chartType .
  • New insight: add a method toInsights that builds anInsight(headline, plan) and call it fromInsights.generate . The plan runs through the normal engine when the user clicksexplore .
  • Report layout: editReportBuilder.build ; thePdf helper offerspara ,table ,image ,rule and automatic page breaks.
  • Different model: change theModel field or setANTHROPIC_MODEL .
  • Your own demo data: editDemoData.create() andDemoData.examplesFor() .
── more in #ai-tools 4 stories · sorted by recency
── more on @datachat 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/datachat-free-zero-d…] indexed:0 read:16min 2026-10-20 · —