簡體   English   中英

如何將條形圖添加到基於 Django 的數據庫中?

[英]How can I add a Bar Chart to my Django based Database?

親愛的社區成員,

我真的希望您能幫助我將條形圖添加到我的 Django 項目中。 1. 我有一個包含大約 1000 個項目的數據庫。 2. 我需要能夠在需要時可視化每個項目 3 個月的銷售額。 不確定什么是正確的方法。

這是我的models.py:

從 django.db 導入模型從數學導入 * 從十進制導入 *

class Itemslist(models.Model):
    item_n = models.CharField(max_length=200)
    sales_this_month = models.DecimalField(blank=True, null=True, max_digits=19, 
    decimal_places=0)
    saleslm = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
    sales2m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)
    sales3m = models.DecimalField(blank=True, null=True, max_digits=19, decimal_places=0)


    def __str__(self):
        return self.item_n

這是我的 views.py 文件,這是我使用提供的最后一個解決方案創建的一個實驗:

def charts(request):
    charts = Itemslist.objects \
        .values('saleslm') \
        .annotate(lm=Count('saleslm')) \
        .annotate(m2=Count('sales2m')) \
        .annotate(3m3=Count('sales3m')) \
        .order_by('saleslm')
    return render(request, 'charts.html', {'charts': charts})

正如您所看到的,這不是我需要的解決方案,我只是想至少想出一些東西,而 eaven 已經向我展示了具有相同值的圖表。 這是我的 hmtl 代碼:

{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}

<br>
<p>Logged in user: {{ user.username }}</p>
<br>


<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container"></div>
{
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
  Highcharts.chart('container', {
      chart: {
          type: 'column'
      },
      title: {
          text: 'Sales previous 3 months'
      },
      xAxis: {
          categories: ['sales']
      },
      series: [{
          name: '3mBack',
          data: [ {% for entry in charts %}{{ entry.m3 }}{% endfor %} ]
      }, {
          name: '2mBack',
          data: [ {% for entry in charts %}{{ entry.m2 }}{% endfor %} ]
      }, {
          name: 'Lmonth',
          data: [ {% for entry in charts %}{{ entry.lm }}{% endfor %} ]
      }, ]

  });
</script>

</body>
</html>

{% endif %}
{% endblock %}

<!-- charting tutorial to follow :  https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html -->

我必須為圖表創建一個請求按鈕,然后必須使用正確的參數生成圖表。

看過這個問題: Displaying multiple bar graph in django

也搜索過這個解決方案https://code.djangoproject.com/wiki/Charts

並查看了這篇文章https://simpleisbetterthancomplex.com/tutorial/2018/04/03/how-to-integrate-highcharts-js-with-django.html

上一篇文章是最清楚的一篇,你可以看到,我剛剛從那里復制粘貼了解決方案,做了一些小的改動。 這是我放在 base.html 文件中的腳本:

<script src="https://code.highcharts.com/highcharts.src.js"></script>

這就是我最終顯示的圖表:

海圖

但是在我的情況下仍然找不到如何處理它。

據我所知,所有這些解決方案都展示了如何將圖表繪制到一個數組,或者求和或自生成的數組。 但我希望能夠選擇何時顯示圖表以及顯示哪個項目。

按鈕放在這個 html 文件上:

{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}

<br>
<p>Logged in user: {{ user.username }}</p>
<br>


    <body>
            <table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
            <thead>
            <tr>
              <th>SUP:</th>
              <th>Item N.:</th>
              <th>SKU</th>
              <th>Description</th>
              <th>3mBack</th>
              <th>2mBack</th>
              <th>Lmonth</th>
              <th>CMonth</th>
              <th>Nmonth</th>
              <th>N2Month</th>
              <th>N3month</th>
              <th></th>

            </tr>
            </thead>
            <tbody>
                        {% for records in sorted %}
                <tr>
                <td>{{ records.sup }}</td>
                <td>{{ records.item_n }}</td>
                <td>{{ records.sku }}</td>
                <td>{{ records.description }}</td>
                <td>{{ records.sales3m }}</td>
                <td>{{ records.sales2m }}</td>
                <td>{{ records.saleslm }}</td>
                <td>{{ records.sales_this_month }}</td>
                <td>{{ records.m1predicted }}</td>
                <td>{{ records.m2predicted }}</td>
                <td>{{ records.m3predicted }}</td>

                <td>
                  <a href="{% url 'edit' records.id %}" class="btn btn-secondary">Edit</a>
                </td>

                            </tr>
                        {% endfor %}

            </tbody>
        </table>

        <script>
        $(document).ready(function() {
            var table = $('#example').DataTable( {
            fixedColumns: true,
                lengthChange: true,
                buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
            } );

            table.buttons().container()
                .appendTo( '#example_wrapper .col-md-6:eq(0)' );
        } );
         </script>
    </body>
</html>
{% endif %}
<div></div>
{% endblock js %}

這是我在這個社區的第一個問題,所以如果有什么不清楚的地方,請幫助我以正確的方式更正。

等待任何有用的答案!!!

好消息社區。

我得到了一個很好的解決方案,現在我的問題已經完全解決了。

至少對於我的需求,這是一個完美的解決方案。

我被要求使用 d3js.org 而不是 highcharts,這對我來說絕對沒問題。

代碼背后的邏輯是您從顯示的值中請求數據,希望當您瀏覽帶有注釋的代碼時會很清楚。

因為它是一個 django 項目,所以這是我的 html 文件的標題:

{% extends 'base.html' %}
{% block js %}
{% if user.is_authenticated %}
{% load loads_extra %}
{% load static %}

<br>
<p>Logged in user: {{ user.username }}</p>
<br>

這是我顯示表/值的 html 代碼的一部分:

<table id="example" class="table table-striped table-bordered dt-responsive nowrap" style="width:100%">
            <thead>
            <tr>
              <th>SUP:</th>
              <th>Item N.:</th>
              <th>SKU</th>
              <th>Description</th>
              <th>6mBack</th>
              <th>5mBack</th>
              <th>4mBack</th>
              <th>3mBack</th>
              <th>2mBack</th>
              <th>Lmonth</th>
              <th>CMonth</th>
              <th>Nmonth</th>
              <th>N2Month</th>
              <th>N3month</th>
              <th>AVGrowth</th>
              <th></th>
              <!-- This is header for new button to draw the Bar Charts -->
              <th></th>

            </tr>
            </thead>
            <tbody>
              {% for records in sorted %}
                <tr>
                <td>{{ records.sup }}</td>
                <td>{{ records.item_n }}</td>
                <td>{{ records.sku }}</td>
                <td>{{ records.description }}</td>
                <td>{{ records.sales6m }}</td>
                <td>{{ records.sales5m }}</td>
                <td>{{ records.sales4m }}</td>
                <td>{{ records.sales3m }}</td>
                <td>{{ records.sales2m }}</td>
                <td>{{ records.saleslm }}</td>
                <td>{{ records.sales_this_month }}</td>
                <td>{{ records.m1predicted }}</td>
                <td>{{ records.m2predicted }}</td>
                <td>{{ records.m3predicted }}</td>
                <td>{{ records.avgrowths }}</td>

                <td>
                  <a href="{% url 'edit' records.id %}" class="btn btn-secondary">Edit</a>
                </td>
                <!-- Add new button for drawing Bar Charts -->
                <td>
                  <button class="btn btn-secondary" onclick="draw_chart(this)" data-toggle="modal" data-target="#myModal">Chart</button>
                </td>

            </tr>
          {% endfor %}

         </tbody>
        </table>

請閱讀評論以了解什么是什么。

這是 html 的其余部分,即通過按下必須可視化的數組前面的按鈕,在充值窗口上生成圖表:

<!-- Modal which Bar Chart will be placed -->
        <div id="myModal" class="modal fade" role="dialog">
            <div class="modal-dialog" style="max-width: 900px !important">
            <!-- Modal content-->
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">&times;</button>
                    </div>
                    <div class="modal-body">
                        <!-- <svg> element which will contains the Bar Chart -->
                        <svg width="1000" height="500"></svg>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                    </div>
                </div>
            </div>
        </div>
        <!-- Insert D3.js Library -->
        <script src="https://d3js.org/d3.v5.min.js"></script>
        <script>
        $(document).ready(function() {
            var table = $('#example').DataTable( {
            fixedColumns: true,
                lengthChange: true,
                buttons: [ 'copy', 'excel', 'csv', 'pdf', 'colvis' ]
            } );

            table.buttons().container()
                .appendTo( '#example_wrapper .col-md-6:eq(0)' );
        } );
        // Main functions for Drawing Bar chart using D3.js
        function draw_chart(item){
            // `item` is the current clicked button element
            // `row_ele` is the parent <tr> element of the current clicked button element
            row_ele = item.closest('tr');
            // Get the value from the <td> element using nth-child()
            val_6mBack = row_ele.querySelector("td:nth-child(5)");
            val_5mBack = row_ele.querySelector("td:nth-child(6)");
            val_4mBack = row_ele.querySelector("td:nth-child(7)");
            val_3mBack = row_ele.querySelector("td:nth-child(8)");
            val_2mBack = row_ele.querySelector("td:nth-child(9)");
            val_Lmonth = row_ele.querySelector("td:nth-child(10)");
            val_CMonth = row_ele.querySelector("td:nth-child(11)");
            val_Nmonth = row_ele.querySelector("td:nth-child(12)");
            val_N2Month = row_ele.querySelector("td:nth-child(13)");
            val_N3month = row_ele.querySelector("td:nth-child(14)");

            // `data` is variable which store the data for Bar Charts
            data = []
            // Pushing data as key/value type objects into the `data` variable
            data.push({'label':'6mBack', 'value': val_6mBack.innerHTML})
            data.push({'label':'5mBack', 'value': val_5mBack.innerHTML})
            data.push({'label':'4mBack', 'value': val_4mBack.innerHTML})
            data.push({'label':'3mBack', 'value': val_3mBack.innerHTML})
            data.push({'label':'2mBack', 'value': val_2mBack.innerHTML})
            data.push({'label':'Lmonth', 'value': val_Lmonth.innerHTML})
            data.push({'label':'CMonth', 'value': val_CMonth.innerHTML})
            data.push({'label':'Nmonth', 'value': val_Nmonth.innerHTML})
            data.push({'label':'N2Month', 'value': val_N2Month.innerHTML})
            data.push({'label':'N3month', 'value': val_N3month.innerHTML})


            // Set <svg> element's width and height
            var svg = d3.select("svg"),
                        margin = 200,
                        width = svg.attr("width") - margin,
                        height = svg.attr("height") - margin
            // Remove the old contents of the <svg> element
            svg.selectAll('*').remove()
            // Initialize X-axis and Y-axis for Bar Chart
            var xScale = d3.scaleBand().range([0, width]).padding(0.4),
                yScale = d3.scaleLinear().range([height, 0]);

            // Set all group which is placed in the <svg>element
            // transform to (50,100) on <svg> area , margint in svg has been changed to 300 and instead 50/100, changed to 100/300, but then back.
            var g = svg.append("g")
                        .attr("transform", "translate(" + 50 + "," + 100 + ")");


            xScale.domain(data.map(function(d) { return d.label; }));
            // If all values of data will be zero, we will fix the range of the Y-axis
            if(d3.max(data, function(d) { return d.value; }) == 0){
                yScale.domain([0, 10]);
            }else{
                // If all is not zero, we will set Y-axis from 0 to maximum value.
                yScale.domain([0, d3.max(data, function(d) { return Number(d.value); })]);
            }

            // Set X- axis
            g.append("g")
             .attr("transform", "translate(0," + height + ")")
             .call(d3.axisBottom(xScale));
             // Set Y-axis using ticket
            g.append("g")
             .call(d3.axisLeft(yScale).tickFormat(function(d){
                 return d;
             }).ticks(10));

             console.log(data)
            // Draw Bar Chart using <rect> element by data which is stored in the `data` variable
            g.selectAll(".bar")
             .data(data)
             .enter().append("rect")
             .attr("class", "bar")
             .attr("x", function(d) { return xScale(d.label); })
             .attr("y", function(d) { return yScale(d.value); })
             .attr("width", xScale.bandwidth())
             .attr("height", function(d) { return height - yScale(d.value); })
             .style('fill','#899da6');
        }
        </script>
    </body>
{% endif %}
{% endblock js %}

所以最后這里是我的 html 的樣子:

在此處輸入圖片說明

這是一個圖表,我通過按下圖表按鈕得到:

在此處輸入圖片說明

為了幫助社區,請提出問題,如果有更好的方法,請添加/更正。

非常感謝您的幫助和關注!!!

views.py 你在 annotate(3m3 它不能以 3 開始) 上有一個錯誤。你也有相同的函數名和變量名 def 圖表和圖表。Python 可能足夠聰明,可以弄清楚,但盡量避免這樣做。我我也反對在此處明確命名變量 saleslm 和 sales2m。

def charts(request):
    return render(request, 'charts.html')


def charts_ajax(request):
    charts_data = Itemslist.objects \
        .values('saleslm') \
        .annotate(lm=Count('saleslm')) \
        .annotate(m2=Count('sales2m')) \
        .annotate(m3=Count('sales3m')) \
        .order_by('saleslm')
    return JsonResponse({'charts': list(charts_data)})

網址.py

path('charts/', views.charts, name='charts_home'),
path('charts_ajax/', views.charts_ajax, name='render_charts_ajax')

html 您的 html 文件中有多個問題。

</html>
{% endif %}
<div></div>
{% endblock js %}

html 結束后你有 div。 html 結束后你不應該有任何東西。 這里很少有其他組織問題。 我通常會有一個塊內容,然后塊 js,而您在塊 js 中擁有所有內容。 我會清理那些。 現在您還添加了數據表。 您可以添加此處提到的按鈕。 https://datatables.net/extensions/buttons/examples/initialisation/custom.html但如果我是你,我會嘗試讓它與簡單的表格一起工作並繼續使用數據表。

<html>
<head>
<meta charset="utf-8">
<title>Django Highcharts Example</title>
</head>
<body>
<div id="container">
</div>
<button id="render_chart" type="button">Render Chart</button>

<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<script>
$(document).ready(function(){
   $('#render_chart').on('click', function(e){
       $.ajax({
           url: "{% url 'render_charts_ajax'%}",
           type: "GET",
           dataType: "json",
           success: function (data) {
               console.log(data.charts[0].saleslm)
               Highcharts.chart('container',{
                   chart:{
                       type:'bar'
                   },
                   title:{
                     text:"Sales Last Month"
                   },
                   series:[{
                       name:"Sales LM",
                       data:[parseInt(data.charts[0].saleslm)]
                   }]
               })
           }
       })
   })
});
</script>

</body>
</html>

在圖表正確顯示之前,您的 json 可能需要一些處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM