kanaui 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/kanaui/kiddo/axes.js +5 -7
- data/app/assets/javascripts/kanaui/kiddo/charts/line_chart.js +41 -52
- data/app/assets/javascripts/kanaui/kiddo/charts/pie_chart.js +18 -13
- data/app/assets/javascripts/kanaui/kiddo/charts/utils/mouse_over.js +23 -13
- data/app/assets/javascripts/kanaui/kiddo/helper.js +91 -4
- data/app/assets/javascripts/kanaui/kiddo/kiddo_initialize.js +29 -6
- data/app/assets/javascripts/kanaui/kiddo/settings.js +1 -0
- data/app/assets/stylesheets/kanaui/kanaui.css +103 -18
- data/app/assets/stylesheets/kanaui/reports.css +85 -0
- data/app/controllers/kanaui/dashboard_controller.rb +20 -17
- data/app/controllers/kanaui/engine_controller.rb +21 -2
- data/app/controllers/kanaui/reports_controller.rb +22 -13
- data/app/helpers/kanaui/dashboard_helper.rb +9 -3
- data/app/views/kanaui/dashboard/index.html.erb +48 -17
- data/app/views/kanaui/layouts/kanaui_application.html.erb +11 -15
- data/app/views/kanaui/reports/_form.html.erb +124 -23
- data/app/views/kanaui/reports/_reports_table.html.erb +22 -17
- data/app/views/kanaui/reports/edit.html.erb +1 -1
- data/app/views/kanaui/reports/index.html.erb +6 -3
- data/app/views/kanaui/reports/new.html.erb +1 -1
- data/config/locales/en.bootstrap.yml +64 -0
- data/config/routes.rb +3 -3
- data/lib/kanaui/engine.rb +0 -1
- data/lib/kanaui/version.rb +1 -1
- data/vendor/assets/javascripts/d3.js +2 -0
- data/vendor/assets/javascripts/log4javascript.js +274 -0
- metadata +4 -16
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0c74b8f72b208b13b20e079654c00f793b3d0c663cd33f9dbb4957aa6fd420e6
|
|
4
|
+
data.tar.gz: 859e32a01514363bb64f4c3772c0d6b70b2ed72fb0daa0d4bda8facef7bba877
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52219b23e1cdd624809a26bc71ab8ea903d3c649ff5e5e6d3fe74538c850341680a189d9e50f1c19097df907430b49dc27009f63319a27f110635b3a4afa6589
|
|
7
|
+
data.tar.gz: 2606b237d12c8e5f4ecf5bcca19bed63ef34eb38c0adb862f4924f3e3d6afe898fdccf53474d328d49cbaa9026d38253f88e4306f5049937c9fd46ccb4601336
|
|
@@ -3,14 +3,12 @@
|
|
|
3
3
|
var self = this;
|
|
4
4
|
|
|
5
5
|
var makeXAxis = function () {
|
|
6
|
-
return d3.
|
|
6
|
+
return d3.axisBottom(self.x).ticks(6);
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
var makeYAxis = function () {
|
|
10
|
-
return d3
|
|
11
|
-
.
|
|
12
|
-
.scale(self.y)
|
|
13
|
-
.orient("left")
|
|
10
|
+
return d3
|
|
11
|
+
.axisLeft(self.y)
|
|
14
12
|
.tickFormat(d3.format(",d"));
|
|
15
13
|
};
|
|
16
14
|
|
|
@@ -28,13 +26,13 @@
|
|
|
28
26
|
"transform",
|
|
29
27
|
"translate(" + self.margin_left + "," + self.height + ")"
|
|
30
28
|
)
|
|
31
|
-
.call(makeXAxis().tickSize(-self.height
|
|
29
|
+
.call(makeXAxis().tickSize(-self.height).tickFormat(""));
|
|
32
30
|
|
|
33
31
|
svg
|
|
34
32
|
.append("g")
|
|
35
33
|
.attr("class", "grid")
|
|
36
34
|
.attr("transform", "translate(" + self.margin_left + ",0)")
|
|
37
|
-
.call(makeYAxis().tickSize(-self.width
|
|
35
|
+
.call(makeYAxis().tickSize(-self.width).tickFormat(""));
|
|
38
36
|
|
|
39
37
|
svg
|
|
40
38
|
.append("g")
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Kiddo.LineChart = function () {
|
|
3
3
|
var self = this;
|
|
4
4
|
|
|
5
|
-
this.x = d3.
|
|
6
|
-
this.y = d3.
|
|
5
|
+
this.x = d3.scaleTime().range([0, this.width]);
|
|
6
|
+
this.y = d3.scaleLinear().range([this.height, 0]);
|
|
7
7
|
|
|
8
|
-
var valueline = d3
|
|
8
|
+
var valueline = d3
|
|
9
9
|
.line()
|
|
10
10
|
.x(function (d) {
|
|
11
11
|
return self.x(d.x);
|
|
@@ -13,80 +13,79 @@
|
|
|
13
13
|
.y(function (d) {
|
|
14
14
|
return self.y(d.y);
|
|
15
15
|
})
|
|
16
|
-
.
|
|
16
|
+
.curve(d3.curveMonotoneX);
|
|
17
17
|
|
|
18
18
|
var axes = Kiddo.Axes.apply(this);
|
|
19
19
|
var helper = new Kiddo.Helper();
|
|
20
20
|
|
|
21
|
-
// Custom
|
|
22
|
-
var
|
|
23
|
-
"#
|
|
24
|
-
"#
|
|
25
|
-
"#
|
|
26
|
-
"#
|
|
27
|
-
"#
|
|
28
|
-
"#
|
|
29
|
-
"#
|
|
30
|
-
"#
|
|
21
|
+
// Custom multi-color theme matching the image
|
|
22
|
+
var colors = [
|
|
23
|
+
"#2196F3", // blue
|
|
24
|
+
"#E53935", // red
|
|
25
|
+
"#43A047", // green
|
|
26
|
+
"#FB8C00", // orange
|
|
27
|
+
"#8E24AA", // purple
|
|
28
|
+
"#00ACC1", // cyan
|
|
29
|
+
"#F4511E", // deep orange
|
|
30
|
+
"#6D4C41", // brown
|
|
31
31
|
];
|
|
32
|
-
self.color = d3.
|
|
32
|
+
self.color = d3.scaleOrdinal().range(colors);
|
|
33
33
|
|
|
34
34
|
return {
|
|
35
35
|
render: function (svg, json) {
|
|
36
36
|
var title = json.title,
|
|
37
37
|
datasets = json.data;
|
|
38
38
|
|
|
39
|
+
datasets.forEach(function (dataset) {
|
|
40
|
+
dataset.values.forEach(function (d) {
|
|
41
|
+
d.date = d.x.split("T")[0];
|
|
42
|
+
d.x = helper.parseDate(d.date);
|
|
43
|
+
d.y = +d.y;
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
39
47
|
// Scale the range of the data before rendering axes
|
|
40
48
|
var allValues = datasets.reduce(function (result, element) {
|
|
41
49
|
return result.concat(element.values);
|
|
42
50
|
}, []);
|
|
43
51
|
|
|
44
52
|
var x_domain = d3.extent(allValues, function (d) {
|
|
45
|
-
return
|
|
53
|
+
return d.x;
|
|
46
54
|
});
|
|
47
55
|
|
|
48
56
|
self.x.domain(x_domain);
|
|
49
57
|
|
|
50
|
-
var y_domain =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return d.y;
|
|
54
|
-
});
|
|
55
|
-
}),
|
|
56
|
-
d3.max(datasets, function (datum) {
|
|
57
|
-
return d3.max(datum.values, function (d) {
|
|
58
|
-
return d.y;
|
|
59
|
-
});
|
|
60
|
-
}),
|
|
61
|
-
];
|
|
58
|
+
var y_domain = d3.extent(allValues, function (d) {
|
|
59
|
+
return d.y;
|
|
60
|
+
});
|
|
62
61
|
|
|
63
62
|
self.y.domain(y_domain);
|
|
64
63
|
|
|
65
64
|
// Render axes first
|
|
66
65
|
axes.render(svg, title);
|
|
67
66
|
|
|
68
|
-
self.color.domain(
|
|
67
|
+
self.color.domain(datasets.map(function (dataset) {
|
|
68
|
+
return dataset.name;
|
|
69
|
+
}));
|
|
69
70
|
|
|
70
|
-
// Create legend container
|
|
71
|
+
// Create legend container to the right of the chart area
|
|
71
72
|
var legendContainer = svg
|
|
72
73
|
.append("g")
|
|
73
74
|
.attr("class", "chart-legend")
|
|
74
|
-
.attr("transform", "translate(" + (self.width
|
|
75
|
+
.attr("transform", "translate(" + (self.width + self.margin_left + 15) + ", 10)");
|
|
75
76
|
|
|
76
77
|
// Calculate total values for legend
|
|
77
78
|
var legendData = datasets.map(function (dataset, index) {
|
|
78
79
|
var latestValue = dataset.values[dataset.values.length - 1];
|
|
79
|
-
var totalCount = dataset.values.length;
|
|
80
80
|
return {
|
|
81
81
|
name: dataset.name,
|
|
82
82
|
value: latestValue ? latestValue.y : 0,
|
|
83
|
-
count: totalCount,
|
|
84
83
|
color: self.color(dataset.name),
|
|
85
84
|
index: index,
|
|
86
85
|
};
|
|
87
86
|
});
|
|
88
87
|
|
|
89
|
-
// Create legend items
|
|
88
|
+
// Create legend items as a vertical column
|
|
90
89
|
var legendItems = legendContainer
|
|
91
90
|
.selectAll(".legend-item")
|
|
92
91
|
.data(legendData)
|
|
@@ -94,34 +93,30 @@
|
|
|
94
93
|
.append("g")
|
|
95
94
|
.attr("class", "legend-item");
|
|
96
95
|
|
|
97
|
-
var
|
|
98
|
-
legendItems.each(function (d
|
|
96
|
+
var yOffset = 0;
|
|
97
|
+
legendItems.each(function (d) {
|
|
99
98
|
var legendItem = d3.select(this);
|
|
100
99
|
|
|
101
|
-
// Add colored circle
|
|
102
100
|
legendItem
|
|
103
101
|
.append("circle")
|
|
104
|
-
.attr("cx",
|
|
105
|
-
.attr("cy",
|
|
102
|
+
.attr("cx", 6)
|
|
103
|
+
.attr("cy", yOffset)
|
|
106
104
|
.attr("r", 6)
|
|
107
105
|
.style("fill", d.color);
|
|
108
106
|
|
|
109
|
-
// Add text label
|
|
110
107
|
var labelText =
|
|
111
|
-
d.name
|
|
108
|
+
helper.formatSeriesName(d.name, self.reportName) + ": " + helper.formatValue(d.value);
|
|
112
109
|
legendItem
|
|
113
110
|
.append("text")
|
|
114
|
-
.attr("x",
|
|
115
|
-
.attr("y",
|
|
111
|
+
.attr("x", 18)
|
|
112
|
+
.attr("y", yOffset)
|
|
116
113
|
.attr("dy", "0.35em")
|
|
117
114
|
.style("font-size", "0.875rem")
|
|
118
115
|
.style("font-weight", "500")
|
|
119
116
|
.style("fill", "#6B7280")
|
|
120
117
|
.text(labelText);
|
|
121
118
|
|
|
122
|
-
|
|
123
|
-
var textWidth = this.getBBox().width;
|
|
124
|
-
xOffset += textWidth + 40; // Add spacing between items
|
|
119
|
+
yOffset += 22;
|
|
125
120
|
});
|
|
126
121
|
|
|
127
122
|
// Render data lines
|
|
@@ -129,12 +124,6 @@
|
|
|
129
124
|
var data = dataset.values,
|
|
130
125
|
name = dataset.name;
|
|
131
126
|
|
|
132
|
-
data.forEach(function (d) {
|
|
133
|
-
d.date = d.x.split("T")[0]; // Support both date and date/times
|
|
134
|
-
d.x = helper.parseDate(d.date);
|
|
135
|
-
d.y = +d.y;
|
|
136
|
-
});
|
|
137
|
-
|
|
138
127
|
svg
|
|
139
128
|
.append("path")
|
|
140
129
|
.attr("class", "line")
|
|
@@ -2,26 +2,27 @@
|
|
|
2
2
|
Kiddo.PieChart = function () {
|
|
3
3
|
var self = this;
|
|
4
4
|
var radius = Math.min(this.width, this.height) / 2;
|
|
5
|
+
var helper = new Kiddo.Helper();
|
|
5
6
|
|
|
6
7
|
// Custom blue color theme - matching the line chart
|
|
7
|
-
var
|
|
8
|
-
"#
|
|
9
|
-
"#
|
|
10
|
-
"#
|
|
11
|
-
"#
|
|
12
|
-
"#
|
|
13
|
-
"#
|
|
14
|
-
"#
|
|
15
|
-
"#
|
|
8
|
+
var colors = [
|
|
9
|
+
"#2196F3", // blue
|
|
10
|
+
"#E53935", // red
|
|
11
|
+
"#43A047", // green
|
|
12
|
+
"#FB8C00", // orange
|
|
13
|
+
"#8E24AA", // purple
|
|
14
|
+
"#00ACC1", // cyan
|
|
15
|
+
"#F4511E", // deep orange
|
|
16
|
+
"#6D4C41", // brown
|
|
16
17
|
];
|
|
17
|
-
var color = d3.
|
|
18
|
+
var color = d3.scaleOrdinal().range(colors);
|
|
18
19
|
|
|
19
|
-
var arc = d3
|
|
20
|
+
var arc = d3
|
|
20
21
|
.arc()
|
|
21
22
|
.outerRadius(radius - 10)
|
|
22
23
|
.innerRadius(0);
|
|
23
24
|
|
|
24
|
-
var pie = d3
|
|
25
|
+
var pie = d3
|
|
25
26
|
.pie()
|
|
26
27
|
.sort(null)
|
|
27
28
|
.value(function (d) {
|
|
@@ -41,6 +42,10 @@
|
|
|
41
42
|
d.value = +d.value;
|
|
42
43
|
});
|
|
43
44
|
|
|
45
|
+
color.domain(data.map(function (d, index) {
|
|
46
|
+
return index;
|
|
47
|
+
}));
|
|
48
|
+
|
|
44
49
|
var g = svg
|
|
45
50
|
.selectAll(".arc")
|
|
46
51
|
.data(pie(data))
|
|
@@ -74,7 +79,7 @@
|
|
|
74
79
|
})
|
|
75
80
|
.html(function (d, i) {
|
|
76
81
|
return (
|
|
77
|
-
colorCircle(d.data.value, i) + d.data.label + ": " + d.data.value
|
|
82
|
+
colorCircle(d.data.value, i) + helper.formatSeriesName(d.data.label) + ": " + d.data.value
|
|
78
83
|
);
|
|
79
84
|
})
|
|
80
85
|
.attr("class", "chart_values");
|
|
@@ -59,15 +59,16 @@
|
|
|
59
59
|
var infoBox = info.node().getBBox();
|
|
60
60
|
var infoTitleBox = infoTitle.node().getBBox();
|
|
61
61
|
var margin = 40;
|
|
62
|
+
var minWidth = Math.max(box.width, infoTitleBox.width) + margin;
|
|
62
63
|
|
|
63
64
|
info.attr("height", infoBox.height + box.height + 7);
|
|
64
|
-
if (infoBox.width <
|
|
65
|
-
info.attr("width",
|
|
66
|
-
infoTitleBg.attr("width",
|
|
65
|
+
if (infoBox.width < minWidth) {
|
|
66
|
+
info.attr("width", minWidth);
|
|
67
|
+
infoTitleBg.attr("width", minWidth);
|
|
67
68
|
|
|
68
69
|
$("#mouseover_canvas #info-title").attr(
|
|
69
70
|
"dx",
|
|
70
|
-
|
|
71
|
+
minWidth / 2 - infoTitleBox.width / 2
|
|
71
72
|
);
|
|
72
73
|
}
|
|
73
74
|
};
|
|
@@ -80,8 +81,10 @@
|
|
|
80
81
|
.attr("transform", "translate(" + self.margin_left + ",0)");
|
|
81
82
|
});
|
|
82
83
|
|
|
83
|
-
function mousemove() {
|
|
84
|
-
var
|
|
84
|
+
function mousemove(event) {
|
|
85
|
+
var pointer = d3.pointer(event, this);
|
|
86
|
+
var mouseX = pointer[0];
|
|
87
|
+
var mouseY = pointer[1];
|
|
85
88
|
|
|
86
89
|
$("#mouseover_canvas .chart_values").detach().remove();
|
|
87
90
|
$("#mouseover_canvas .chart_circles").detach().remove();
|
|
@@ -94,7 +97,7 @@
|
|
|
94
97
|
var data = element.values;
|
|
95
98
|
var name = element.name;
|
|
96
99
|
|
|
97
|
-
var x0 = x.invert(
|
|
100
|
+
var x0 = x.invert(mouseX),
|
|
98
101
|
i = helper.bisectDate(data, x0, 1),
|
|
99
102
|
d0 = data[i - 1],
|
|
100
103
|
d1 = data[i];
|
|
@@ -115,11 +118,7 @@
|
|
|
115
118
|
.attr("cy", y(d.y))
|
|
116
119
|
.style("fill", self.color(name));
|
|
117
120
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
canvas.attr("transform", "translate(" + canvasPosition + ",0)");
|
|
121
|
-
|
|
122
|
-
canvas.select("#info-title").text(d.date);
|
|
121
|
+
canvas.select("#info-title").text(helper.formatDate(d.date));
|
|
123
122
|
|
|
124
123
|
elementsForLegend.push({ element: element, d: d });
|
|
125
124
|
});
|
|
@@ -150,11 +149,22 @@
|
|
|
150
149
|
.text(
|
|
151
150
|
element.d === undefined
|
|
152
151
|
? element.element.name
|
|
153
|
-
: helper.formatValueDisplay(element.element.name, element.d)
|
|
152
|
+
: helper.formatValueDisplay(element.element.name, element.d, self.reportName)
|
|
154
153
|
);
|
|
155
154
|
|
|
156
155
|
addInfoDimensions(text);
|
|
157
156
|
});
|
|
157
|
+
|
|
158
|
+
// Position tooltip to follow the cursor; flip left when near the right edge.
|
|
159
|
+
var tooltipOffset = 15;
|
|
160
|
+
var tooltipWidth = info.node().getBBox().width;
|
|
161
|
+
var tooltipHeight = info.node().getBBox().height;
|
|
162
|
+
var localX = (mouseX + tooltipOffset + tooltipWidth > self.width)
|
|
163
|
+
? mouseX - tooltipWidth - tooltipOffset
|
|
164
|
+
: mouseX + tooltipOffset;
|
|
165
|
+
var canvasX = localX + self.margin_left;
|
|
166
|
+
var canvasY = Math.max(0, mouseY - 150);
|
|
167
|
+
canvas.attr("transform", "translate(" + canvasX + "," + canvasY + ")");
|
|
158
168
|
}
|
|
159
169
|
},
|
|
160
170
|
};
|
|
@@ -1,19 +1,106 @@
|
|
|
1
1
|
(function (Kiddo, d3) {
|
|
2
2
|
Kiddo.Helper = function () {
|
|
3
|
+
var formatValue = function (d) {
|
|
4
|
+
return d % 1 === 0 ? d3.format(",d")(d) : d3.format(",.2f")(d);
|
|
5
|
+
};
|
|
3
6
|
var formatCurrency = function (d) {
|
|
4
7
|
return "$" + formatValue(d);
|
|
5
8
|
};
|
|
6
|
-
|
|
9
|
+
|
|
10
|
+
var humanizeSegment = function (segment) {
|
|
11
|
+
segment = String(segment || "")
|
|
12
|
+
.replace(/[_-]+/g, " ")
|
|
13
|
+
.replace(/\s+/g, " ")
|
|
14
|
+
.trim();
|
|
15
|
+
|
|
16
|
+
if (!segment) {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return segment
|
|
21
|
+
.split(" ")
|
|
22
|
+
.map(function (word) {
|
|
23
|
+
if (/^\d+(\.\d+)?$/.test(word)) {
|
|
24
|
+
return word;
|
|
25
|
+
}
|
|
26
|
+
if (/^[A-Z]{2,3}$/.test(word)) {
|
|
27
|
+
return word;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
31
|
+
})
|
|
32
|
+
.join(" ");
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
var formatSeriesName = function (name, reportName) {
|
|
36
|
+
return String(name || "")
|
|
37
|
+
.split(/\s*::\s*/)
|
|
38
|
+
.filter(function (segment) {
|
|
39
|
+
// Remove numeric-only segments (tenant record id)
|
|
40
|
+
return !/^\d+$/.test(segment.trim());
|
|
41
|
+
})
|
|
42
|
+
.map(function (segment) {
|
|
43
|
+
var parts = segment.split(/\s*:\s*/);
|
|
44
|
+
if (parts.length > 1) {
|
|
45
|
+
var qualifier = humanizeSegment(parts.slice(1).join(": "));
|
|
46
|
+
var label = (reportName && parts[0].trim().toLowerCase() === "count")
|
|
47
|
+
? reportName
|
|
48
|
+
: humanizeSegment(parts[0]);
|
|
49
|
+
|
|
50
|
+
// For count-based reports, a numeric qualifier is usually tenant id
|
|
51
|
+
// and should not be displayed in UI labels.
|
|
52
|
+
if (reportName && parts[0].trim().toLowerCase() === "count" && /^\d+$/.test(qualifier)) {
|
|
53
|
+
return label;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return label + " (" + qualifier + ")";
|
|
57
|
+
}
|
|
58
|
+
return humanizeSegment(segment);
|
|
59
|
+
})
|
|
60
|
+
.filter(function (segment) {
|
|
61
|
+
return segment.length > 0;
|
|
62
|
+
})
|
|
63
|
+
.join(" : ");
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// Extracts just the qualifier part (e.g. "EUR" from "count: EUR :: 1") for compact tooltip labels
|
|
67
|
+
var formatSeriesLabel = function (name) {
|
|
68
|
+
var segments = String(name || "")
|
|
69
|
+
.split(/\s*::\s*/)
|
|
70
|
+
.filter(function (segment) {
|
|
71
|
+
return !/^\d+$/.test(segment.trim());
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (segments.length === 0) return humanizeSegment(name);
|
|
75
|
+
|
|
76
|
+
var parts = segments[0].split(/\s*:\s*/);
|
|
77
|
+
if (parts.length > 1) {
|
|
78
|
+
return humanizeSegment(parts.slice(1).join(": "));
|
|
79
|
+
}
|
|
80
|
+
return humanizeSegment(segments[0]);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
var parseDateFn = d3.timeParse("%Y-%m-%d");
|
|
84
|
+
var formatDateFn = d3.timeFormat("%b %d, %Y");
|
|
85
|
+
var formatDate = function (dateStr) {
|
|
86
|
+
var parsed = parseDateFn(dateStr);
|
|
87
|
+
return parsed ? formatDateFn(parsed) : dateStr;
|
|
88
|
+
};
|
|
7
89
|
|
|
8
90
|
return {
|
|
9
|
-
parseDate:
|
|
91
|
+
parseDate: parseDateFn,
|
|
10
92
|
bisectDate: d3.bisector(function (d) {
|
|
11
93
|
return d.x;
|
|
12
94
|
}).left,
|
|
13
95
|
formatCurrency: formatCurrency,
|
|
14
96
|
formatValue: formatValue,
|
|
15
|
-
|
|
16
|
-
|
|
97
|
+
formatSeriesName: formatSeriesName,
|
|
98
|
+
formatDate: formatDate,
|
|
99
|
+
formatValueDisplay: function (name, d, reportName) {
|
|
100
|
+
var seriesLabel = reportName
|
|
101
|
+
? formatSeriesName(name, reportName)
|
|
102
|
+
: formatSeriesLabel(name);
|
|
103
|
+
return seriesLabel + ": " + formatValue(d.y);
|
|
17
104
|
},
|
|
18
105
|
};
|
|
19
106
|
};
|
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
(function (d3, $, window, document, undefined) {
|
|
2
|
+
function errorMessage(error) {
|
|
3
|
+
if (error && error.responseText) {
|
|
4
|
+
try {
|
|
5
|
+
var response = JSON.parse(error.responseText);
|
|
6
|
+
if (response.message) {
|
|
7
|
+
return response.message;
|
|
8
|
+
}
|
|
9
|
+
} catch (ex) {
|
|
10
|
+
return error.responseText;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return error && error.message ? error.message : String(error);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function renderError(message) {
|
|
18
|
+
var escapedMessage = $("<div/>").text(message).html();
|
|
19
|
+
$("#chartAnchor").prepend(
|
|
20
|
+
'<div class="alert alert-danger" role="alert">' + escapedMessage + "</div>"
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
2
24
|
$(document).ready(function () {
|
|
3
25
|
if ($("#chartAnchor").length == 0) {
|
|
4
26
|
return;
|
|
5
27
|
}
|
|
6
28
|
|
|
7
|
-
d3.json($("#chartAnchor").data("reports-path")
|
|
29
|
+
d3.json($("#chartAnchor").data("reports-path")).then(function (json) {
|
|
8
30
|
$("#loading-spinner").remove();
|
|
9
31
|
|
|
10
32
|
var renderer = new Kiddo.Renderer("#chartAnchor");
|
|
11
33
|
|
|
12
|
-
if (error) {
|
|
13
|
-
ajaxErrorAlert(error);
|
|
14
|
-
return renderer.noData();
|
|
15
|
-
}
|
|
16
|
-
|
|
17
34
|
var data = json[0];
|
|
18
35
|
|
|
19
36
|
if (
|
|
@@ -49,6 +66,12 @@
|
|
|
49
66
|
console.log(ex);
|
|
50
67
|
renderer.noData();
|
|
51
68
|
}
|
|
69
|
+
}).catch(function (error) {
|
|
70
|
+
$("#loading-spinner").remove();
|
|
71
|
+
|
|
72
|
+
var renderer = new Kiddo.Renderer("#chartAnchor");
|
|
73
|
+
renderError(errorMessage(error));
|
|
74
|
+
return renderer.noData();
|
|
52
75
|
});
|
|
53
76
|
});
|
|
54
77
|
})(d3, jQuery, window, document);
|