Skip to content

Commit 691f8aa

Browse files
committed
Merge branch 'release/v1.3.1'
2 parents 788857b + e79d198 commit 691f8aa

File tree

10 files changed

+161
-42
lines changed

10 files changed

+161
-42
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.3.1] - 2024-06-16
6+
- Fix issue with Line Chart on highcharts engine
7+
- Reintroduce the stacking option on highcharts engine.
8+
- Fix issue with having different version of the same chart on the same page.
9+
- Enhanced the demo dashboard to show more capabilities regarding the charts.
10+
511
## [1.3.0] - 2023-11-08
612
- Implement Slick reporting media override feature + docs
713
- Add `Integrating reports into your Admin site` section to the docs

demo_proj/demo_app/reports.py

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -601,20 +601,83 @@ class ChartJSExample(TimeSeriesReport):
601601
title_source=["name"],
602602
plot_total=True,
603603
),
604+
# Chart(
605+
# "Total Sales [Line details]",
606+
# Chart.LINE,
607+
# data_source=["sum__value"],
608+
# title_source=["name"],
609+
# # plot_total=True,
610+
# ),
611+
]
612+
613+
614+
class HighChartExample(TimeSeriesReport):
615+
chart_engine = "highcharts"
616+
report_title = _("Highcharts Examples ")
617+
618+
chart_settings = [
619+
Chart("Client Sales [Column]", Chart.COLUMN, data_source=["sum__value"], title_source=["name"]),
620+
Chart(
621+
"Stacking Client Sales [Column]",
622+
Chart.COLUMN,
623+
data_source=["sum__value"],
624+
title_source=["name"],
625+
stacking=True,
626+
),
627+
Chart(
628+
"Total Client Sales[Column]",
629+
Chart.COLUMN,
630+
data_source=["sum__value"],
631+
title_source=["name"],
632+
plot_total=True,
633+
),
604634
Chart(
605-
"Total Sales [Line details]",
635+
"Stacking Total Client Sales [Column]",
636+
Chart.COLUMN,
637+
data_source=["sum__value"],
638+
title_source=["name"],
639+
plot_total=True,
640+
stacking=True,
641+
),
642+
Chart(
643+
"Client Sales [Bar]",
644+
Chart.BAR,
645+
data_source=["sum__value"],
646+
title_source=["name"],
647+
),
648+
Chart(
649+
"Total Client Sales [Bar]", Chart.BAR, data_source=["sum__value"], title_source=["name"], plot_total=True
650+
),
651+
Chart(
652+
"Client Sales [Line]",
606653
Chart.LINE,
607654
data_source=["sum__value"],
608655
title_source=["name"],
609656
# plot_total=True,
610657
),
658+
Chart(
659+
"Total Client Sales [Line]",
660+
Chart.LINE,
661+
data_source=["sum__value"],
662+
title_source=["name"],
663+
plot_total=True,
664+
),
665+
Chart(
666+
"Total Sales [Pie]",
667+
Chart.PIE,
668+
data_source=["sum__value"],
669+
title_source=["name"],
670+
plot_total=True,
671+
),
672+
Chart(
673+
"Client Sales [Area]",
674+
Chart.AREA,
675+
data_source=["sum__value"],
676+
title_source=["name"],
677+
),
611678
]
612679

613680

614-
class HighChartExample(ChartJSExample):
615-
chart_engine = "highcharts"
616-
617-
618681
class ProductSalesApexChart(ReportView):
619682
report_title = _("Product Sales Apex Charts")
620683
report_model = SalesTransaction

demo_proj/templates/dashboard.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,16 @@
99
<div class="col-lg-6">
1010
{% get_widget_from_url url_name="product-sales" %}
1111
</div>
12-
<div class="col-lg-6">
13-
{% get_widget_from_url url_name="total-product-sales" title="Widget custom title" %}
12+
<div class="col-lg-6">
13+
{% get_widget_from_url url_name="total-product-sales-by-country" title="Widget custom title" %}
1414
</div>
1515

1616
<div class="col-lg-6">
1717
{% get_widget_from_url url_name="total-product-sales" chart_id=1 title="Custom default Chart" %}
1818
</div>
1919

2020
<div class="col-lg-6">
21-
{% get_widget_from_url url_name="total-product-sales" display_table=False title="No table, Chart Only" %}
21+
{% get_widget_from_url url_name="monthly-product-sales" chart_id=1 display_table=False title="No table, Chart Only" %}
2222
</div>
2323

2424
<div class="col-lg-6">

demo_proj/templates/menu.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
174174
</span>
175175
<span class="nav-link-title">
176-
HighCharts
176+
HighCharts Charts Demo
177177
</span>
178178
</a>
179179
</li>
@@ -188,7 +188,7 @@
188188
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
189189
</span>
190190
<span class="nav-link-title">
191-
ChartsJS
191+
Charts.js Charts
192192
</span>
193193
</a>
194194
</li>
@@ -202,7 +202,7 @@
202202
d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"/></svg>
203203
</span>
204204
<span class="nav-link-title">
205-
Apex Chart Demo
205+
Apex Charts
206206
</span>
207207
</a>
208208
</li>

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ install_requires =
4949
pytz
5050
simplejson
5151
django-crispy-forms
52-
crispy-bootstrap4
52+
5353

5454

5555

slick_reporting/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
default_app_config = "slick_reporting.apps.ReportAppConfig"
22

3-
VERSION = (1, 3, 0)
3+
VERSION = (1, 3, 1)
44

5-
__version__ = "1.3.0"
5+
__version__ = "1.3.1"

slick_reporting/generator.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class Chart:
2222
data_source: list
2323
title_source: list
2424
plot_total: bool = False
25+
stacking: bool = False # only for highcharts
2526
engine: str = ""
2627
entryPoint: str = ""
2728
COLUMN = "column"
@@ -39,6 +40,7 @@ def to_dict(self):
3940
plot_total=self.plot_total,
4041
engine=self.engine,
4142
entryPoint=self.entryPoint,
43+
stacking=self.stacking,
4244
)
4345

4446

@@ -938,7 +940,7 @@ def get_full_response(
938940
@staticmethod
939941
def get_chart_settings(chart_settings=None, default_chart_title=None, chart_engine=None):
940942
"""
941-
Ensure the sane settings are passed to the front end.
943+
Ensure the sane settings are passed to the front end. ?
942944
"""
943945
chart_engine = chart_engine or SLICK_REPORTING_DEFAULT_CHARTS_ENGINE
944946
output = []
@@ -959,6 +961,7 @@ def get_chart_settings(chart_settings=None, default_chart_title=None, chart_engi
959961
chart.get("entryPoint")
960962
or app_settings.SLICK_REPORTING_SETTINGS["CHARTS"][chart["engine_name"]]["entryPoint"]
961963
)
964+
chart["stacking"] = chart.get("stacking", False)
962965

963966
output.append(chart)
964967
return output

slick_reporting/static/slick_reporting/slick_reporting.chartsjs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
function is_time_series(response, chartOptions) {
1212
if (chartOptions.time_series_support === false) return false;
13-
return response['metadata']['time_series_pattern'] !== ""
13+
return response['metadata']['time_series_pattern'] == ""
1414
}
1515

1616
function getTimeSeriesColumnNames(response) {
@@ -83,7 +83,7 @@
8383
txt = $(txt).text() || txt; // the title is an <a tag , we want teh text only
8484
legendResults.push(txt)
8585
}
86-
datasetData.push(row[dataFieldName])
86+
datasetData.push(parseFloat(row[dataFieldName]))
8787
}
8888
return {
8989
'labels': legendResults,

slick_reporting/static/slick_reporting/slick_reporting.highchart.js

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
});
6161
chartOptions.data = response.data;
6262

63-
6463
let is_time_series = is_timeseries_support(response, chartOptions); // response.metadata.time_series_pattern || '';
6564
let is_crosstab = is_crosstab_support(response, chartOptions);
6665

@@ -183,6 +182,8 @@
183182
valueDecimals: 2
184183
}
185184
}
185+
186+
186187
} else if (chart_type === 'area') {
187188
highchart_object.chart.type = 'area';
188189

@@ -195,7 +196,8 @@
195196
}
196197
}
197198
} else if (chart_type === 'line') {
198-
var marker_enabled = true;
199+
let marker_enabled = true;
200+
highchart_object.chart.type = 'line';
199201
// disable marker when ticks are more then 12 , relying on the hover of the mouse ;
200202
try {
201203
if (highchart_object.series[0].data.length > 12) marker_enabled = false;
@@ -218,7 +220,11 @@
218220
}
219221

220222
if (is_time_series) {
221-
highchart_object.xAxis.categories = chart_data.titles;
223+
if (chartOptions.plot_total && chartOptions.type !== 'line') {
224+
highchart_object.xAxis.categories = [chartOptions.title]
225+
} else {
226+
highchart_object.xAxis.categories = chart_data.titles;
227+
}
222228
highchart_object.xAxis.tickmarkPlacement = 'on';
223229
if (chart_type !== 'line')
224230
highchart_object.tooltip.shared = false //Option here;
@@ -291,22 +297,32 @@
291297
})
292298
} else {
293299
let all_column_to_be_summed = []
300+
let data = []
294301
Object.keys(data_sources).forEach(function (series_cols, index) {
295302
all_column_to_be_summed = all_column_to_be_summed.concat(data_sources[series_cols]);
296303
})
297304
let totalValues = $.slick_reporting.calculateTotalOnObjectArray(response.data, all_column_to_be_summed)
298305

299306
Object.keys(data_sources).forEach(function (series_cols, index) {
300-
let data = []
301-
data_sources[series_cols].forEach(function (col, index) {
302307

303-
series.push({
304-
'name': response.metadata.time_series_column_verbose_names[index],
305-
data: [totalValues[col]]
306-
})
308+
data_sources[series_cols].forEach(function (col, index) {
309+
data.push(totalValues[col])
310+
if (chartOptions.type !== "line") {
311+
series.push({
312+
'name': response.metadata.time_series_column_verbose_names[index],
313+
data: [totalValues[col]]
314+
})
315+
}
307316
})
308317

309318
})
319+
if (chartOptions.type === "line") {
320+
series.push({
321+
'name': chartOptions.title,
322+
data: data
323+
})
324+
}
325+
310326
}
311327
return {
312328
'categories': response.metadata.time_series_column_verbose_names,
@@ -380,7 +396,8 @@
380396
}
381397

382398
let chart = $elem.find("div[data-inner-chart-container]")
383-
let cache_key = data.report_slug + ':' + chartOptions.id;
399+
400+
let cache_key = $.slick_reporting.get_xpath($elem) + ":" + data.report_slug + ':' + chartOptions.id;
384401
try {
385402
let existing_chart = _chart_cache[cache_key];
386403
if (typeof (existing_chart) !== 'undefined') {

slick_reporting/static/slick_reporting/slick_reporting.js

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
(function ($) {
22

33
function executeFunctionByName(functionName, context /*, args */) {
4-
let args = Array.prototype.slice.call(arguments, 2);
5-
let namespaces = functionName.split(".");
6-
let func = namespaces.pop();
7-
for (let i = 0; i < namespaces.length; i++) {
8-
context = context[namespaces[i]];
9-
}
10-
try {
11-
func = context[func];
12-
if (typeof func == 'undefined') {
13-
throw `Function ${functionName} is not found in the context ${context}`
4+
let args = Array.prototype.slice.call(arguments, 2);
5+
let namespaces = functionName.split(".");
6+
let func = namespaces.pop();
7+
for (let i = 0; i < namespaces.length; i++) {
8+
context = context[namespaces[i]];
149
}
10+
try {
11+
func = context[func];
12+
if (typeof func == 'undefined') {
13+
throw `Function ${functionName} is not found in the context ${context}`
14+
}
1515

16-
} catch (err) {
17-
console.error(`Function ${functionName} is not found in the context ${context}`, err)
16+
} catch (err) {
17+
console.error(`Function ${functionName} is not found in the context ${context}`, err)
18+
}
19+
return func.apply(context, args);
1820
}
19-
return func.apply(context, args);
20-
}
2121

2222
function getObjFromArray(objList, obj_key, key_value, failToFirst) {
2323
failToFirst = typeof (failToFirst) !== 'undefined';
@@ -64,12 +64,42 @@
6464
return total_container;
6565
}
6666

67+
function get_xpath($element, forceTree) {
68+
if ($element.length === 0) {
69+
return null;
70+
}
71+
72+
let element = $element[0];
73+
74+
if ($element.attr('id') && ((forceTree === undefined) || !forceTree)) {
75+
return '//*[@id="' + $element.attr('id') + '"]';
76+
} else {
77+
let paths = [];
78+
for (; element && element.nodeType === Node.ELEMENT_NODE; element = element.parentNode) {
79+
let index = 0;
80+
for (let sibling = element.previousSibling; sibling; sibling = sibling.previousSibling) {
81+
if (sibling.nodeType === Node.DOCUMENT_TYPE_NODE)
82+
continue;
83+
if (sibling.nodeName === element.nodeName)
84+
++index;
85+
}
86+
87+
var tagName = element.nodeName.toLowerCase();
88+
var pathIndex = (index ? '[' + (index + 1) + ']' : '');
89+
paths.splice(0, 0, tagName + pathIndex);
90+
}
91+
92+
return paths.length ? '/' + paths.join('/') : null;
93+
}
94+
}
95+
6796

6897
$.slick_reporting = {
6998
'getObjFromArray': getObjFromArray,
7099
'calculateTotalOnObjectArray': calculateTotalOnObjectArray,
71100
"executeFunctionByName": executeFunctionByName,
72-
defaults:{
101+
"get_xpath": get_xpath,
102+
defaults: {
73103
total_label: 'Total',
74104
}
75105

0 commit comments

Comments
 (0)