Skip to content

Commit 7431461

Browse files
committed
[fix] Fixed dashboard pie charts not showing 0 for no data #301
Fixes #301
1 parent 84ed7f6 commit 7431461

2 files changed

Lines changed: 85 additions & 17 deletions

File tree

openwisp_utils/admin_theme/static/admin/js/ow-dashboard.js

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
(function() {
2+
23
'use strict';
34

5+
function slugify(str) {
6+
str = str.replace(/^\s+|\s+$/g, '');
7+
// Make the string lowercase
8+
str = str.toLowerCase();
9+
// Remove invalid chars
10+
str = str.replace(/[^a-z0-9 -]/g, '')
11+
// Collapse whitespace and replace by -
12+
.replace(/\s+/g, '-')
13+
// Collapse dashes
14+
.replace(/-+/g, '-');
15+
return str;
16+
}
17+
418
let elementsParam = Object.values(owDashboardCharts),
519
container = document.getElementById('plot-container');
620

@@ -38,10 +52,11 @@
3852
type: 'pie',
3953
hole: 0.6,
4054
},
41-
element = document.createElement('div');
55+
element = document.createElement('div'),
56+
totalValues = 0;
4257

4358
// Show a graph depicting disabled graph when there is insufficient data
44-
if (elementsParam[i].query_params.values.length == 0) {
59+
if (elementsParam[i].query_params.values.length === 0) {
4560
data.values = [1];
4661
data.labels = ['Not enough data'];
4762
data.marker = {
@@ -71,23 +86,22 @@
7186
data.filters = elementsParam[i].filters;
7287

7388
// add total to pie chart
74-
var total = 0;
7589
for (var c = 0; c < data.values.length; c++) {
76-
total += data.values[c];
90+
totalValues += data.values[c];
7791
}
78-
layout.annotations = [
79-
{
80-
font: {
81-
size: 20,
82-
weight: 'bold'
83-
},
84-
showarrow: false,
85-
text: `<b>${total}</b>`,
86-
x: 0.5,
87-
y: 0.5
88-
}
89-
];
9092
}
93+
layout.annotations = [
94+
{
95+
font: {
96+
size: 20,
97+
weight: 'bold'
98+
},
99+
showarrow: false,
100+
text: `<b>${totalValues}</b>`,
101+
x: 0.5,
102+
y: 0.5
103+
}
104+
];
91105

92106
Plotly.newPlot(element, [data], layout, options);
93107

@@ -104,6 +118,28 @@
104118
window.location = path;
105119
});
106120
}
121+
122+
// Add quick link button
123+
if (elementsParam[i].hasOwnProperty('quick_link')) {
124+
let quickLinkContainer = document.createElement('div');
125+
quickLinkContainer.classList.add('quick-link-container');
126+
let quickLink = document.createElement('a');
127+
quickLink.href = elementsParam[i].quick_link.url;
128+
quickLink.innerHTML = elementsParam[i].quick_link.label;
129+
quickLink.title = elementsParam[i].quick_link.title || elementsParam[i].quick_link.label;
130+
quickLink.classList.add('button', 'quick-link');
131+
// Add custom css classes
132+
if (elementsParam[i].quick_link.custom_css_classes) {
133+
for(let j=0; j<elementsParam[i].quick_link.custom_css_classes.length; ++j){
134+
quickLink.classList.add(elementsParam[i].quick_link.custom_css_classes[j]);
135+
}
136+
}
137+
quickLinkContainer.appendChild(quickLink);
138+
element.appendChild(
139+
quickLinkContainer
140+
);
141+
}
142+
element.classList.add(slugify(elementsParam[i].name));
107143
container.appendChild(element);
108144
}
109145

tests/test_project/tests/test_selenium.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from selenium.webdriver.support import expected_conditions as EC
77
from selenium.webdriver.support.ui import WebDriverWait
88

9-
from ..models import Book, Shelf
9+
from ..models import Book, Operator, Shelf
1010
from . import CreateMixin
1111
from .utils import SeleniumTestMixin
1212

@@ -643,3 +643,35 @@ def test_input_filters(self):
643643
self.web_driver.find_element_by_css_selector('.field-clear').click()
644644
self.web_driver.find_element_by_xpath(admin_xpath)
645645
self.web_driver.find_element_by_xpath(user_xpath)
646+
647+
648+
class TestDashboardCharts(SeleniumTestMixin, CreateMixin, StaticLiveServerTestCase):
649+
@classmethod
650+
def setUpClass(cls):
651+
super().setUpClass()
652+
653+
def setUp(self):
654+
self.admin = self._create_admin()
655+
self.web_driver.set_window_size(1600, 768)
656+
657+
def test_pie_chart_zero_annotation(self):
658+
Operator.objects.all().delete()
659+
self.login()
660+
url = reverse('admin:index')
661+
self.open(url)
662+
try:
663+
WebDriverWait(self.web_driver, 10).until(
664+
EC.visibility_of_element_located(
665+
(
666+
By.CSS_SELECTOR,
667+
'.operator-project-distribution .annotation-text tspan',
668+
)
669+
)
670+
)
671+
except TimeoutException:
672+
self.fail('Failed to find annotation text element in the chart')
673+
else:
674+
annotation_text = self.web_driver.find_element_by_css_selector(
675+
'.operator-project-distribution .annotation-text tspan'
676+
)
677+
self.assertEqual(annotation_text.text, '0')

0 commit comments

Comments
 (0)