statistics.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. const _ = require('lodash')
  2. const app = require('../app')
  3. function trim (str) {
  4. return str.replace(/^\s+|\s+$/gm,'');
  5. }
  6. function rgbaToHex (rgba) {
  7. const parts = rgba.substring(rgba.indexOf("(")).split(","),
  8. r = parseInt(trim(parts[0].substring(1)), 10),
  9. g = parseInt(trim(parts[1]), 10),
  10. b = parseInt(trim(parts[2]), 10),
  11. a = parseFloat(trim(parts[3].substring(0, parts[3].length - 1))).toFixed(2)
  12. return ('#' + r.toString(16).padStart(2, 0) + g.toString(16).padStart(2, 0) + b.toString(16).padStart(2, 0))
  13. }
  14. app.service('statistics', function(api, $mdColors) {
  15. window.$mdColors = $mdColors
  16. const colors = [
  17. rgbaToHex($mdColors.getThemeColor('blue')),
  18. rgbaToHex($mdColors.getThemeColor('red')),
  19. rgbaToHex($mdColors.getThemeColor('amber')),
  20. rgbaToHex($mdColors.getThemeColor('teal')),
  21. rgbaToHex($mdColors.getThemeColor('deep-orange')),
  22. rgbaToHex($mdColors.getThemeColor('cyan')),
  23. rgbaToHex($mdColors.getThemeColor('purple')),
  24. rgbaToHex($mdColors.getThemeColor('lime')),
  25. rgbaToHex($mdColors.getThemeColor('indigo')),
  26. rgbaToHex($mdColors.getThemeColor('pink'))
  27. ]
  28. const chart = ({
  29. rows,
  30. seriesField,
  31. dataField,
  32. labelsField,
  33. format
  34. }) => {
  35. const labels = _.chain(rows).map(x => x[labelsField]).uniq().value()
  36. const series = _.chain(rows).map(x => x[seriesField]).uniq().value()
  37. const seriesData = _.chain(rows)
  38. .groupBy(x => x[seriesField])
  39. .toPairs()
  40. .map(([key, rows]) => [
  41. key,
  42. _.chain(rows)
  43. .map(row => [row[labelsField], row[dataField]])
  44. .fromPairs()
  45. .value()
  46. ])
  47. .fromPairs()
  48. .value()
  49. const data = series.map(s => {
  50. const sdata = seriesData[s]
  51. return labels.map(l => sdata[l])
  52. })
  53. return {
  54. labels,
  55. series,
  56. data,
  57. colors: colors.slice(0, series.length),
  58. options: {
  59. tooltips: {
  60. callbacks: {
  61. label: (tooltipItem, data) => {
  62. const label = data.datasets[tooltipItem.datasetIndex].label || ''
  63. const value = tooltipItem.yLabel
  64. return format ? format(label, value) : `${label}: ${value}`
  65. }
  66. }
  67. }
  68. }
  69. }
  70. }
  71. this.charts = (rows) => {
  72. return {
  73. delivery: chart({
  74. rows,
  75. seriesField: 'key',
  76. dataField: 'delivered',
  77. labelsField: 'date',
  78. format: (label, value) => `${label}: ${value.toLocaleString()} cartons`
  79. }),
  80. costPerCarton: chart({
  81. rows,
  82. seriesField: 'key',
  83. dataField: 'costPerCarton',
  84. labelsField: 'date',
  85. format: (label, value) => `${label}: $${value.toFixed(2)} per carton`
  86. }),
  87. laborCost: chart({
  88. rows,
  89. seriesField: 'key',
  90. dataField: 'laborCost',
  91. labelsField: 'date',
  92. format: (label, value) => `${label}: $${value.toFixed(2)} labor cost`
  93. })
  94. }
  95. }
  96. })