chart.sql 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. SET ":user" = COALESCE(:user, $user, '');
  2. SET ":date" = COALESCE(:date, $date, CURRENT_TIMESTAMP);
  3. SET ":start_of_day" = (SELECT datetime(datetime(:date, 'localtime'), 'start of day'));
  4. SET ":end_of_day" = (SELECT datetime(:start_of_day, '+1 days'));
  5. SET ":total_time" = (WITH delta AS (SELECT julianday(COALESCE((
  6. SELECT min(lag.ts, datetime(:end_of_day, 'utc'))
  7. FROM activities lag
  8. WHERE lag.ts > a.ts AND lag.activity <> a.activity
  9. ORDER BY lag.ts ASC
  10. LIMIT 1
  11. ), min(CURRENT_TIMESTAMP, datetime(:end_of_day, 'utc')))) - julianday(a.ts) AS delta
  12. , activity
  13. FROM activities a
  14. WHERE user = :user
  15. AND datetime(datetime(ts, 'localtime'), 'start of day') = :start_of_day)
  16. SELECT printf("%.0f", sum(delta)*60*24) AS minutes --, activity
  17. FROM delta
  18. WHERE activity = 'Eating'
  19. GROUP BY delta.activity);
  20. SELECT 'chart' AS component
  21. --, '' AS title
  22. , :total_time || ' min.' AS title
  23. , TRUE AS time
  24. , 'area' AS type
  25. , 1 AS ymax
  26. , 0 AS ymin
  27. , 1 AS ystep
  28. , '100' AS height
  29. -- TODO: fix color to series
  30. --
  31. -- SELECT DISTINCT color(activity) FROM activities ORDER BY activity;
  32. , 'azure' AS color
  33. , 'green' AS color
  34. , 'red' AS color
  35. ;
  36. SET ":any" = EXISTS (SELECT * FROM activities
  37. WHERE user = :user
  38. AND datetime(ts, 'localtime')
  39. BETWEEN :start_of_day AND :end_of_day
  40. LIMIT 1
  41. );
  42. SELECT NULL AS x, NULL AS y, 'Unknown' AS series WHERE :any;
  43. SELECT NULL AS x, NULL AS y, 'Eating' AS series WHERE :any;
  44. SELECT NULL AS x, NULL AS y, 'Not eating' AS series WHERE :any;
  45. SET ":morning_offset" = '08:00:00.000';
  46. SET ":evening_offset" = '03:00:00.000';
  47. WITH plot AS (
  48. SELECT ROW_NUMBER() OVER (ORDER BY ts) AS row
  49. , ts
  50. , activity
  51. FROM (
  52. SELECT ts, activity FROM activities
  53. WHERE user = :user
  54. AND datetime(ts, 'localtime') BETWEEN :start_of_day AND :end_of_day
  55. UNION
  56. SELECT datetime(:start_of_day, 'utc'), (
  57. SELECT activity FROM activities
  58. WHERE user = :user AND datetime(ts, 'localtime') <= :start_of_day
  59. AND :any
  60. ORDER BY ts DESC
  61. LIMIT 1
  62. )
  63. UNION
  64. SELECT datetime(:end_of_day, 'utc'), (
  65. SELECT activity FROM activities
  66. WHERE user = :user AND datetime(ts, 'localtime') <= :end_of_day
  67. AND :any
  68. ORDER BY ts DESC
  69. LIMIT 1
  70. )
  71. )
  72. )
  73. SELECT datetime(:start_of_day, '+'||:morning_offset) AS x, 1 AS y, (
  74. SELECT activity FROM activities
  75. WHERE user = :user AND datetime(ts, 'localtime') <= datetime(:start_of_day, '+'||:morning_offset)
  76. AND :any
  77. ORDER BY ts DESC
  78. LIMIT 1
  79. ) AS series
  80. UNION
  81. SELECT datetime(:end_of_day, '-'||:evening_offset) AS x, 1 AS y, (
  82. SELECT activity FROM activities
  83. WHERE user = :user AND datetime(ts, 'localtime') <= datetime(:end_of_day, '-'||:evening_offset)
  84. AND :any
  85. ORDER BY ts DESC
  86. LIMIT 1
  87. ) AS series
  88. UNION
  89. SELECT datetime(x, 'localtime') AS x, CASE value WHEN 0 THEN NULL ELSE value END AS y, series FROM (
  90. SELECT datetime(next.ts, '-00:00:01.000') AS x, 0 AS value, next.activity AS series
  91. FROM plot, plot next
  92. WHERE plot.row = next.row - 1
  93. AND plot.activity <> next.activity
  94. UNION
  95. SELECT ts AS x, 1 AS value, activity AS series
  96. FROM plot
  97. UNION
  98. SELECT datetime(next.ts, '-00:00:01.000') AS x, 1 AS value, plot.activity AS series
  99. FROM plot, plot next
  100. WHERE plot.row = next.row - 1
  101. AND plot.activity <> next.activity
  102. UNION
  103. SELECT next.ts AS x, 0 AS value, plot.activity AS series
  104. FROM plot, plot next
  105. WHERE plot.row = next.row - 1
  106. AND plot.activity <> next.activity
  107. ) q
  108. WHERE
  109. datetime(datetime(x, 'localtime'), '-'||:morning_offset) >= :start_of_day
  110. AND
  111. datetime(datetime(x, 'localtime'), '+'||:evening_offset) <= :end_of_day
  112. ;