Add interval selector to modal line charts
Change-Id: I6b22d120989bbb159bdfba3767dc7d88a1d491f8
This commit is contained in:
parent
c6329f592b
commit
c550d330e1
@ -12,7 +12,6 @@ horizon.d3_modal_line_chart = {
|
||||
init: function() {
|
||||
var self = this;
|
||||
|
||||
// Load modals for modal chart links
|
||||
$(document).on('click', '.modal_chart', function (evt) {
|
||||
evt.preventDefault();
|
||||
var $this = $(this);
|
||||
@ -23,50 +22,65 @@ horizon.d3_modal_line_chart = {
|
||||
var modal = $('.modal:last');
|
||||
modal.modal();
|
||||
|
||||
$(modal).on('click', 'ul#interval_selector li a', function(event){
|
||||
event.preventDefault();
|
||||
|
||||
interval = $(event.target).data("interval");
|
||||
self.draw('/infrastructure/resource_management/racks/usage_data', {interval: interval});
|
||||
|
||||
$("ul#interval_selector li").removeClass("active");
|
||||
$(event.target).parent().addClass("active");
|
||||
})
|
||||
|
||||
self.init_svg();
|
||||
self.draw('/infrastructure/resource_management/racks/usage_data')
|
||||
});
|
||||
},
|
||||
|
||||
draw: function(url) {
|
||||
init_svg: function() {
|
||||
var self = this;
|
||||
|
||||
var margin = {top: 20, right: 80, bottom: 30, left: 50};
|
||||
var width = 700 - margin.left - margin.right;
|
||||
var height = 400 - margin.top - margin.bottom;
|
||||
self.margin = {top: 20, right: 80, bottom: 30, left: 50};
|
||||
self.width = 700 - self.margin.left - self.margin.right;
|
||||
self.height = 400 - self.margin.top - self.margin.bottom;
|
||||
|
||||
var svg = d3.select("#modal_chart")
|
||||
.append("svg")
|
||||
.attr("width", width + margin.left + margin.right)
|
||||
.attr("height", height + margin.top + margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
|
||||
self.svg = d3.select("#modal_chart")
|
||||
.append("svg")
|
||||
.attr("width", self.width + self.margin.left + self.margin.right)
|
||||
.attr("height", self.height + self.margin.top + self.margin.bottom)
|
||||
.append("g")
|
||||
.attr("transform", "translate(" + self.margin.left + "," + self.margin.top + ")");
|
||||
|
||||
var x = d3.time.scale().range([0, width]);
|
||||
var y = d3.scale.linear().range([height, 0]);
|
||||
self.x = d3.time.scale().range([0, self.width]);
|
||||
self.y = d3.scale.linear().range([self.height, 0]);
|
||||
|
||||
var xAxis = d3.svg.axis()
|
||||
.scale(x)
|
||||
.orient("bottom");
|
||||
var yAxis = d3.svg.axis()
|
||||
.scale(y)
|
||||
.orient("left");
|
||||
self.xAxis = d3.svg.axis()
|
||||
.scale(self.x)
|
||||
.orient("bottom").ticks(6);
|
||||
self.yAxis = d3.svg.axis()
|
||||
.scale(self.y)
|
||||
.orient("left");
|
||||
|
||||
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%L").parse;
|
||||
self.parse_date = d3.time.format("%Y-%m-%dT%H:%M:%S.%L").parse;
|
||||
|
||||
var line = d3.svg.line().interpolate("linear")
|
||||
.x(function(d) { return x(d.date); })
|
||||
.y(function(d) { return y(d.value); });
|
||||
self.line = d3.svg.line().interpolate("linear")
|
||||
.x(function(d) { return self.x(d.date); })
|
||||
.y(function(d) { return self.y(d.value); });
|
||||
|
||||
var color = d3.scale.category10();
|
||||
self.color = d3.scale.category10();
|
||||
},
|
||||
|
||||
d3.json(url, function(error, data) {
|
||||
data.forEach(function(d) {
|
||||
d.date = parseDate(d.date);
|
||||
});
|
||||
draw: function(url, url_options) {
|
||||
var self = this;
|
||||
var url_options = url_options || {};
|
||||
url_options.interval = url_options.interval || "1w";
|
||||
|
||||
color.domain(d3.keys(data[0]).filter(function(key) { return key !== 'date'; }));
|
||||
d3.json(self.data_url(url, url_options), function(error, data) {
|
||||
data.forEach(function(d) { d.date = self.parse_date(d.date); });
|
||||
|
||||
var usage_values = color.domain().map(function(name) {
|
||||
self.color.domain(d3.keys(data[0]).filter(function(key) { return key !== 'date'; }));
|
||||
|
||||
var usage_values = self.color.domain().map(function(name) {
|
||||
return {
|
||||
name: name,
|
||||
values: data.map(function(d) {
|
||||
@ -75,32 +89,42 @@ horizon.d3_modal_line_chart = {
|
||||
};
|
||||
});
|
||||
|
||||
x.domain(d3.extent(data, function(d) { return d.date; }));
|
||||
y.domain([
|
||||
d3.min(usage_values, function(u) { return d3.min(u.values, function(v) { return v.value; }) - 1; }),
|
||||
d3.max(usage_values, function(u) { return d3.max(u.values, function(v) { return v.value; }) + 6; })
|
||||
]);
|
||||
self.svg.selectAll(".axis").remove();
|
||||
self.x.domain(d3.extent(data, function(d) { return d.date; }));
|
||||
self.y.domain([0, 15]);
|
||||
|
||||
svg.append("g")
|
||||
.attr("transform", "translate(0," + height + ")")
|
||||
.attr("class", "axis")
|
||||
.call(xAxis);
|
||||
svg.append("g")
|
||||
.attr("class", "axis")
|
||||
.call(yAxis)
|
||||
self.svg.append("g")
|
||||
.attr("transform", "translate(0," + self.height + ")")
|
||||
.attr("class", "axis")
|
||||
.call(self.xAxis);
|
||||
self.svg.append("g")
|
||||
.attr("class", "axis")
|
||||
.call(self.yAxis)
|
||||
|
||||
var usage = svg.selectAll(".usage")
|
||||
.data(usage_values)
|
||||
.enter().append("g");
|
||||
var usages = self.svg.selectAll(".usage")
|
||||
.data(usage_values, function(d) { return self.key(d) });
|
||||
|
||||
var usage = usages.enter().append("g")
|
||||
.attr("class", "usage");
|
||||
|
||||
usage.append("path")
|
||||
.attr("d", function(d) { return line(d.values); })
|
||||
.style("stroke", function(d) { return color(d.name); })
|
||||
.style("fill", "none")
|
||||
.style("stroke-width", 3);
|
||||
.attr("d", function(d) { return self.line(d.values); })
|
||||
.style("stroke", function(d) { return self.color(d.name); })
|
||||
.style("fill", "none")
|
||||
.style("stroke-width", 3);
|
||||
|
||||
usages.exit().remove();
|
||||
});
|
||||
},
|
||||
|
||||
data_url: function(url, options) {
|
||||
return url + '?' + $.param(options);
|
||||
},
|
||||
|
||||
key: function(data){
|
||||
return data.name + data.values.length + data.values[0].date + data.values[data.values.length-1].date
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
horizon.addInitFunction(function () {
|
||||
|
@ -6,6 +6,13 @@
|
||||
{% block template %}
|
||||
{% jstemplate %}
|
||||
<div class="modal" style="top: 80px; display: block;">
|
||||
<ul id="interval_selector">
|
||||
<li><a href="#" data-interval="12h">12h</a></li>
|
||||
<li><a href="#" data-interval="24h">24h</a></li>
|
||||
<li class="active"><a href="#" data-interval="1w">1w</a></li>
|
||||
<li><a href="#" data-interval="1m">1m</a></li>
|
||||
<li><a href="#" data-interval="1y">1y</a></li>
|
||||
</ul>
|
||||
<div id="modal_chart"></div>
|
||||
</div>
|
||||
{% endjstemplate %}
|
||||
|
@ -108,9 +108,29 @@ class DetailView(tabs.TabView):
|
||||
class UsageDataView(View):
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
interval = request.GET.get('interval', '1w')
|
||||
|
||||
if interval == '12h':
|
||||
data_count = 12
|
||||
timedelta_param = 'hours'
|
||||
elif interval == '24h':
|
||||
data_count = 24
|
||||
timedelta_param = 'hours'
|
||||
elif interval == '1m':
|
||||
data_count = 30
|
||||
timedelta_param = 'days'
|
||||
elif interval == '1y':
|
||||
data_count = 52
|
||||
timedelta_param = 'weeks'
|
||||
else:
|
||||
# default is 1 week
|
||||
data_count = 7
|
||||
timedelta_param = 'days'
|
||||
|
||||
values = []
|
||||
for i in range(10):
|
||||
values.append({'date': datetime.now() + timedelta(days=i),
|
||||
for i in range(data_count):
|
||||
timediff = timedelta(**{timedelta_param: i})
|
||||
values.append({'date': datetime.now() - timediff,
|
||||
'ram': random.randint(1, 9)})
|
||||
|
||||
return HttpResponse(json.dumps(values, cls=DjangoJSONEncoder),
|
||||
|
@ -19,6 +19,30 @@ table.capacities{
|
||||
}
|
||||
|
||||
|
||||
#interval_selector {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 15px;
|
||||
|
||||
li {
|
||||
display: inline;
|
||||
list-style-type: none;
|
||||
padding-right: 5px;
|
||||
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
|
||||
a {
|
||||
color: black;
|
||||
|
||||
&:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
.axis {
|
||||
path, line {
|
||||
|
Loading…
x
Reference in New Issue
Block a user