Qt Quick based coffee brewing control chart.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.qml 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. import CustomComponents 1.0
  2. import QtQuick 1.0
  3. Rectangle {
  4. id: root
  5. property real sumy : 0
  6. property real sumxsq : 0
  7. property real sumx : 0
  8. property real sumxy : 0
  9. property int n : 0
  10. width: 720
  11. height: 680
  12. BrewingControlChart {
  13. id: graph
  14. width: 450; height: 600
  15. anchors {right: parent.right; rightMargin: 20; top: parent.top; topMargin: 20}
  16. }
  17. Item {
  18. anchors {left: parent.left; leftMargin: 10; top: parent.top; topMargin: 10}
  19. Column {
  20. spacing: 8
  21. Row {
  22. spacing: 5
  23. Text {
  24. text: "Mass of ground coffee: "
  25. }
  26. TextInput {
  27. id: groundMass
  28. width: 30
  29. validator: DoubleValidator {
  30. bottom: 0
  31. decimals: 2
  32. notation: DoubleValidator.StandardNotation
  33. }
  34. KeyNavigation.tab: brewedMass
  35. Line {
  36. x1: -3; y1: groundMass.height
  37. x2: 33; y2: y1
  38. penWidth: 1
  39. color: "black"
  40. }
  41. }
  42. }
  43. Row {
  44. spacing: 5
  45. Text {
  46. text: "Mass of brewed coffee:"
  47. }
  48. TextInput {
  49. id: brewedMass
  50. width: 30
  51. validator: DoubleValidator {
  52. bottom: 0
  53. decimals: 2
  54. notation: DoubleValidator.StandardNotation
  55. }
  56. KeyNavigation.backtab: groundMass
  57. KeyNavigation.tab: ptds
  58. Line {
  59. x1: -3; y1: brewedMass.height
  60. x2: 33; y2: y1
  61. penWidth: 1
  62. color: "black"
  63. }
  64. }
  65. }
  66. Row {
  67. spacing: 56
  68. Text {
  69. text: "Percent TDS:"
  70. }
  71. TextInput {
  72. id: ptds
  73. width: 30
  74. validator: DoubleValidator {
  75. bottom: 0
  76. top: 100
  77. decimals: 2
  78. notation: DoubleValidator.StandardNotation
  79. }
  80. KeyNavigation.backtab: brewedMass
  81. Line {
  82. x1: -3; y1: ptds.height
  83. x2: 33; y2: y1
  84. penWidth: 1
  85. color: "black"
  86. }
  87. }
  88. }
  89. Row {
  90. spacing: 87
  91. Text {
  92. id: colorlabel
  93. text: "Color:"
  94. }
  95. ColorPicker {
  96. id: colorpicker
  97. width: 37; height: colorlabel.height
  98. }
  99. }
  100. Row {
  101. id: lsfrow
  102. visible: false
  103. spacing: 1
  104. Text {
  105. id: fitcolorlabel
  106. text: "Least Squares Fit Color:"
  107. }
  108. ColorPicker {
  109. id: fitcolorpicker
  110. width: 37; height: colorlabel.height
  111. onColorChanged: {
  112. graph.setFitColor(color)
  113. }
  114. }
  115. }
  116. Rectangle {
  117. id: plotButton
  118. z: 0
  119. anchors.horizontalCenter: parent.horizontalCenter
  120. height: buttonText.height + 20; width: buttonText.width + 40
  121. border.color: "black"
  122. radius: 10
  123. Text {
  124. id: buttonText
  125. text: "Plot This Brew"
  126. anchors {horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter}
  127. }
  128. MouseArea {
  129. anchors.fill: parent
  130. onClicked: {
  131. var extraction = (brewedMass.text * (ptds.text / 100)) / groundMass.text
  132. graph.plotPoint(extraction, (ptds.text / 100), colorpicker.color)
  133. dataViewModel.append({"color": colorpicker.color, "ptds": ptds.text, "extraction": extraction})
  134. root.n += 1
  135. root.sumy += (ptds.text / 100)
  136. root.sumx += extraction
  137. root.sumxy += ((ptds.text / 100) * extraction)
  138. root.sumxsq += Math.pow(extraction, 2)
  139. if(root.n > 1) {
  140. var a = ((root.sumy * root.sumxsq)-(root.sumx * root.sumxy))/((root.n * root.sumxsq)-Math.pow(root.sumx, 2))
  141. var b = ((root.n * root.sumxy)-(root.sumx * root.sumy))/((root.n * root.sumxsq) - Math.pow(root.sumx, 2))
  142. var x1 = 0.14
  143. var x2 = 0.26
  144. var y1 = a + (b * x1)
  145. var y2 = a + (b * x2)
  146. if(y1 < 0.008) {
  147. x1 = (0.008 - a) / b
  148. y1 = 0.008
  149. }
  150. if(y2 < 0.008) {
  151. x2 = (0.008 - a) / b
  152. y2 = 0.008
  153. }
  154. if(y1 > 0.016) {
  155. x1 = (0.016 - a) / b
  156. y1 = 0.016
  157. }
  158. if(y2 > 0.016) {
  159. x2 = (0.016 - a) / b
  160. y2 = 0.016
  161. }
  162. graph.setFit(x1, y1, x2, y2);
  163. }
  164. }
  165. }
  166. }
  167. ListView {
  168. spacing: 3
  169. height: 400
  170. width: 100
  171. z: -1
  172. contentHeight: dataViewModel.count * 35
  173. model: ListModel {
  174. id: dataViewModel
  175. }
  176. delegate: Row {
  177. spacing: 3
  178. Rectangle {
  179. width: 30; height: 30
  180. color: dataViewModel.get(index).color
  181. }
  182. Column {
  183. Text {
  184. text: "Strength: " + dataViewModel.get(index).ptds + "% TDS"
  185. }
  186. Text {
  187. text: "Extraction: " + Number(dataViewModel.get(index).extraction * 100).toFixed(2) + "%"
  188. }
  189. }
  190. }
  191. }
  192. }
  193. }
  194. Component.onCompleted: {
  195. var quitItem = window.addMenuItem("File", "Quit");
  196. quitItem.shortcut = "Ctrl+Q";
  197. quitItem.triggered.connect(function() {
  198. Qt.quit();
  199. });
  200. var clearItem = window.addMenuItem("Plotting", "Clear Data");
  201. clearItem.triggered.connect(function() {
  202. graph.clear();
  203. dataViewModel.clear();
  204. root.sumy = 0;
  205. root.sumxsq = 0;
  206. root.sumx = 0;
  207. root.sumxy = 0;
  208. root.n = 0;
  209. graph.setFit(0, 0, 0, 0);
  210. });
  211. var showLeastSquares = window.addMenuItem("Plotting", "Least Squares Fit");
  212. showLeastSquares.checkable = true;
  213. showLeastSquares.triggered.connect(function() {
  214. graph.setFitVisible(showLeastSquares.checked);
  215. lsfrow.visible = showLeastSquares.checked;
  216. });
  217. }
  218. }