Vì D3.js v3 có bộ sưu tập đẹp là methods to load data from external resources ¹, Tốt hơn hết là bạn không nhúng dữ liệu vào trang của mình, bạn chỉ cần tải nó.
Đây sẽ là câu trả lời bằng ví dụ.
Hãy bắt đầu với một định nghĩa mô hình:
# models.py
from django.db import models
class Play(models.Model):
name = models.CharField(max_length=100)
date = models.DateTimeField()
Một URLconf:
# urls.py
from django.conf.urls import url
from .views import graph, play_count_by_month
urlpatterns = [
url(r'^$', graph),
url(r'^api/play_count_by_month', play_count_by_month, name='play_count_by_month'),
]
Chúng tôi đang sử dụng hai url, một trở về html (xem), và các url khác (xem play_count_by_month
) làm api để chỉ trả về dữ liệu dưới dạng JSON.
Và cuối cùng quan điểm của chúng tôi:
# views.py
from django.db import connections
from django.db.models import Count
from django.http import JsonResponse
from django.shortcuts import render
from .models import Play
def graph(request):
return render(request, 'graph/graph.html')
def play_count_by_month(request):
data = Play.objects.all() \
.extra(select={'month': connections[Play.objects.db].ops.date_trunc_sql('month', 'date')}) \
.values('month') \
.annotate(count_items=Count('id'))
return JsonResponse(list(data), safe=False)
Ở đây chúng ta định nghĩa một cái nhìn để trả lại dữ liệu của chúng tôi như JSON, lưu ý rằng tôi đã thay đổi thêm để có cơ sở dữ liệu thuyết bất khả tri, vì tôi đã thử nghiệm với SQLite.
Và sau mẫu của chúng tôi graph/graph.html
cho thấy một đồ thị của số lần nghe nhạc theo tháng:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y-%m-%d").parse; // for dates like "2014-01-01"
//var parseDate = d3.time.format("%Y-%m-%dT00:00:00Z").parse; // for dates like "2014-01-01T00:00:00Z"
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var line = d3.svg.line()
.x(function(d) { return x(d.month); })
.y(function(d) { return y(d.count_items); });
var svg = d3.select("body").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 + ")");
d3.json("{% url "play_count_by_month" %}", function(error, data) {
data.forEach(function(d) {
d.month = parseDate(d.month);
d.count_items = +d.count_items;
});
x.domain(d3.extent(data, function(d) { return d.month; }));
y.domain(d3.extent(data, function(d) { return d.count_items; }));
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Play count");
svg.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
});
</script>
</body>
</html>
này sẽ trả về một đồ thị đẹp như thế này (dữ liệu ngẫu nhiên):
Cập nhật 1: D3 v4 sẽ di chuyển mã để tải dữ liệu ngoài vào một lib chuyên dụng, vui lòng xem d3-request. Cập nhật 2: Để trợ giúp, tôi đã đặt tất cả các tệp lại với nhau thành một dự án mẫu, trên github: github.com/fgmacedo/django-d3-example
Bạn đang sử dụng Django 1.7? Tôi đã có giải pháp tùy chỉnh cho bạn, chỉ để xác minh rằng chúng tôi đang sử dụng cùng một phiên bản. –
Trên 1.4.1 nâng cấp khi chúng tôi nói và sau đó tôi sẽ thử câu trả lời của bạn. –
Ok. Đó là vì [django.http.JsonResponse] (https://docs.djangoproject.com/en/dev/ref/request-response/#jsonresponse-objects) đã được giới thiệu vào ngày 1.7. –