第九篇 干货满满!!!Django框架集成Echarts环境Sql数据库异步更新图表数据

1、效果图展示

以下左上图表的数据是直接从后端SQL读取的数据啦!!!
在这里插入图片描述

2、前端

echarts.html

{% load static %}
<!doctype html>
<html>

<head>
  <meta charset="utf-8">
  <script type="text/javascript" src="{% static 'js/jquery.js' %}"></script>
  <link rel="stylesheet" href="{% static 'css/comon0.css' %}">

</head>
<script>
  $(window).load(function () {
    $(".loading").fadeOut()
  })

  /****/
  $(document).ready(function () {
    var whei = $(window).width()
    $("html").css({ fontSize: whei / 20 })
    $(window).resize(function () {
      var whei = $(window).width()
      $("html").css({ fontSize: whei / 20 })
    });
  });
</script>
<script type="text/javascript" src="{% static 'js/echarts.min.js' %}"></script>
<script language="JavaScript" src="{% static 'js/js.js' %}"></script>

<body>
  <div class="canvas" style="opacity: .2">
    <iframe frameborder="0" src="/static/js/index.html" style="width: 100%; height: 100%"></iframe>
  </div>
  <div class="loading">
    <div class="loadbox"> <img src="{% static 'picture/loading.gif' %}"> 页面加载中... </div>
  </div>
  <div class="head">
    <h1>大数据可视化展板通用模板</h1>
    <div class="weather"><!--<img src="{% static 'picture/weather.png' %}"><span>多云转小雨</span>--><span id="showTime"></span></div>

    <script>
      var t = null;
      t = setTimeout(time, 1000);//開始运行
      function time() {
        clearTimeout(t);//清除定时器
        dt = new Date();
        var y = dt.getFullYear();
        var mt = dt.getMonth() + 1;
        var day = dt.getDate();
        var h = dt.getHours();//获取时
        var m = dt.getMinutes();//获取分
        var s = dt.getSeconds();//获取秒
        document.getElementById("showTime").innerHTML = y + "年" + mt + "月" + day + "-" + h + "时" + m + "分" + s + "秒";
        t = setTimeout(time, 1000); //设定定时器,循环运行     
      }

    </script>


  </div>
  <div class="mainbox">
    <ul class="clearfix">
      <li>
        <div class="boxall" style="height: 3.2rem">
          <div class="alltitle">模块标题样式</div>
          <div class="allnav" id="echart1"></div>
          <div class="boxfoot"></div>
        </div>
        <div class="boxall" style="height: 3.2rem">
          <div class="alltitle">模块标题样式</div>
          <div class="allnav" id="echart2"></div>
          <div class="boxfoot"></div>
        </div>

        <div class="boxall" style="height: 6.4rem; padding: 20px 0%">
          <div class="alltitle">各部门销售构成</div>
          <div class="allnav">
            <div class="sy" id="fb1"></div>
            <div class="sy" id="fb2"></div>
            <div class="sy" id="fb3"></div>
            <div class="sy" id="fb4"></div>
            <div class="sy" id="fb5"></div>
          </div>
          <div class="boxfoot">

          </div>
        </div>
      </li>
      <li>
        <div class="bar">
          <div class="barbox">
            <ul class="clearfix">
              <li class="pulll_left counter">{{GrossIncome}} 万</li>
              <li class="pulll_left counter">{{GrossOutcome}} 万</li>
            </ul>
          </div>
          <div class="barbox2">
            <ul class="clearfix">
              <li class="pulll_left">2025年总收入情况 </li>
              <li class="pulll_left">2025年总支出情况</li>
            </ul>
          </div>
        </div>
        <div class="map">
          <div class="map1"><img src="{% static 'picture/lbx.png' %}"></div>
          <div class="map2"><img src="{% static 'picture/jt.png' %}"></div>
          <div class="map3"><img src="{% static 'picture/map.png' %}"></div>
          <div class="map4" id="map_1"></div>
        </div>
      </li>
      <li>
        <div class="boxall" style="height:3.4rem">
          <div class="alltitle">模块标题样式</div>
          <div class="allnav" id="echart4"></div>
          <div class="boxfoot"></div>
        </div>
        <div class="boxall" style="height: 3.2rem">
          <div class="alltitle">模块标题样式</div>
          <div class="allnav" id="echart5"></div>
          <div class="boxfoot"></div>
        </div>
        <div class="boxall" style="height: 3rem">
          <div class="alltitle">模块标题样式</div>
          <div class="allnav" id="echart6"></div>
          <div class="boxfoot"></div>
        </div>
      </li>
    </ul>
  </div>
  <div class="back"></div>


  <script type="text/javascript" src="{% static 'js/china.js' %}"></script>
  <script type="text/javascript" src="{% static 'js/area_echarts.js' %}"></script>
</body>

</html>

在这里插入图片描述

js.js

主要是echarts_1接口的更新,其他代码有需要请联系博主。
在这里插入图片描述
在这里插入图片描述
以下完整代码:

$(function () {
    echarts_1();
    echarts_2();
    echarts_4();
    echarts_31();
    echarts_32();
    echarts_33();
    echarts_5();
    echarts_6();

    window.onload = function() {
        echarts_1();
    };

    
    function echarts_1() {
        // 基于准备好的dom,初始化echarts实例
        var myChart = echarts.init(document.getElementById('echart1'));

        option = {
            //  backgroundColor: '#00265f',
            tooltip: {
                trigger: 'axis',
                axisPointer: {
                    type: 'shadow'
                }
            },
            grid: {
                left: '0%',
                top: '10px',
                right: '0%',
                bottom: '4%',
                containLabel: true
            },
            xAxis: [{
                type: 'category',
                data: [],
                axisLine: {
                    show: true,
                    lineStyle: {
                        color: "rgba(255,255,255,.1)",
                        width: 1,
                        type: "solid"
                    },
                },

                axisTick: {
                    show: false,
                },
                axisLabel: {
                    interval: 0,
                    // rotate:50,
                    show: true,
                    splitNumber: 15,
                    textStyle: {
                        color: "rgba(255,255,255,.6)",
                        fontSize: '12',
                    },
                },
            }],
            yAxis: [{
                type: 'value',
                axisLabel: {
                    //formatter: '{value} %'
                    show: true,
                    textStyle: {
                        color: "rgba(255,255,255,.6)",
                        fontSize: '12',
                    },
                },
                axisTick: {
                    show: false,
                },
                axisLine: {
                    show: true,
                    lineStyle: {
                        color: "rgba(255,255,255,.1	)",
                        width: 1,
                        type: "solid"
                    },
                },
                splitLine: {
                    lineStyle: {
                        color: "rgba(255,255,255,.1)",
                    }
                }
            }],
            series: [
                {
                    type: 'bar',
                    data: [],
                    barWidth: '35%', //柱子宽度
                    // barGap: 1, //柱子之间间距
                    itemStyle: {
                        normal: {
                            color: '#2f89cf',
                            opacity: 1,
                            barBorderRadius: 5,
                        }
                    }
                }

            ]
        };


        // 使用AJAX请求获取数据
        fetch('/app01/fabric_order_summary/')
            .then(response => {
                if (!response.ok) {
                    throw new Error('网络响应失败');
                }
                return response.json();
            })
            .then(data => {
                // 获取传递的数据,此处获取的为JSON格式的字典列表
                var data_array = data; // 直接使用data,因为返回的就是一个列表
                // 检查数据是否为空
                if (data_array.length === 0) {
                    console.log("数据为空");
                    alert('数据为空,请稍后重试。');
                    return;
                }
                // 按照 总出库数量 降序排序
                data_array.sort((a, b) => b.总出库数量 - a.总出库数量);
                // 在控制台中输出处理后的数据
                console.log("各品牌全年总出库量:", data_array);
                // 更新series数据
                option.series[0].data = data_array.map(item => item.总出库数量);
                // 更新 xAxis 数据为对应的品牌名称
                option.xAxis[0].data = data_array.map(item => item.品牌);
                // 使用刚指定的配置项和数据显示图表。
                myChart.setOption(option, true);
                // 自动调整图表大小
                window.addEventListener("resize", function () {
                    myChart.resize();
                });
            })
            .catch(error => {
                console.error('AJAX请求失败:', error);
                alert('数据获取失败,请稍后重试。');
            });
    }
)

3、Django框架布局

models.py

在这里插入图片描述

from django.db import models
class 面料基础档案(models.Model):
    面料花号=models.CharField(db_column="面料花号",max_length=100, primary_key=True)  # 设置面料花号为主键
    所属品牌=models.CharField(db_column="所属品牌",max_length=100)
    责任来源属性=models.CharField(db_column="责任来源属性",max_length=100)
    
    class Meta:
        managed = False
        db_table = "面料基础档案"     #sql表名
        


class 销售基础数据(models.Model):
    '''
        图表数据
    '''
    id = models.AutoField(primary_key=True, db_column="订单编号")  # 显式定义主键
    出库日期 = models.DateField(db_column="出库日期")
    出库数量 = models.DecimalField(db_column="出库数量", max_digits=10, decimal_places=2)
    面料净价 = models.DecimalField(db_column="面料净价", max_digits=10, decimal_places=2)
    成本 = models.DecimalField(db_column="成本", max_digits=10, decimal_places=4)
    汇率 = models.DecimalField(db_column="汇率", max_digits=10, decimal_places=4)
    面料花号=models.ForeignKey(面料基础档案, on_delete=models.CASCADE,db_column="面料花号",max_length=100)

    
    class Meta:
        managed = False
        db_table = "销售基础数据"     #sql表名

views.py

在这里插入图片描述
定义的数据接口名称为fabric_order_summary

def fabric_order_summary(request):
    # 设置筛选条件
    year = 2025
    responsible_sources = ['现货面料', 'TESATA现货']

    # 筛选出库日期为2025年且责任来源属性为指定值的记录
    brand_total_outbounds = (销售基础数据.objects
                             .filter(出库日期__year=year,
                                     面料花号__责任来源属性__in=responsible_sources)
                             .values('面料花号__所属品牌')  # 按所属品牌分组
                             .annotate(total_outbound=Sum('出库数量'))  # 计算每个品牌的总出库数量
                             )

    # 将查询结果转换为字典列表,以便转换为JSON
    result_list = []
    for brand_total in brand_total_outbounds:
        result_list.append({
            '品牌': brand_total['面料花号__所属品牌'],
            '总出库数量': float(brand_total['total_outbound'])  # 将Decimal转换为float
        })

    # 返回JSON格式的数据
    return JsonResponse(result_list, safe=False)  # 返回JSON响应

urls.py(app01里的url)

from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from .views import fabric_order_summary

urlpatterns = [
    path('', views.index, name='index'),  # 用户列表
    path('fabric_order_summary/', fabric_order_summary, name='fabric_order_summary')
    
]

if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

4、补充:JSON数据调试

可以访问地址:
http://127.0.0.1:8000/app01/fabric_order_summary/
可以看到数据顺利传到视图函数,并且是正确的JSON格式可以调用到前端。于是我们可以调用这个Python接口,来实现后端SQL数据库的异步更新数据。
在这里插入图片描述

欢迎 评论区/私信 交流技术问题~~~
动动发财的小手给作者点点赞、收藏哦!

转侵删。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值