Skip to content
Web > Charts > Chart Type Walkthroughs > Cartesian

Gantt Chart of Batch Jobs

Known issues

Some chart features have known issues in the current release. See Known issues.

This walkthrough draws a timeline of batch jobs, one bar per job from its start to its end time, answering "Which jobs overlapped, and which ran late?"

Prerequisites

  • Editor mode: click once on the screen, then press Ctrl+d. The AMIDB Shell Tool and the gallery are used as in the quickstart.
  • Data: the example data that stage 1 creates. To use a table of your own instead, see With your own data.

1. Create the example data

The chart reads a table in the Center, so create the table first.

  1. Select Dashboard -> AMIDB Shell Tool....
  2. Run:

    1
    2
    3
    4
    5
    6
    7
    CREATE PUBLIC TABLE ChartDemoJobs (Job String, StartTime UTC, EndTime UTC, Status String);
    INSERT INTO ChartDemoJobs VALUES
     ("Load prices", parseDate("2026-10-21 06:00", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 06:40", "yyyy-MM-dd HH:mm", "EST5EDT"), "Done"),
     ("Reconcile", parseDate("2026-10-21 06:30", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 07:50", "yyyy-MM-dd HH:mm", "EST5EDT"), "Done"),
     ("Risk run", parseDate("2026-10-21 07:00", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 08:30", "yyyy-MM-dd HH:mm", "EST5EDT"), "Late"),
     ("Reports", parseDate("2026-10-21 08:30", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 09:00", "yyyy-MM-dd HH:mm", "EST5EDT"), "Done");
    SELECT * FROM ChartDemoJobs;
    
  3. Check that the lower pane shows the 4 rows.

The times are stored in New York time, the default user time zone.

2. Create the chart

The gallery creates a datamodel that reads the table, then places the chart.

  1. Select Windows -> New Window, then the edit button on Blank1, then "Create Table / Visualization / Form".
  2. Select "AMI (__AMI)", then "Next >>".
  3. Select the "USER" tile ChartDemoJobs, then "Next >>".
  4. Select "Test (alt+enter)", then "Next >>".
  5. Select the "Cartesian" tab, then the "Gantt" tile.
  6. Set the fields below the tiles:

    Field Value
    "Task:" Job
    "Start:" StartTime
    "End:" EndTime
    "Bar label:" Status
  7. Select "Finish".

  8. Check that the window shows 4 bars between 6:00 and 9:00, each labeled "Done" or "Late".

Result

4 bars, one per job, in the order of the rows from the bottom: "Load prices", "Reconcile", "Risk run", and "Reports". "Risk run", 7:00 to 8:30, is labeled "Late".

To check without looking, read the render stats: session.getDevTools().getAllRenderStats() in the AMIDB Shell Tool, with "Run on this web session" selected (see Running a script), or web_debug op=panelRenderStats over MCP. The "Bars" layer reports Rows 4, "4 groups", and an empty Problem.

With your own data

If your table holds a deadline per job rather than a status, shape the rows in the datamodel's query. To try it on example rows, run this in the AMIDB Shell Tool first:

1
2
3
4
5
6
CREATE PUBLIC TABLE ChartDemoJobRuns (Job String, StartTime UTC, EndTime UTC, Deadline UTC);
INSERT INTO ChartDemoJobRuns VALUES
 ("Load prices", parseDate("2026-10-21 06:00", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 06:40", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 07:00", "yyyy-MM-dd HH:mm", "EST5EDT")),
 ("Reconcile", parseDate("2026-10-21 06:30", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 07:50", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 08:00", "yyyy-MM-dd HH:mm", "EST5EDT")),
 ("Risk run", parseDate("2026-10-21 07:00", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 08:30", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 08:00", "yyyy-MM-dd HH:mm", "EST5EDT")),
 ("Reports", parseDate("2026-10-21 08:30", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 09:00", "yyyy-MM-dd HH:mm", "EST5EDT"), parseDate("2026-10-21 09:30", "yyyy-MM-dd HH:mm", "EST5EDT"));

Remove it afterwards with DROP TABLE ChartDemoJobRuns;.

  1. Follow stage 2 with the "USER" tile ChartDemoJobRuns, or the one for your own table, in place of ChartDemoJobs.
  2. When the gallery shows the datamodel's query, replace the query with:

    1
    2
    3
    {
      CREATE TABLE ChartDemoJobs AS EXECUTE SELECT Job, StartTime, EndTime, (EndTime > Deadline ? "Late" : "Done") AS Status FROM ChartDemoJobRuns WHERE ${WHERE} ORDER BY StartTime;
    }
    
  3. Select "Test (alt+enter)".

  4. Check that the "Tables" tab shows ChartDemoJobs alone, with the same 4 rows as the example table in stage 1, "Risk run" marked "Late".

Then continue with stage 2: the fields are the same, and any later stages apply as written. To do this over MCP, put the same statements in the onProcess of the datamodel that step 1 of "Over MCP" imports, with USE ds="AMI" before each EXECUTE.

The query marks a job "Late" when it ends after its deadline, and sorts the jobs by start time. After stage 2, to show them in that order with the earliest at the top:

  1. Open "Edit Axis" on the task axis, the vertical one.
  2. "Sub-Title Ordering:" already reads "Original", set by the template, so the bars follow the rows from the bottom. Select "Ordering:" once, so that it reads "Ascending".
  3. Select "Close".
  4. Check that the bars run "Load prices", "Reconcile", "Risk run", and "Reports" from the top.

Over MCP, set the same 2 options on the chart's left axis with web_execute op=updatePanel: "isGroupOrdered": false and "flip": true.

Over MCP

An agent builds the same chart from the same table. Connecting an agent is covered in the AI section; the tools are on Building charts over MCP.

  1. Create the datamodel with web_execute op=importDatamodel and this dmJson, then run it once with op=initDatamodelSchema and dmName ChartDemoJobs:

    {"id": "ChartDemoJobs", "queryMode": "startup", "callbacks": [{"name": "onProcess", "amiscript": ["{ CREATE TABLE ChartDemoJobs AS USE ds=\"AMI\" EXECUTE SELECT * FROM ChartDemoJobs; }"]}]}
    
  2. Create the chart:

    {"windowName": "ChartDemoGantt", "templateKey": "tplGantt", "datamodelId": "ChartDemoJobs", "dmTable": "ChartDemoJobs", "title": "ChartDemoGantt", "bindings": "{\"CAT\": \"Job\", \"START\": \"StartTime\", \"END\": \"EndTime\", \"LBL\": \"Status\"}"}
    
  3. Run the datamodel again with web_execute op=executeDatamodel, dmName ChartDemoJobs. A chart created over MCP can stay empty until its datamodel runs again, with its axes at 0-100.

  4. Confirm that every layer reports the rows above and an empty Problem: run web_debug op=panelRenderStats.

The call is web_create_chart_from_template.

Removing the example

Remove the chart, then its datamodel, then the table, so that the next walkthrough can reuse the names:

  1. Close the chart's window with its close button, and select "Delete" when asked whether to delete the panel.
  2. Select Dashboard -> Data Modeler..., expand "Datamodels", right-click the chart's datamodel, ChartDemoJobs, and select "Delete Datamodel", then "Yes". If that name was taken when stage 2 ran, the gallery added a number to it, as in ChartDemoJobs1.
  3. Run DROP TABLE ChartDemoJobs; in the AMIDB Shell Tool.
  4. Check that SELECT * FROM ChartDemoJobs; reports Unknown table: ChartDemoJobs.

Over MCP, delete the chart with web_danger op=deletePanel, then the datamodel with op=deleteDatamodel, dmName ChartDemoJobs, and drop the table as in step 3. deleteDatamodel refuses a datamodel that has been committed; delete that one in the Data Modeler as in step 2. See Removing an agent's chart.