ソースを参照

improve layout and make dark theme

Daniel Sheffield 1 年間 前
コミット
b0417aa345

+ 0 - 11
app/rest/filter-item.tpl

@@ -1,11 +0,0 @@
-<td>
-  <!--<label for="{{id}}">{{label}}</label>-->
-  <select id="{{id}}" name="{{fname}}" size=10 multiple>
-    <%
-      include('app/rest/filter-option', value=hint, disabled=True)
-      for opt in options:
-        include('app/rest/filter-option', **opt)
-      end
-    %>
-  </select>
-</td>

+ 11 - 0
app/rest/filter-set.tpl

@@ -0,0 +1,11 @@
+<div class="pure-g">
+  <%
+    for filter in (product, category, group):
+      include('app/rest/include-exclude', **filter)
+    end
+  %>
+  <%
+    include('app/rest/include-exclude', **tags)
+    include('app/rest/select-one', **units)
+  %>
+</div>

+ 6 - 52
app/rest/form.tpl

@@ -1,56 +1,10 @@
 <form id="filter" style="display: inline-flex"  method="{{ method }}" action="{{ action }}">
+    <%
+    include('app/rest/filter-set',
+      product=product, category=category, group=group,
+      tags=tags, units=units)
+    %>
     <div>
-    <table class="pure-table pure-table-bordered pure-table-striped">
-        <thead style="position: sticky; top: 0">
-            <tr>
-{{! ''.join( header )}}
-            </tr>
-        </thead>
-        <tbody>     
-            <tr>
-{{! ''.join( _include )}}
-            </tr>
-            <tr>
-{{! ''.join( _exclude )}}
-            </tr>
-        </tbody>
-    </table>
-    </div>
-    <div>
-    <table class="pure-table pure-table-bordered pure-table-striped" style="max-width: 32vw; position: sticky; top: 0">
-        <thead>
-            <tr>
-                <th>Tags</th>
-                <th>
-                    Unit
-                    <button style="position: absolute; right: 0.2em" type="submit">
-                        Apply
-                    </button>
-                </th>
-            </tr>
-            <tr>
-                <td>
-                    <select id="tag" name="tag" size=10 multiple>
-                        <%
-                        include('app/rest/filter-option', value="Select", disabled=True)
-                        for opt in tags:
-                            include('app/rest/filter-option', **opt)
-                        end
-                        %>
-                    </select>
-                </td>
-                <td>
-                    <select id="unit" name="unit" size=10>
-                        <%
-                        include('app/rest/filter-option', value="Select", disabled=True)
-                        for opt in units:
-                            include('app/rest/filter-option', **opt)
-                        end
-                        %>
-                    </select>
-                </td>
-            </tr>
-        </thead>
-    </table>
+    <button type="submit"> Apply </button>
     </div>
 </form>

+ 15 - 0
app/rest/include-exclude.tpl

@@ -0,0 +1,15 @@
+<div class="pure-u-1-3 pure-u-lg-1-5">
+<div class="pure-g">
+  <div class="pure-u-1">
+    <div class="l-box">
+      <h3>{{name.title()}}</h3>
+    </div>
+  </div>
+  <% include('app/rest/select', id=f"{name}-include", name=name, options=_include["options"], hint="Include") %>
+  <%
+  if defined("_exclude"):
+    include('app/rest/select', id=f"{name}-exclude", name=name, options=_exclude["options"], hint="Exclude")
+  end
+  %>
+</div>
+</div>

+ 1 - 0
app/rest/label.tpl

@@ -0,0 +1 @@
+<label for="{{id}}">{{label}}</label>

+ 0 - 0
app/rest/filter-option.tpl → app/rest/option.tpl


+ 50 - 44
app/rest/pyapi.py

@@ -39,8 +39,11 @@ matplotlib.use('agg')
 
 def line(pivot, ylabel=None, xlabel=None):
     ax = sns.lineplot(data=pivot, markers=True)
-    ax.set_xlabel(xlabel)
-    ax.set_ylabel(ylabel)
+    ax.set_xlabel(xlabel, color='#cccccc')
+    ax.set_ylabel(ylabel, color='#cccccc')
+    ax.axes.tick_params(colors='#cccccc', which='both')
+    for _, spine in ax.spines.items():
+        spine.set_color('#cccccc')
 
 ALL_UNITS = {'g', 'kg', 'mL', 'L', 'Pieces', 'Bunches', 'Bags'}
 PARAMS = { 'group', 'category', 'product', 'unit', 'tag' }
@@ -53,7 +56,7 @@ password = f"password={os.getenv('PASSWORD','')}"
 if not password.split('=',1)[1]:
     password = ''
 conn = connect(f"{host} {db} {user} {password}")
-sns.set_theme()
+sns.set_theme(style='darkgrid', palette='pastel')
 
 def get_product_rollup_statement(filters, having=None):
     where = [ get_where_include_exclude(
@@ -128,53 +131,56 @@ def get_form(action, method, filter_data, data):
                 first=(idx == 0),
             ) for idx, k in enumerate(keys)
         ],
