Skip to content

Commit d4b1524

Browse files
committed
save
1 parent 65638c9 commit d4b1524

File tree

9 files changed

+140
-3
lines changed

9 files changed

+140
-3
lines changed

bolt-charts/LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2023, Dropseed, LLC
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

bolt-charts/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<!-- This file is compiled from bolt-charts/bolt/vendor/README.md. Do not edit this file directly. -->
2+
3+
# bolt-charts

bolt-charts/bolt/charts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# bolt-charts

bolt-charts/bolt/charts/__init__.py

Whitespace-only changes.

bolt-charts/pyproject.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[tool.poetry]
2+
3+
name = "bolt-charts"
4+
packages = [
5+
{ include = "bolt" },
6+
]
7+
8+
version = "0.0.0"
9+
description = ""
10+
authors = ["Dave Gaeddert <[email protected]>"]
11+
license = "MIT"
12+
# readme = "README.md"
13+
14+
[tool.poetry.dependencies]
15+
python = "^3.11"
16+
plotly = ">5.0.0"
17+
pandas = "*"
18+
19+
[build-system]
20+
requires = ["poetry-core>=1.0.0"]
21+
build-backend = "poetry.core.masonry.api"

bolt-staff/bolt/staff/admin/cards/charts.py

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,78 @@
11
import datetime
2-
2+
import plotly.express as px
3+
import pandas as pd
34
from .base import Card
5+
from bolt.db.models import Count
6+
from bolt.db.models.functions import TruncDate
7+
8+
class Chart:
9+
def render_html(self):
10+
config = {
11+
"displayModeBar": False,
12+
"scrollZoom": False,
13+
"responsive": True,
14+
# "staticPlot": True,
15+
}
16+
return self.get_figure().to_html(full_html=False, config=config)#, include_plotlyjs=False)
17+
18+
def render_image(self):
19+
return self.get_figure().to_image(format="png")
20+
21+
def __html__(self):
22+
return self.render_html()
23+
24+
25+
class BarChart(Chart):
26+
def __init__(self, *, dataframe, x, y):
27+
self.dataframe = dataframe
28+
self.x = x
29+
self.y = y
30+
31+
def get_figure(self):
32+
fig = px.bar(self.dataframe, x=self.x, y=self.y)
33+
return fig
34+
35+
36+
37+
class TrendCard(Card):
38+
template_name = "admin/cards/trend.html"
39+
40+
model = None
41+
trend_field = "created_at"
42+
43+
# default behavior can be querysets and models?
44+
# override if custom objects, but rare?
45+
46+
def get_template_context(self):
47+
context = super().get_template_context()
48+
context["chart"] = self.get_chart()
49+
return context
50+
51+
def get_chart(self):
52+
filters = {
53+
f"{self.trend_field}__range": self.datetime_range.as_tuple(),
54+
}
55+
data = (
56+
self.model.objects.filter(**filters)
57+
.annotate(date=TruncDate(self.trend_field))
58+
.values("date")
59+
.annotate(count=Count("id"))
60+
.order_by("date")
61+
)
62+
63+
dataframe = pd.DataFrame.from_records(
64+
data,
65+
columns=["date", "count"],
66+
)
67+
68+
# fill the zeroes for the missing dates
69+
dataframe = dataframe.set_index("date").reindex(self.datetime_range).fillna(0).reset_index()
70+
71+
return BarChart(
72+
dataframe=dataframe,
73+
x="date",
74+
y="count",
75+
)
476

577

678
class ChartCard(Card):

bolt-staff/bolt/staff/admin/templates/admin/base.html

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
{{ request.user }}
6868
</span>
6969
</div>
70-
<a class="ml-2 hover:text-white hover:underline flex-shrink-0" href="{{ url('logout') }}">Log out</a>
70+
<a class="flex-shrink-0 ml-2 hover:text-white hover:underline" href="{{ url('logout') }}">Log out</a>
7171
</div>
7272
</div>
7373
<div id="admin-content" data-toggle-class="fixed ml-64 -mr-64" class="flex-grow overflow-auto text-black border-l bg-paper lg:rounded-lg lg:mt-3 lg:mb-3 lg:mr-3 lg:ml-64 border-black/10">
@@ -145,6 +145,13 @@ <h1 class="text-2xl font-semibold text-stone-700">
145145
</form>
146146
</div>
147147
</div>
148+
{#
149+
<!-- Tell tailwind about potential col-span sizes for cards -->
150+
<div class="col-span-1"></div>
151+
<div class="col-span-2"></div>
152+
<div class="col-span-3"></div>
153+
<div class="col-span-4"></div>
154+
#}
148155
<div class="grid grid-cols-1 gap-6 mt-4 mb-6 sm:grid-cols-2 lg:grid-cols-4">
149156
{% for card in cards %}
150157
<section class="col-span-{{ card.size.value }}">
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{% extends "admin/cards/base.html" %}
2+
3+
{% block content %}
4+
{{ chart }}
5+
{% endblock %}

bolt/bolt/templates/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Templates
22

3-
Render HTML templates using Jinja.
3+
Render templates using Jinja2.
44

55
Templates are typically rendered in `TemplateViews`,
66
but you can also render them directly to strings for emails or other use cases.

0 commit comments

Comments
 (0)