Skip to content
Snippets Groups Projects
Commit 413b63b9 authored by Tomáš's avatar Tomáš
Browse files

share charts for uniweb and district pages

parent 846babf7
Branches
No related tags found
2 merge requests!714Release,!700Add charts to uniweb & district pages
Pipeline #11384 passed
Showing
with 70754 additions and 49 deletions
...@@ -19,6 +19,7 @@ from shared.blocks import ( ...@@ -19,6 +19,7 @@ from shared.blocks import (
ButtonBlock, ButtonBlock,
CardLinkBlockMixin, CardLinkBlockMixin,
CardLinkWithHeadlineBlockMixin, CardLinkWithHeadlineBlockMixin,
ChartBlock,
ProgramItemBlock, ProgramItemBlock,
) )
......
This diff is collapsed.
...@@ -38,6 +38,7 @@ from maps_utils.validation import validators as maps_validators ...@@ -38,6 +38,7 @@ from maps_utils.validation import validators as maps_validators
from shared.blocks import ( from shared.blocks import (
DEFAULT_CONTENT_BLOCKS, DEFAULT_CONTENT_BLOCKS,
ButtonGroupBlock, ButtonGroupBlock,
ChartBlock,
FigureBlock, FigureBlock,
FullSizeHeaderBlock, FullSizeHeaderBlock,
HeadlineBlock, HeadlineBlock,
...@@ -57,6 +58,10 @@ from tuning import admin_help ...@@ -57,6 +58,10 @@ from tuning import admin_help
from . import blocks from . import blocks
from .forms import JekyllImportForm from .forms import JekyllImportForm
CONTENT_BLOCKS = DEFAULT_CONTENT_BLOCKS + [
("chart", ChartBlock(template="district/blocks/chart.html")),
]
class DistrictHomePage( class DistrictHomePage(
MenuMixin, ExtendedMetadataHomePageMixin, MetadataPageMixin, CalendarMixin, Page MenuMixin, ExtendedMetadataHomePageMixin, MetadataPageMixin, CalendarMixin, Page
...@@ -350,6 +355,13 @@ class DistrictArticlePage( ...@@ -350,6 +355,13 @@ class DistrictArticlePage(
): ):
### FIELDS ### FIELDS
content = StreamField(
CONTENT_BLOCKS,
verbose_name="Článek",
blank=True,
use_json_field=True,
)
author_page = models.ForeignKey( author_page = models.ForeignKey(
"district.DistrictPersonPage", on_delete=models.SET_NULL, null=True, blank=True "district.DistrictPersonPage", on_delete=models.SET_NULL, null=True, blank=True
) )
...@@ -790,7 +802,7 @@ class DistrictElectionBasePage( ...@@ -790,7 +802,7 @@ class DistrictElectionBasePage(
### FIELDS ### FIELDS
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
], ],
...@@ -1208,7 +1220,7 @@ class DistrictCenterPage( ...@@ -1208,7 +1220,7 @@ class DistrictCenterPage(
related_name="+", related_name="+",
) )
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
], ],
...@@ -1306,7 +1318,7 @@ class DistrictCrossroadPage( ...@@ -1306,7 +1318,7 @@ class DistrictCrossroadPage(
) )
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
...@@ -1357,7 +1369,7 @@ class DistrictCustomPage( ...@@ -1357,7 +1369,7 @@ class DistrictCustomPage(
### FIELDS ### FIELDS
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
...@@ -1404,7 +1416,7 @@ class DistrictGeoFeatureCollectionPage( ...@@ -1404,7 +1416,7 @@ class DistrictGeoFeatureCollectionPage(
use_json_field=True, use_json_field=True,
) )
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
...@@ -1414,7 +1426,7 @@ class DistrictGeoFeatureCollectionPage( ...@@ -1414,7 +1426,7 @@ class DistrictGeoFeatureCollectionPage(
use_json_field=True, use_json_field=True,
) )
content_after = StreamField( content_after = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
...@@ -1424,7 +1436,7 @@ class DistrictGeoFeatureCollectionPage( ...@@ -1424,7 +1436,7 @@ class DistrictGeoFeatureCollectionPage(
use_json_field=True, use_json_field=True,
) )
content_footer = StreamField( content_footer = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
...@@ -1636,7 +1648,7 @@ class DistrictGeoFeatureDetailPage( ...@@ -1636,7 +1648,7 @@ class DistrictGeoFeatureDetailPage(
verbose_name="obrázek", verbose_name="obrázek",
) )
content = StreamField( content = StreamField(
DEFAULT_CONTENT_BLOCKS CONTENT_BLOCKS
+ [ + [
("badge", blocks.PersonBadgeBlock()), ("badge", blocks.PersonBadgeBlock()),
("people_group", blocks.PeopleGroupListBlock()), ("people_group", blocks.PeopleGroupListBlock()),
......
{% load wagtailcore_tags %}
{% load static %}
<script src="{% static "shared/vendor/chart.js/chart.umd.4.2.0.js" %}"></script>
<div class="py-4">
<canvas
class="lg:h-120 lg:w-auto w-full mx-auto"
id="{{ block_id }}"
></canvas>
</div>
{% include "shared/chart_script_snippet.html" with value=value block_id=block_id %}
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
<div class="lg:w-2/3"> <div class="lg:w-2/3">
<div itemprop="description" class="w-full space-y-8"> <div itemprop="description" class="w-full space-y-8">
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
{% if page.author_page %} {% if page.author_page %}
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
{{ page.text | richtext }} {{ page.text | richtext }}
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
{% if page.has_calendar %} {% if page.has_calendar %}
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<div class="space-y-8"> <div class="space-y-8">
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<div class="lg:flex mt-8 lg:space-x-16"> <div class="lg:flex mt-8 lg:space-x-16">
<div class="lg:w-2/3 space-y-8"> <div class="lg:w-2/3 space-y-8">
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</div> </div>
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
<div class="mt-4 md:mt-8 space-y-4"> <div class="mt-4 md:mt-8 space-y-4">
{% for block in page.hero_cta_buttons %} {% for block in page.hero_cta_buttons %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</p> </p>
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</section> </section>
......
...@@ -80,7 +80,7 @@ ...@@ -80,7 +80,7 @@
<div class="space-y-8 lg:space-y-16"> <div class="space-y-8 lg:space-y-16">
<section> <section>
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</section> </section>
...@@ -129,7 +129,7 @@ ...@@ -129,7 +129,7 @@
{% if page.content_after %} {% if page.content_after %}
<section class="space-y-4"> <section class="space-y-4">
{% for block in page.content_after %} {% for block in page.content_after %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</section> </section>
{% endif %} {% endif %}
...@@ -137,7 +137,7 @@ ...@@ -137,7 +137,7 @@
<div class="space-y-8 lg:flex lg:space-y-0 lg:space-x-16"> <div class="space-y-8 lg:flex lg:space-y-0 lg:space-x-16">
<section class="lg:w-2/3 space-y-4"> <section class="lg:w-2/3 space-y-4">
{% for block in page.content_footer %} {% for block in page.content_footer %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
</section> </section>
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
</div> </div>
{% for block in page.content %} {% for block in page.content %}
{% include_block block %} {% include_block block with block_id=block.id %}
{% endfor %} {% endfor %}
{% if parts|length > 1 %} {% if parts|length > 1 %}
......
import typing import typing
from datetime import datetime from datetime import datetime
from django.contrib.syndication.views import Feed from django.contrib.syndication.views import Feed
...@@ -58,10 +57,7 @@ class LatestArticlesFeed(Feed): ...@@ -58,10 +57,7 @@ class LatestArticlesFeed(Feed):
def item_link(self, item: MainArticlePage) -> str: def item_link(self, item: MainArticlePage) -> str:
return item.get_full_url() return item.get_full_url()
def item_enclosure_url( def item_enclosure_url(self, item: MainArticlePage) -> typing.Union[None, str]:
self,
item: MainArticlePage
) -> typing.Union[None, str]:
if item.image is None: if item.image is None:
return None return None
...@@ -69,8 +65,5 @@ class LatestArticlesFeed(Feed): ...@@ -69,8 +65,5 @@ class LatestArticlesFeed(Feed):
item_enclosure_mime_type = "image/webp" item_enclosure_mime_type = "image/webp"
def item_enclosure_length( def item_enclosure_length(self, item: MainArticlePage) -> int:
self,
item: MainArticlePage
) -> int:
return item.image.file_size return item.image.file_size
import json
import logging import logging
import re import re
import urllib import urllib
...@@ -657,6 +658,77 @@ class CardLinkWithHeadlineBlockMixin(blocks.StructBlock): ...@@ -657,6 +658,77 @@ class CardLinkWithHeadlineBlockMixin(blocks.StructBlock):
label = "Karty odkazů s nadpisem" label = "Karty odkazů s nadpisem"
class ChartDataset(blocks.StructBlock):
label = blocks.CharBlock(
label="Označení zdroje dat",
max_length=120,
)
data = blocks.ListBlock(
blocks.IntegerBlock(),
label="Data",
default=[0],
)
class Meta:
label = "Zdroj dat"
class ChartBlock(blocks.StructBlock):
title = blocks.CharBlock(
label="Název",
max_length=120,
)
chart_type = blocks.ChoiceBlock(
label="Typ",
choices=[
("bar", "Graf se sloupci"),
("horizontalBar", "Graf s vodorovnými sloupci"),
("pie", "Koláčový graf"),
("doughnut", "Donutový graf"),
("polarArea", "Graf polární oblasti"),
("radar", "Radarový graf"),
("line", "Graf s liniemi"),
],
default="bar",
)
labels = blocks.ListBlock(
blocks.CharBlock(
max_length=40,
label="Skupina",
),
label="Skupiny",
)
datasets = blocks.ListBlock(
ChartDataset(),
label="Zdroje dat",
)
def get_context(self, value, parent_context=None):
context = super().get_context(value, parent_context=parent_context)
datasets = []
for dataset in value["datasets"]:
dataset = dict(dataset)
datasets.append(
{"label": dataset["label"], "data": [item for item in dataset["data"]]}
)
value["datasets"] = json.dumps(datasets)
value["labels"] = json.dumps([label for label in value["labels"]])
return context
class Meta:
# template = ""
label = "Graf"
icon = "form"
help_text = """Všechny položky zdrojů dat se chovají jako sloupce.
Zobrazí se tolik definovaných sloupců, kolik existuje skupin."""
DEFAULT_CONTENT_BLOCKS = [ DEFAULT_CONTENT_BLOCKS = [
( (
"text", "text",
......
<script>
window.addEventListener(
"load",
() => {
const getRandomInt = (max) => {
return Math.floor(Math.random() * Math.floor(max));
}
const chartType = "{{ value.chart_type }}";
let colorOrder = getRandomInt(6);
const colors = [
"rgba(255, 99, 132, 0.6)",
"rgba(54, 162, 235, 0.6)",
"rgba(255, 206, 86, 0.6)",
"rgba(75, 192, 192, 0.6)",
"rgba(153, 102, 255, 0.6)",
"rgba(255, 159, 64, 0.6)",
"rgba(75, 192, 192, 0.6)",
"rgba(153, 102, 255, 0.6)",
];
const getColor = () => {
if (colorOrder === colors.length) {
colorOrder = 0;
}
return colors[colorOrder++];
}
const getDatasets = () => {
const datasets = {{ value.datasets|safe }};
let finalDatasets = [];
for (let i = 0; i < datasets.length; i++) {
let tempDataset = {};
tempDataset["label"] = datasets[i]["label"];
tempDataset["data"] = datasets[i]["data"];
if (chartType == "pie" || chartType == "doughnut" || datasets.length == 1) {
let backgroundColor = [];
for (let j = 0; j < tempDataset["data"].length; j++)
backgroundColor.push(getColor());
tempDataset["backgroundColor"] = backgroundColor;
} else {
tempDataset["backgroundColor"] = getColor();
}
tempDataset["borderColor"] = getColor();
tempDataset["borderWidth"] = 1;
finalDatasets.push(tempDataset);
}
return finalDatasets;
};
const ctx = document.getElementById("{{ block_id }}").getContext("2d");
const blockChart = new Chart(
ctx,
{
type: "{% if value.chart_type != "horizontalBar" %}{{ value.chart_type }}{% else %}bar{% endif %}",
data: {
labels: {{ value.labels|safe }},
datasets: getDatasets(),
},
options: {
{% if value.chart_type == "horizontalBar" %}
indexAxis: "y",
{% endif %}
plugins: {
title: {
display: true,
text: "{{ value.title|escapejs }}",
},
},
scales: {
y: {
ticks: {
beginAtZero: true,
},
},
},
}
}
);
}
);
</script>
...@@ -6,9 +6,8 @@ from django.db import migrations ...@@ -6,9 +6,8 @@ from django.db import migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [
('uniweb', '0034_alter_uniwebflexiblepage_content_and_more'), ("uniweb", "0034_alter_uniwebflexiblepage_content_and_more"),
('uniweb', '0035_alter_uniwebarticletag_content_object'), ("uniweb", "0035_alter_uniwebarticletag_content_object"),
] ]
operations = [ operations = []
]
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment