【问题标题】:Using Django, AJAX and JSONs to update charts based on user input使用 Django、AJAX 和 JSON 根据用户输入更新图表
【发布时间】:2016-01-28 09:18:52
【问题描述】:

使用 Django 我想可视化连接的 SQLite 数据库中的数据。我已经到了可以通过 Django 视图查询这些数据并在 d3 图中将其可视化的地步。现在我希望允许用户使用下拉列表来自定义他们自己的查询,在这种情况下允许他们选择与数据库中的一列值相对应的数字。

我使用 JSON 创建下拉列表,基于静态查询在 Django 视图中创建此 JSON。同样,我使用 JSON 来检索图形的数据,这是我遇到一些困难的地方。

问题

虽然我得到一个 JSON 返回到我的控制台,但我希望在 d3.json() 中使用它来显示值。我希望通过将 json 返回到 url 并使用 d3 访问它来做到这一点。但是我遇到了以下错误:

GET http://127.0.0.1:8000/database/db_getselection/1416/ 500 (INTERNAL SERVER ERROR)

模板

<div class="BoxIt">
    <!-- Make a list of all ReportDataDictionaryIndex values, based on database table -->
    <div class="div-dropdown" style="height:25px;">
        <!-- Drop down list directly from database -->
        <select id="selected_variable" name="selected_variable"></select>
        <div id="results_selection"></div>
    </div>

    <h2>sel_var is: {{ sel_var }}</h2>
    <h2>variable_data_Te: {{ variable_data_Te }}</h2>

    <div class="div">
        <!-- Chart to visualise data -->
        <svg id="variable_data_plot" width="400" height="300"></svg>
    </div>
</div>

JS/jQuery

<script>
    $.getJSON('{% url "db_dictionaryindices" %}', function(options) {
        var select = document.getElementById("selected_variable");
        for (var i = 0; i < options.length; i++) {
            var opt = options[i].reportdatadictionaryindex;
            var el = document.createElement("option");
            el.textContent = opt;
            el.value = opt;
            select.appendChild(el);
        };

        $("#selected_variable").change(function () {
            var url = "/database/db_getselection/" + $("#selected_variable").val() +"/";
            var selected_var = $("#selected_variable").val();
            console.log(url);
            console.log("Selected variable: "+selected_var);
            console.log("selection is working!") // sanity check
            $.ajax({
                url: url,
                type: "POST",
                dataType: 'json',
                data: { selected_variable : selected_var },

                success: function(data){
                    console.log(data);
                    var post_data = data;
                    drawLineChart(post_data);

                    console.log("success"); // another sanity check
                    //$("#results_selection").html("<strong>Success: "+data+"</strong>");

                },
                error: function(xhr,errmsg,err) {
                    console.log(data);
                    $('#results_selection').html("<div class='alert-box alert radius' data-alert>Oops! We have encountered an error: "+errmsg+
                            " <a href='#' class='close'>&times;</a></div>"); // add the error to the dom
                    console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
                }
            });

            //Call this function within AJAX after the call returns a success
            function drawLineChart(post_data){

                    post_data.forEach(function (d) {
                        d.timeindex = +d.timeindex;
                        d.value = +d.value;


                        var vis = d3.select("#variable_data_plot"),
                                WIDTH = 400,
                                HEIGHT = 300,
                                MARGINS = {
                                    top: 20,
                                    right: 20,
                                    bottom: 20,
                                    left: 50
                                };

                        //d3.scale.linear uses two properties called range and domain to create the scale. Range defines the area avaiable to rende the graph, and Domain defines the min and max values.
                        var xScale = d3.scale.linear()
                                .range([MARGINS.left, WIDTH - MARGINS.right]).domain([0, d3.max(post_data, function (d) {
                                    return d.timeindex
                                })]);

                        var yScale = d3.scale.linear()
                                .range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([0, 50]);

                        //Create axis using scales defined
                        var xAxis = d3.svg.axis()
                                .scale(xScale);
                        //.orient("bottom");

                        var yAxis = d3.svg.axis()
                                .scale(yScale)
                                .orient("left");

                        vis.append("svg:g")
                                .attr("class", "x axis")
                                .attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
                                .call(xAxis);

                        vis.append("svg:g")
                                .attr("class", "y axis")
                                .attr("transform", "translate(" + (MARGINS.left) + ",0)")
                            //.attr("y", 6)
                            //.attr("dy", ".71em")
                            //.style("text-anchor", "end")
                                .call(yAxis);

                        var line = d3.svg.line()
                                .x(function (d) {
                                    return xScale(d.timeindex);
                                })
                                .y(function (d) {
                                    return yScale(d.value);
                                });

                        vis.append("svg:path")
                                .attr('d', line(post_data))
                                .attr('stroke', 'green')
                                .attr('stroke-width', 2)
                                .attr('fill', 'none')
                                .attr("class", "line");
                    });

            };
        });
    });

    // acquire csrf token using jQuery
    function getCookie(name) {} // ETC...


</script>

数据库/views.py

def db_data(request):
    return render(request, 'database/database.html')

def db_getselection(request, sel_var):
    sel_var = request.POST.get('selected_variable')

    logr.debug(sel_var)
    variable_data_Te = Reportdata.objects.using('visdata').filter(reportdatadictionaryindex=sel_var).values("timeindex", "value")[:100]
    variable_data_Te = json.dumps(list(variable_data_Te), cls = DjangoJSONEncoder)

    return HttpResponse(variable_data_Te, content_type = 'application/json')

def db_dictionaryindices(request):
    DataDictionaryIndices = Reportdatadictionary.objects.using('visdata').values("reportdatadictionaryindex")[:15]
    DataDictionaryIndices = json.dumps(list(DataDictionaryIndices), cls = DjangoJSONEncoder)
    return HttpResponse(DataDictionaryIndices, content_type = 'application/json')

数据库/urls.py

urlpatterns = patterns('',
    url(r'^$', views.db_data, name='db_data'),
    url(r'^db_getselection/(?P<sel_var>\d+)/$', views.db_getselection, name='db_getselection'),
    url(r'^api/db_dictionaryindices/$', views.db_dictionaryindices, name='db_dictionaryindices'),
    ) + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

这是我之前通过设置静态值进入图表的一些数据的图像。

【问题讨论】:

    标签: jquery json ajax django d3.js


    【解决方案1】:

    一个月后,我想通了,我会回答我自己的问题。将问题编辑为工作脚本。

    我可以直接在我的 AJAX 成功中调用 d3 图的函数,而不是尝试使用 d3.json 和访问 URL:

    AJAX

    $.ajax({
        url: url,
        type: "POST",
        dataType: 'json',
        data: { selected_variable : selected_var },
    
        success: function(data){
            console.log(data);
            var post_data = data;
            drawLineChart(post_data);
        })}
    

    然后,我没有像原来想使用的那样使用 d3.json,而是直接使用数据来创建图形:

    d3 图

    function drawLineChart(post_data){
    
        post_data.forEach(function (d) {
            d.timeindex = +d.timeindex;
            d.value = +d.value;
    
        //ETC
        )}
    }
    

    结果

    如果有人看到任何可以更有效或更好的方法,请告诉我。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 2018-04-30
      • 2020-10-06
      • 1970-01-01
      • 2013-06-06
      • 2021-04-08
      • 2020-04-18
      相关资源
      最近更新 更多