When Malloy runs a query, it returns two things. The results of the query and metadata about the results. The metadata are the schema for the results, including type information. Malloy also provides a mechanism to tag things in the source code and return tags with this meta data.
In Malloy, anything that can be named can be tagged. A tag starts with a #
. Tags that start on a new line attach the tag the thing on the following line. For more details about how tagging works, see the Tags section.
Malloy's rendering library interprets these tags to change how results are rendered.
Tagging individual elements
In the query below, the measure percent_of_total
is tagged as a percentage. Any time percent_of_total
is used in a query, Malloy's rendering library will be displayed as a percentage.
source: flights is duckdb.table('../data/flights.parquet') extend { measure: flight_count is count() # percent percent_of_flights is flight_count / all(flight_count) }
run: flights -> { group_by: carrier aggregate: flight_count percent_of_flights }
[ { "carrier": "WN", "flight_count": 88751, "percent_of_flights": 0.2573783375431738 }, { "carrier": "US", "flight_count": 37683, "percent_of_flights": 0.10928088577750582 }, { "carrier": "AA", "flight_count": 34577, "percent_of_flights": 0.10027347046489979 }, { "carrier": "NW", "flight_count": 33580, "percent_of_flights": 0.09738216554968143 }, { "carrier": "UA", "flight_count": 32757, "percent_of_flights": 0.09499546149228454 }, { "carrier": "DL", "flight_count": 32130, "percent_of_flights": 0.09317715840116929 }, { "carrier": "RU", "flight_count": 16074, "percent_of_flights": 0.046614679244954715 }, { "carrier": "MQ", "flight_count": 15869, "percent_of_flights": 0.046020178234302996 }, { "carrier": "EV", "flight_count": 15769, "percent_of_flights": 0.04573017774130216 }, { "carrier": "HP", "flight_count": 9750, "percent_of_flights": 0.028275048067581715 }, { "carrier": "AS", "flight_count": 8453, "percent_of_flights": 0.024513741673360845 }, { "carrier": "CO", "flight_count": 7139, "percent_of_flights": 0.020703135195329833 }, { "carrier": "B6", "flight_count": 4842, "percent_of_flights": 0.01404182387110058 }, { "carrier": "OH", "flight_count": 4420, "percent_of_flights": 0.012818021790637044 }, { "carrier": "TZ", "flight_count": 3033, "percent_of_flights": 0.00879571495271542 } ]
WITH __stage0 AS ( SELECT group_set, CASE WHEN group_set=1 THEN base."carrier" END as "carrier__1", CASE WHEN group_set=1 THEN COUNT(1) END as "flight_count__1", (CASE WHEN group_set=1 THEN COUNT(1) END)*1.0/MAX((CASE WHEN group_set=0 THEN COUNT(1) END)) OVER () as "percent_of_flights__1" FROM '../data/flights.parquet' as base CROSS JOIN (SELECT UNNEST(GENERATE_SERIES(0,1,1)) as group_set ) as group_set GROUP BY 1,2 ) SELECT "carrier__1" as "carrier", MAX(CASE WHEN group_set=1 THEN "flight_count__1" END) as "flight_count", MAX(CASE WHEN group_set=1 THEN "percent_of_flights__1" END) as "percent_of_flights" FROM __stage0 WHERE group_set NOT IN (0) GROUP BY 1 ORDER BY 2 desc NULLS LAST
run: duckdb.table('../data/flights.parquet') -> { group_by: carrier aggregate: flight_count is count() }
[ { "carrier": "WN", "flight_count": 88751 }, { "carrier": "US", "flight_count": 37683 }, { "carrier": "AA", "flight_count": 34577 }, { "carrier": "NW", "flight_count": 33580 }, { "carrier": "UA", "flight_count": 32757 }, { "carrier": "DL", "flight_count": 32130 }, { "carrier": "RU", "flight_count": 16074 }, { "carrier": "MQ", "flight_count": 15869 }, { "carrier": "EV", "flight_count": 15769 }, { "carrier": "HP", "flight_count": 9750 }, { "carrier": "AS", "flight_count": 8453 }, { "carrier": "CO", "flight_count": 7139 }, { "carrier": "B6", "flight_count": 4842 }, { "carrier": "OH", "flight_count": 4420 }, { "carrier": "TZ", "flight_count": 3033 } ]
SELECT base."carrier" as "carrier", COUNT(1) as "flight_count" FROM '../data/flights.parquet' as base GROUP BY 1 ORDER BY 2 desc NULLS LAST
Simply adding # bar_chart
before the query tags it and tells the rendering library to show the result as a bar chart. See the docs on the Bar Chart tag for more information.
# bar_chart run: duckdb.table('../data/flights.parquet') -> { group_by: carrier aggregate: flight_count is count() }
[ { "carrier": "WN", "flight_count": 88751 }, { "carrier": "US", "flight_count": 37683 }, { "carrier": "AA", "flight_count": 34577 }, { "carrier": "NW", "flight_count": 33580 }, { "carrier": "UA", "flight_count": 32757 }, { "carrier": "DL", "flight_count": 32130 }, { "carrier": "RU", "flight_count": 16074 }, { "carrier": "MQ", "flight_count": 15869 }, { "carrier": "EV", "flight_count": 15769 }, { "carrier": "HP", "flight_count": 9750 }, { "carrier": "AS", "flight_count": 8453 }, { "carrier": "CO", "flight_count": 7139 }, { "carrier": "B6", "flight_count": 4842 }, { "carrier": "OH", "flight_count": 4420 }, { "carrier": "TZ", "flight_count": 3033 } ]
SELECT base."carrier" as "carrier", COUNT(1) as "flight_count" FROM '../data/flights.parquet' as base GROUP BY 1 ORDER BY 2 desc NULLS LAST
Malloy's renderering library uses the Vega-Lite for charting, allowing visualization of results. Malloy's rendering library is a separate layer from Malloy's data access layer.:
Rendering tags
Number - number formatting, percentages, duration, and bytes
Bar Charts - various forms of column charts