Browse Source

New report showing percent weight loss by item and operator

Neal Wilson 6 years ago
parent
commit
07e405cf86
1 changed files with 240 additions and 0 deletions
  1. 240
    0
      config/Reports/lossplots.xml

+ 240
- 0
config/Reports/lossplots.xml View File

@@ -0,0 +1,240 @@
1
+<window id="lossplots">
2
+    <reporttitle>Production:->Weight Loss By Item and Operator</reporttitle>
3
+    <layout type="vertical">
4
+        <webview id="report" />
5
+    </layout>
6
+    <menu name="File">
7
+        <item id="print" shortcut="Ctrl+P">Print...</item>
8
+    </menu>
9
+    <program>
10
+        <![CDATA[
11
+this.windowTitle = TTR("lossplots", "Typica - Weight Loss By Item and Operator");
12
+var report = findChildObject(this, 'report');
13
+var printMenu = findChildObject(this, 'print');
14
+printMenu.triggered.connect(function() {
15
+    report.print();
16
+});
17
+var query = new QSqlQuery;
18
+query.exec("WITH a AS (SELECT roasted_id, max(time) AS last_batch FROM roasting_log WHERE roasted_id IN (SELECT item FROM current_items) GROUP BY roasted_id), b AS (SELECT roasted_id, last_batch, (SELECT unroasted_id FROM roasting_log WHERE roasted_id = a.roasted_id AND time = last_batch) FROM a), c AS (SELECT roasting_log.roasted_id, ((unroasted_total_quantity - roasted_quantity)/unroasted_total_quantity) AS loss FROM roasting_log, b WHERE roasting_log.roasted_id = b.roasted_id AND roasting_log.unroasted_id = b.unroasted_id AND unroasted_total_quantity > 0 AND approval = true) SELECT roasted_id, (SELECT name FROM items WHERE id = roasted_id) AS name, count(1), min(loss), percentile_cont(0.25) WITHIN GROUP (ORDER BY loss) AS lower_quart, percentile_cont(0.5) WITHIN GROUP (ORDER BY loss) AS median, percentile_cont(0.75) WITHIN GROUP (ORDER BY loss) AS upper_quart, max(loss), avg(loss) FROM c GROUP BY roasted_id ORDER BY name ASC");
19
+var items = new Array;
20
+while(query.next()) {
21
+    var item = new Object;
22
+    item.roasted_id = query.value(0);
23
+    item.name = query.value(1);
24
+    item.mean = query.value(8);
25
+    item.min = query.value(3);
26
+    item.max = query.value(7);
27
+    item.plots = new Array;
28
+    var plot = new Object;
29
+    plot.count = query.value(2);
30
+    plot.min = item.min;
31
+    plot.max = item.max;
32
+    plot.lower_quart = query.value(4);
33
+    plot.median = query.value(5);
34
+    plot.upper_quart = query.value(6);
35
+    plot.name = "All";
36
+    item.plots.push(plot);
37
+    items.push(item);
38
+}
39
+query.exec("WITH a AS (SELECT roasted_id, max(time) AS last_batch FROM roasting_log WHERE roasted_id IN (SELECT item FROM current_items) GROUP BY roasted_id), b AS (SELECT roasted_id, last_batch, (SELECT unroasted_id FROM roasting_log WHERE roasted_id = a.roasted_id AND time = last_batch) FROM a), c AS (SELECT roasting_log.roasted_id, ((unroasted_total_quantity - roasted_quantity)/unroasted_total_quantity) AS loss, person FROM roasting_log, b WHERE roasting_log.roasted_id = b.roasted_id AND roasting_log.unroasted_id = b.unroasted_id AND unroasted_total_quantity > 0 AND approval = true) SELECT roasted_id, person, count(1), min(loss), percentile_cont(0.25) WITHIN GROUP (ORDER BY loss) AS lower_quart, percentile_cont(0.5) WITHIN GROUP (ORDER BY loss) AS median, percentile_cont(0.75) WITHIN GROUP (ORDER BY loss) AS upper_quart, max(loss) FROM c GROUP BY roasted_id, person");
40
+while(query.next()) {
41
+    var plot = new Object;
42
+    plot.count = query.value(2);
43
+    plot.min = query.value(3);
44
+    plot.max = query.value(7);
45
+    plot.lower_quart = query.value(4);
46
+    plot.median = query.value(5);
47
+    plot.upper_quart = query.value(6);
48
+    plot.name = query.value(1);
49
+    for(var i = 0; i < items.length; i++) {
50
+        if(items[i].roasted_id == query.value(0)) {
51
+            items[i].plots.push(plot);
52
+            break;
53
+        }
54
+    }
55
+}
56
+query = query.invalidate();
57
+var buffer = new QBuffer;
58
+buffer.open(3);
59
+var output = new XmlWriter(buffer);
60
+output.writeStartDocument("1.0");
61
+output.writeDTD('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0 plus SVG 1.1//EN" "http://www.w3.org/2002/04/xhtml-math-svg.dtd">');
62
+output.writeStartElement("html");
63
+output.writeAttribute("xmlns", "http://www.w3.org/1999/xhtml");
64
+output.writeStartElement("head");
65
+output.writeTextElement("style", ".box {font: 10px sans-serif;} .whisker {font: 10px sans-serif;} .axis {font: 12px sans-serif;} .axis path {fill: none; stroke: #000; shape-rendering: crispEdges;} .axis line {fill: none; stroke: #000; shape-rendering: crispEdges;} .x.axis path {fill: none; stroke: #000; shape-rendering: crispEdges;}");
66
+output.writeEndElement(); //head
67
+output.writeStartElement("body");
68
+function position(value, min, max) {
69
+    return 300 - (((Number(value)-Number(min))/(Number(max)-Number(min)))*300);
70
+}
71
+for(var i = 0; i < items.length; i++) {
72
+    output.writeStartElement("svg");
73
+    output.writeAttribute("xmlns", "http://www.w3.org/2000/svg");
74
+    output.writeAttribute("height", "420");
75
+    output.writeAttribute("width", 84 + (items[i].plots.length * 179));
76
+    output.writeStartElement("g"); //plots
77
+    output.writeAttribute("transform", "translate(50,30)");
78
+    var plotMin = items[i].min;
79
+    var plotMax = items[i].max;
80
+    for(var j = 0; j < items[i].plots.length; j++) {
81
+        output.writeStartElement("g"); //plot
82
+        output.writeAttribute("transform", "translate(" + (55 + (179 * j)).toString() + ",30)");
83
+        output.writeStartElement("line"); //center line
84
+        output.writeAttribute("class", "center");
85
+        output.writeAttribute("style", "fill: #000; stroke: #000; stroke-width: 1px;");
86
+        output.writeAttribute("x1", "27");
87
+        output.writeAttribute("x2", "27");
88
+        output.writeAttribute("y1", position(items[i].plots[j].min, plotMin, plotMax));
89
+        output.writeAttribute("y2", position(items[i].plots[j].max, plotMin, plotMax));
90
+        output.writeEndElement(); //line
91
+        output.writeStartElement("rect"); //upper and lower quartiles box
92
+        output.writeAttribute("class", "box");
93
+        output.writeAttribute("style", "fill: #12DD11; stroke: #000; stroke-width: 1px;");
94
+        output.writeAttribute("x", "0");
95
+        output.writeAttribute("width", "54");
96
+        output.writeAttribute("y", position(items[i].plots[j].upper_quart, plotMin, plotMax));
97
+        output.writeAttribute("height", position(items[i].plots[j].lower_quart, plotMin, plotMax) - position(items[i].plots[j].upper_quart, plotMin, plotMax));
98
+        output.writeEndElement(); //rect
99
+        output.writeStartElement("line"); //median line
100
+        output.writeAttribute("class", "median");
101
+        output.writeAttribute("style", "fill: #12DD11; stroke: #000; stroke-width: 1px;");
102
+        output.writeAttribute("x1", "0");
103
+        output.writeAttribute("x2", "54");
104
+        output.writeAttribute("y1", position(items[i].plots[j].median, plotMin, plotMax));
105
+        output.writeAttribute("y2", position(items[i].plots[j].median, plotMin, plotMax));
106
+        output.writeEndElement(); //line
107
+        output.writeStartElement("line"); //minimum whisker
108
+        output.writeAttribute("class", "whisker");
109
+        output.writeAttribute("style", "fill: #12DD11; stroke: #000; stroke-width: 1px;");
110
+        output.writeAttribute("x1", "0");
111
+        output.writeAttribute("x2", "54");
112
+        output.writeAttribute("y1", position(items[i].plots[j].min, plotMin, plotMax));
113
+        output.writeAttribute("y2", position(items[i].plots[j].min, plotMin, plotMax));
114
+        output.writeEndElement(); //line
115
+        output.writeStartElement("line"); //maximum whisker
116
+        output.writeAttribute("class", "whisker");
117
+        output.writeAttribute("style", "fill: #12DD11; stroke: #000; stroke-width: 1px;");
118
+        output.writeAttribute("x1", "0");
119
+        output.writeAttribute("x2", "54");
120
+        output.writeAttribute("y1", position(items[i].plots[j].max, plotMin, plotMax));
121
+        output.writeAttribute("y2", position(items[i].plots[j].max, plotMin, plotMax));
122
+        output.writeEndElement(); //line
123
+        output.writeStartElement("text"); //upper quartile label
124
+        output.writeAttribute("class", "box");
125
+        output.writeAttribute("dy", ".3em");
126
+        output.writeAttribute("dx", "-6");
127
+        output.writeAttribute("x", "0");
128
+        output.writeAttribute("y", position(items[i].plots[j].upper_quart, plotMin, plotMax));
129
+        output.writeAttribute("text-anchor", "end");
130
+        output.writeCharacters(Number(items[i].plots[j].upper_quart * 100).toFixed(2) + "%");
131
+        output.writeEndElement(); //text
132
+        output.writeStartElement("text"); //lower quartile label
133
+        output.writeAttribute("class", "box");
134
+        output.writeAttribute("dy", ".3em");
135
+        output.writeAttribute("dx", "-6");
136
+        output.writeAttribute("x", "0");
137
+        output.writeAttribute("y", position(items[i].plots[j].lower_quart, plotMin, plotMax));
138
+        output.writeAttribute("text-anchor", "end");
139
+        output.writeCharacters(Number(items[i].plots[j].lower_quart * 100).toFixed(2) + "%");
140
+        output.writeEndElement(); //text
141
+        output.writeStartElement("text"); //median label
142
+        output.writeAttribute("class", "box");
143
+        output.writeAttribute("dy", ".3em");
144
+        output.writeAttribute("dx", "6");
145
+        output.writeAttribute("x", "54");
146
+        output.writeAttribute("y", position(items[i].plots[j].median, plotMin, plotMax));
147
+        output.writeAttribute("text-anchor", "start");
148
+        output.writeCharacters(Number(items[i].plots[j].median * 100).toFixed(2) + "%");
149
+        output.writeEndElement(); //text
150
+        output.writeStartElement("text"); //minimum label
151
+        output.writeAttribute("class", "whisker");
152
+        output.writeAttribute("dy", ".3em");
153
+        output.writeAttribute("dx", "6");
154
+        output.writeAttribute("x", "54");
155
+        output.writeAttribute("y", position(items[i].plots[j].min, plotMin, plotMax));
156
+        output.writeAttribute("text-anchor", "start");
157
+        output.writeCharacters(Number(items[i].plots[j].min * 100).toFixed(2) + "%");
158
+        output.writeEndElement(); //text
159
+        output.writeStartElement("text"); //maximum label
160
+        output.writeAttribute("class", "whisker");
161
+        output.writeAttribute("dy", ".3em");
162
+        output.writeAttribute("dx", "6");
163
+        output.writeAttribute("x", "54");
164
+        output.writeAttribute("y", position(items[i].plots[j].max, plotMin, plotMax));
165
+        output.writeAttribute("text-anchor", "start");
166
+        output.writeCharacters(Number(items[i].plots[j].max * 100).toFixed(2) + "%");
167
+        output.writeEndElement(); //text
168
+        output.writeEndElement(); //g
169
+    }
170
+    output.writeStartElement("g"); //mean line and label
171
+    output.writeAttribute("transform", "translate(0, 30)");
172
+    output.writeStartElement("line");
173
+    output.writeAttribute("class", "center");
174
+    output.writeAttribute("style", "stroke: #000; stroke-width: 1px;");
175
+    output.writeAttribute("x1", "0");
176
+    output.writeAttribute("x2", (items[i].plots.length * 179) - 16);
177
+    output.writeAttribute("y1", position(items[i].mean, plotMin, plotMax));
178
+    output.writeAttribute("y2", position(items[i].mean, plotMin, plotMax));
179
+    output.writeEndElement(); //line
180
+    output.writeStartElement("text");
181
+    output.writeAttribute("class", "box");
182
+    output.writeAttribute("dy", ".3em");
183
+    output.writeAttribute("dx", "-6");
184
+    output.writeAttribute("x", "0");
185
+    output.writeAttribute("y", position(items[i].mean, plotMin, plotMax));
186
+    output.writeAttribute("text-anchor", "end");
187
+    output.writeCharacters(Number(items[i].mean * 100).toFixed(2) + "%");
188
+    output.writeEndElement(); //text
189
+    output.writeEndElement(); //g
190
+    output.writeStartElement("g") //x axis
191
+    output.writeAttribute("class", "x axis");
192
+    output.writeAttribute("transform", "translate(0,340)");
193
+    for(var j = 0; j < items[i].plots.length; j++) {
194
+        output.writeStartElement("g"); //name and population size
195
+        output.writeAttribute("class", "tick");
196
+        output.writeAttribute("transform", "translate(" + (82 + (j * 179)) + ",0)");
197
+        output.writeStartElement("line"); //tick
198
+        output.writeAttribute("y2", "6");
199
+        output.writeAttribute("x2", "0");
200
+        output.writeEndElement(); //line
201
+        output.writeStartElement("text"); //label
202
+        output.writeAttribute("style", "text-anchor: middle");
203
+        output.writeAttribute("y", "9");
204
+        output.writeAttribute("x", "0");
205
+        output.writeStartElement("tspan");
206
+        output.writeAttribute("x", "0");
207
+        output.writeAttribute("dy", ".71em");
208
+        output.writeCharacters(items[i].plots[j].name);
209
+        output.writeEndElement(); //tspan
210
+        output.writeStartElement("tspan");
211
+        output.writeAttribute("x", "0");
212
+        output.writeAttribute("dy", "1.42em");
213
+        output.writeCharacters("(n=" + items[i].plots[j].count + ")");
214
+        output.writeEndElement(); //tspan
215
+        output.writeEndElement(); //text
216
+        output.writeEndElement(); //g
217
+    }
218
+    output.writeStartElement("path");
219
+    output.writeAttribute("class", "domain");
220
+    output.writeAttribute("d", "M0,6V0H" + ((items[i].plots.length * 179) - 16) + "V6");
221
+    output.writeEndElement(); //path
222
+    output.writeEndElement(); //g
223
+    output.writeStartElement("text") //chart title
224
+    output.writeAttribute("x", (84 + (items[i].plots.length * 179))/2);
225
+    output.writeAttribute("y", "15");
226
+    output.writeAttribute("text-anchor", "middle");
227
+    output.writeAttribute("style", "font-size: 18px;");
228
+    output.writeCharacters(items[i].name);
229
+    output.writeEndElement(); //text
230
+    output.writeEndElement(); //g
231
+    output.writeEndElement(); //svg
232
+}
233
+output.writeEndElement(); //body
234
+output.writeEndElement(); //html
235
+output.writeEndDocument();
236
+report.setContent(buffer);
237
+buffer.close();
238
+        ]]>
239
+    </program>
240
+</window>

Loading…
Cancel
Save