-        _include=[ template(
-            'app/rest/filter-item',
-            label="+",
-            hint="Include",
-            id=f"{k}-include",
-            fname=k,
-            options=sorted(map(lambda x: {
+        **{
+            k: {
+                "name": k,
+                "_include": {
+                    "options": sorted(map(lambda x: {
+                        "selected": x[0],
+                        "value": x[1],
+                    }, chain(
+                        map(lambda x: (True, x), filter_data[k][0]),
+                        map(lambda x: (False, x), set([
+                            x[k] for _, x in group.iterrows()
+                        ]) - filter_data[k][0])
+                    )), key=lambda x: x["display"] if "display" in x else x["value"])
+                },
+                "_exclude": {
+                    "options": sorted(map(lambda x: {
+                        "selected": x[0],
+                        "value": f"!{x[1]}",
+                        "display": x[1]
+                    }, chain(
+                        map(lambda x: (True, x), filter_data[k][1]),
+                        map(lambda x: (False, x), set([
+                            x[k] for _, x in group.iterrows()
+                        ]) - filter_data[k][1])
+                    )), key=lambda x: x["display"] if "display" in x else x["value"])
+                }
+            } for k in keys
+        },
+        tags={
+            "name": "tags",
+            "_include": {
+                "options": sorted(map(lambda x: {
                     "selected": x[0],
                     "value": x[1],
-                }, chain(
-                map(lambda x: (True, x), filter_data[k][0]),
-                map(lambda x: (False, x), set([
-                    x[k] for _, x in group.iterrows()
-                ]) - filter_data[k][0])
-            )), key=lambda x: x["display"] if "display" in x else x["value"]), # include
-        ) for k in keys ],
-        _exclude=[ template(
-            'app/rest/filter-item',
-            label="-",
-            hint="Exclude",
-            id=f"{k}-exclude",
-            fname=k,
-            options=sorted(map(lambda x: {
-                    "selected": x[0],
-                    "value": f"!{x[1]}",
-                    "display": x[1]
-                }, chain(
-                map(lambda x: (True, x), filter_data[k][1]),
-                map(lambda x: (False, x), set([
-                    x[k] for _, x in group.iterrows()
-                ]) - filter_data[k][1])
-            )), key=lambda x: x["display"] if "display" in x else x["value"]), # exclude
-        ) for k in keys ],
-        tags=sorted(map(lambda x: {
-                "selected": x[0],
-                "value": x[1],
-            },chain(
-                map(lambda x: (True, x), filter_data['tag'][0]),
-                map(lambda x: (False, x), set(chain(*data[in_chart]['tags'])) - filter_data['tag'][0])
-        )), key=lambda x: x["display"] if "display" in x else x["value"]), # include,
-        units=sorted(map(lambda x: {
+                },chain(
+                    map(lambda x: (True, x), filter_data['tag'][0]),
+                    map(lambda x: (False, x), set(chain(*data[in_chart]['tags'])) - filter_data['tag'][0])
+                )), key=lambda x: x["display"] if "display" in x else x["value"])
+            }
+        },
+        units={
+            "name": "units",
+            "options": sorted(map(lambda x: {
                 "selected": x[0],
                 "value": x[1],
             },chain(
                 map(lambda x: (True, x), filter_data['unit'][0]),
                 map(lambda x: (False, x), ALL_UNITS - filter_data['unit'][0])
-        )), key=lambda x: x["display"] if "display" in x else x["value"]), # include
+            )), key=lambda x: x["display"] if "display" in x else x["value"])
+        }
     )
 
 @route('/grocery/static/<filename:path>')
@@ -246,7 +252,7 @@ def trend_internal(path, query):
             yield template("app/rest/loading", progress=progress)
             pivot = data.pivot_table(index=['ts_raw',], columns=['product',], values=['$/unit'], aggfunc='mean')
             pivot.columns = pivot.columns.droplevel()
-            plt.figure(figsize=[16, 9])
+            plt.figure(facecolor='black', figsize=[16, 9])
             line(pivot, xlabel='Time', ylabel=f'$ / {unit}')
             
             progress[-1]["status"] = "done"

+ 10 - 0
app/rest/select-one.tpl

@@ -0,0 +1,10 @@
+<div class="pure-u-1-3 pure-u-lg-1-5">
+<div class="pure-g">
+  <div class="pure-u-1">
+    <div class="l-box">
+      <h3>{{name.title()}}</h3>
+    </div>
+  </div>
+  <% include('app/rest/select', id=f"{name}-select-one", name=name, options=options) %>
+</div>
+</div>

+ 17 - 0
app/rest/select.tpl

@@ -0,0 +1,17 @@
+<div class="pure-u-1">
+<%
+  if defined("label"):
+    include('app/rest/label', id=id, label=label)
+  end
+%>
+<select id="{{id}}" name="{{name}}" size=10 multiple  style="width: 98%; margin: 1em">
+  <%
+    if defined("hint"):
+      include('app/rest/option', value=hint, disabled=True)
+    end
+    for opt in options:
+      include('app/rest/option', **opt)
+    end
+  %>
+</select>
+</div>

+ 2 - 1
app/rest/trend.tpl

@@ -2,8 +2,9 @@
 <html>
     <head>
         <style>
+body {background-color: #080808; color: #cccccc; }
+select {color: #cccccc; background-color: #080808; }
 svg {width: 100vw}
-select {max-width: 23vw}
         </style>
         <title>Trend</title>
         <meta name="viewport" content="width=device-width, initial-scale=1"/>