I've been playing around with some queries and data in the stardog sandbox that use some of the user defined functions that I put together and I thought I'd share.
I like working with the CLI and wanted to be able to quickly generate some sort of bar chart. The following is a query a put together based on the query from the sandbox calculating the daily change in covid19 cases in nyc (covid19nyc db).
The query prints an ascii bar chart that colors the bar red if the % change is over 1.5 and green if it's lower. It also includes an emoji smile if it's below and a frown if above.
I've already found a couple of bugs and a few small changes I'd like to make to the functions. I need just one or two more and I think I should be able to easily rotate the chart horizontally instead of vertically. I also think with a little extra logic in the query I could use semi blocks to make the chart smoother.
Query:
prefix string: <http://semantalytics.com/2017/09/ns/stardog/kibble/string/>
prefix emoji: <http://semantalytics.com/2017/09/ns/stardog/kibble/string/emoji/>
prefix console: <http://semantalytics.com/2017/09/ns/stardog/kibble/console/>
select
?dailyIncrease
?percentageIncrease
( if(?percentageIncrease > 1.5, emoji:emojify(":("), emoji:emojify(":)" )) as ?emoji)
( string:rightPad(concat(IF(?percentageIncrease > 1.5, console:foregroundRed(), console:foregroundGreen()), string:repeat('\u2589', xsd:integer(roundHalfToEven((?dailyIncrease / ?maxDailyIncrease) * 60))), console:reset()), 70) as ?n)
{
{
SELECT (MAX(?dailyIncrease) AS ?maxDailyIncrease)
{
{
SELECT ?day (sum(?cases) as ?totalCases) {
?report :date ?day ;
:cases ?cases
}
GROUP BY ?day
}
{
SELECT ?previousDay (sum(?cases) as ?previousTotalCases) {
?report :date ?previousDay ;
:cases ?cases
}
GROUP BY ?previousDay
}
BIND((?totalCases-?previousTotalCases) AS ?dailyIncrease)
BIND(roundHalfToEven((?dailyIncrease / ?previousTotalCases) * 100, 2) AS ?percentageIncrease)
FILTER(?day - ?previousDay = "P1D"^^xsd:dayTimeDuration)
}
}
{
SELECT ?day ?totalCases ?dailyIncrease ?percentageIncrease
{
{
SELECT ?day (sum(?cases) as ?totalCases) {
?report :date ?day ;
:cases ?cases
}
GROUP BY ?day
}
{
SELECT ?previousDay (sum(?cases) as ?previousTotalCases) {
?report :date ?previousDay ;
:cases ?cases
}
GROUP BY ?previousDay
}
BIND((?totalCases-?previousTotalCases) AS ?dailyIncrease)
BIND(roundHalfToEven((?dailyIncrease / ?previousTotalCases) * 100, 2) AS ?percentageIncrease)
FILTER(?day - ?previousDay = "P1D"^^xsd:dayTimeDuration)
}
ORDER BY desc(?day)
}
}
Result: