亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Django中利用Highcharts 實現數據可視化

發布時間:2021-03-24 15:53:10 來源:億速云 閱讀:250 作者:Leah 欄目:開發技術

本篇文章為大家展示了怎么在Django中利用Highcharts 實現數據可視化,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

開發環境

使用 Python 2.7.14,django 1.11.8,highcharts 4.0.1
直接命令行輸入以下語句,即可安裝django 1.11.8

pip install django==1.11.8

至于Highcharts,可以去官網下載。我用的是之前前輩給的模板,js不是太懂,所以基本沒改,只是為了方便進行拓展,對功能模塊進行了注釋。

開發需求

手頭已有爬取的winstore不同app,不同榜單,不同地區的多天rank數據。這些rank數據存放在MySQL服務器中,庫名為winstore,表名為winstore_rank。

現在需要將這些rank數據用折線圖的方式展示出來。同時在網頁上需要可以根據選擇的日期,地區,榜單來動態產生折線圖。

問題解析

根據開發需求,可以將這次任務分為三個部分。

前端頁面

a. ajax動態獲取地區列表、榜單列表,生成對應的下拉列表,必要時需將傳統下拉列表轉換成多選下拉列表

b. 根據搜索結果,將符合條件的app的rank添加到折線圖中

服務器端

a. 接受前端的請求,與數據庫通信,返回所請求數據

MySQL數據庫

a. 根據服務器端傳輸的sql語句進行對應的查詢

根據上述的分析,前端肯定是js + jQuery + Echarts + jquery.multiselect了,服務器端采用Django,數據庫方面Django有對應的驅動模塊,不用管。

1. 前端頁面

新建一個文件rank.html,內容如下:

<head>
 {% load static %}
 <script type="text/javascript" src="{% static 'js/jquery.min.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/highcharts.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/jquery-ui.min.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/exporting.js' %}"></script>
 <script type="text/javascript" src="{% static 'js/jquery.multiselect.min.js' %}"></script>

 <link rel="stylesheet" href="{% static 'css/jquery-ui.min.css' %}" rel="external nofollow" >
 <link rel="stylesheet" href="{% static 'css/jquery.multiselect.css' %}" rel="external nofollow" >
 <link rel="stylesheet" href="{% static 'css/screen1.css' %}" rel="external nofollow" >

 <style type="text/css">
  #set-content ul li #chart {
   width: 60px;
   font-size: 12px;
   height: 22px;
  }
 </style>
 <script type="text/javascript">

  // 設定開始日期和結束日期,默認為最近10天
  $(function() {
   $("#beginDate").datepicker({dateFormat: "yy-mm-dd"});
   $("#endDate").datepicker({dateFormat: "yy-mm-dd"});
   var dateNow = new Date();
   var str_dateNow = dateNow.getFullYear() + "-" + (dateNow.getMonth() + 1) + "-" + dateNow.getDate();
   var dateBegin = new Date(dateNow - 10 * 1000 * 3600 * 24);
   var str_dateBegin = dateBegin.getFullYear() + "-" + (dateBegin.getMonth() + 1) + "-" + dateBegin.getDate();
   $("#beginDate").datepicker("setDate", str_dateBegin);
   $("#endDate").datepicker("setDate", str_dateNow);
  });
  // 動態獲取數據庫中region數據,填充入下拉列表
  $(function() {
   $.get("/getWinstoreRegions",
     {"limit": "0"},
     function(regionsDict) {
      for (var id in regionsDict) {
       regionOption = "<option value='" + id + "'>" + regionsDict[id] + "</option>";
       $("#region").append(regionOption);
      }
     },
     "json"
     )
  });

  // 動態獲取數據庫中chart數據,填充入下拉列表
  $(function() {
   $.get("/getWinstoreCharts",
     {"limit": "0"},
     function(chartsDict) {
      for (var id in chartsDict) {
       chartOption = "<option value='" + id + "'>" + chartsDict[id] + "</option>";
       $("#chart").append(chartOption);
      }
     },
     "json"
     )
  });
  // 動態獲取數據庫中category數據,填充入下拉列表
  $(function() {
   $.get("/getWinstoreCategories",
     {"limit": "0"},
     function(categoriesDict) {
      for (var id in categoriesDict) {
       categoryOption = "<option value='" + id + "'>" + categoriesDict[id] + "</option>";
       $("#category").append(categoryOption);
      }
     },
     "json"
     )
  });
  // 動態獲取數據庫中app名字,填充入下拉列表
  $(function() {
   $.get( "/getWinstoreApps",
    {"limit":"0",},
    function(dataDict) {
     // 循環添加下拉列表的option
     for (var id in dataDict) {
      appOption = "<option value='" + id + "'>" + dataDict[id] + "</option>";
      $("#appName").append(appOption);
     }
     // 初始化多選
     $("#appName").multiselect({header: false,});
     // 選中所有下拉列表項
     $("#appName").multiselect("checkAll");
     // 動態設置多選框的寬度
     var ulList = $(".ui-multiselect-checkboxes")[0];
     // 必須先單擊多選下拉列表,然后才可以獲取對應元素的寬度值
     $(".ui-multiselect")[0].click();
     var maxWidth = 0;
     for (var i = 0; i < ulList.childElementCount; i++) {
      var currentInputWidth = $(ulList.childNodes[i]).find("input")[0].offsetWidth;
      var currentSpanWidth = $(ulList.childNodes[i]).find("span")[0].offsetWidth;
      var currentWidth = currentSpanWidth + currentInputWidth * 3;
      if (currentWidth > maxWidth) {
       maxWidth = currentWidth;
      }
     }
     // 設置對應標簽的寬度
     $($(".ui-multiselect")[0]).width(maxWidth);
     $($(".ui-multiselect-menu")[0]).width(maxWidth + 6);
     // 二次單擊
     $(".ui-multiselect")[0].click();
    },
    "json");
  });
  // 綁定query按鈕的單擊操作
  $(function() {
   $("#query").click(function() {
    var region = $("#region").val();
    var beginDate = $("#beginDate").val();
    var endDate = $("#endDate").val();
    var chart = $("#chart").val();
    var appNames = $("#appName").val();
    var category = $("#category").val();

    // 將appNames連接成字符串
    queryReport(region, beginDate, endDate, chart, category, appNames.join("@"));
   });
  })
  var lineChart;
  // 獲取繪圖數據
  function queryReport(region, beginDate, endDate, chart, category, appNames) {
   // 清空原有繪圖數據
   $("#container")[0].innerHTML = "";
   // 初始化折線圖參數
    var lineChart = new Highcharts.Chart({
            chart: {
             renderTo: 'container',             type: 'line'
            },
            title: {
             text: 'Daily Ranking',
             style: {fontFamily: 'Helvetica', fontWeight: '200'}
            },
            subtitle: {
             text: 'By Product',
             style: {fontFamily: 'Helvetica', fontWeight: '200'}
            },

            xAxis: [{ // master axis
             type: 'datetime',
             gridLineWidth:1,
             gridLineDashStyle: 'longdash',
             tickInterval: 24 * 3600 * 1000,
            }, { // slave axis
             type: 'datetime',
             linkedTo: 0,
             opposite: true,
             tickInterval: 24 * 3600 * 1000,
             labels: {
              formatter: function () {return Highcharts.dateFormat('%a', this.value);}
             }
            }],            tooltip: {
             headerFormat: '<span>{point.key}</span><br/>',
             pointFormat: '<span >\u25AC</span> {series.name}: <b>{point.y}</b><br/>',
            },
            yAxis: [{ // Primary yAxis
             min:1,
             reversed: true,
             labels: {
              format: 'No. {value}',
              style: {
               color: '#4572A7'
              }
             },
             title: {
              text: 'Ranking',
              style: {
               color: '#4572A7'
               }
              }
             },
             { // Secondary yAxis
             min:1,
             reversed: true,
             title: {
              text: 'Ranking',
              style: {
               color: '#4572A7'
              }
             },
             labels: {
             format: 'No. {value}',
             style: {
              color: '#4572A7'
              }
             },
             opposite: true,
            }],

            plotOptions: {
             column: {
              dataLabels: {
               enabled: true
              },
              enableMouseTracking: true
             },
             line: {
              dataLabels: {
               enabled: true
              },
              enableMouseTracking: true
             }
            },
            series: [],
           });
   // 構造url參數
   parameters = {'region': region,
      'beginDate': beginDate,
      'endDate': endDate,
      'chart': chart,
      'category': category,
      'appNames': appNames
      };

   // 請求繪圖數據
   $.get("/getWinstoreRank",
     parameters,
     function(rankDict) {
      var ranksOfApp = new Array();
      for (var app in rankDict) {
       lineChart.addSeries({
        name: app,
        data: rankDict[app]
       });
      }
     },
     "json"
     );
  }
 </script>

</head>


<body>
 <div id="set-content">
  <ul>
   <li>
    <label for="region">Country/Region: </label>
    <select id="region"></select>
   </li>
   <li>
    <label for="beginDate">Begin Date: </label>
    <input type="text" id="beginDate">
   </li>
   <li>
    <label for="endDate">End Date: </label>
    <input type="text" id="endDate">
   </li>
   <li>
    <label for="chart">Chart: </label>
    <select id="chart"></select>
   </li>
   <li>
    <label for="category">Category: </label>
    <select id="category"></select>
   </li>
   <li>
    <label for="appName">App:</label>
    <select id="appName" multiple="multiple" size="4"></select>
   </li>
   <li>
    <button id='query'>Query</button>
   </li>
  </ul>
 </div>
 <div id="container"></div>
</body>

這里稍微解釋下,在實際使用中,使用highcharts生成折線圖,根據不同的數據,只需要修改series參數即可。而series參數是個啥,可以在上面的HTML代碼中搜索series即可。稍微觀察下,就明白了。

至于你想換個大餅圖,柱狀圖,可以 點擊這里 找現成的例子,稍作修改就可以使用了。當然也許你有更多個性化的需求,那可以 點擊這里 找到對應的配置項進行修改。

2. 服務器端

1、首先命令行進入到你想放置項目代碼的地方

django_admin startproject winstore

2、進入剛剛新建的項目文件夾

cd winstore

3、創建新的應用rank。這里的應用可以理解成具有獨立功能的一組網頁的結合,當然在本篇博客里,只有一個網頁了。

python manage.py startapp rank

4、在rank文件夾中新建文件夾templatesstatic,將剛剛新建的rank.html放入templates文件夾,同時將引用的js庫文件放入static文件夾下,注意文件夾層級。

5.、打開winstore文件夾下的settings.py ,在INSTALL_APPS 下添加rank,添加之后如下:

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rank' # 添加的部分
]

DATABASES修改成你自己的MySQL數據庫的控制信息。下面是我的數據庫設置:

DATABASES = {
 'default': {
  'ENGINE': 'django.db.backends.mysql',
  'NAME': 'winstore', # 數據庫名
  'HOST': '127.0.0.1', # IP
  'PORT': '3306',  # 端口號
  'USER': 'root',  # 用戶名
  'PASSWORD': '111111', # 密碼
 }
}

6、編輯rank文件夾下的views.py文件,在rank.html中加入必要的網頁動態功能的實現。由于app的排名數據是根據其所處的榜單chart和應用類別category,以及不同的地區region來確定的,所以這里里的功能實現就需要包括5個部分。分別對appNamechartcategoryregion 實現從數據庫動態獲取其取值集合以及獲取排名數據。對應的實現分別如下:

appName

def getWinstoreApps(request):
 """
 根據接收到的GET請求返回app的取值集合
 """
 # 構造SQL語句
 sql = 'SELECT DISTINCT appName FROM winstore_rank'
 # 默認appNames的key和value相同
 appNames = {}
 try:
  result = getDataFromSQL(sql)
  result = [r[0] for r in result]
  for key in result:
   appNames[key] = key
 except Exception as e:
  print('getWinstoreApps ERROR: ' + str(e))
  appNames['QQ'] = 'QQ'
 return JsonResponse(appNames)

chart

def getWinstoreCharts(request):
 """
 根據接收到的GET請求返回chart的取值集合
 """
 # 構造SQL語句
 sql = 'SELECT DISTINCT chart FROM winstore_rank'
 # 默認charts的key和value相同
 charts = {}
 try:
  result = getDataFromSQL(sql)
  result = [r[0] for r in result]
  for key in result:
   charts[key] = key
 except Exception as e:
  print('getWinstoreCharts ERROR: ' + str(e))
  charts['Free'] = 'Free'
 return JsonResponse(charts)

category

def getWinstoreCategories(request):
 """
 根據接收到的GET請求返回category的取值集合
 """
 # 構造SQL語句
 sql = 'SELECT DISTINCT category FROM winstore_rank'
 # 默認categories的key和value相同
 categories = {}
 try:
  result = getDataFromSQL(sql)
  result = [r[0] for r in result]
  for key in result:
   categories[key] = key
 except Exception as e:
  print('getWinstoreCategories ERROR: ' + str(e))
  categories['Education'] = 'Education'
 return JsonResponse(categories)

region

def getWinstoreRegions(request):
 """
 根據接收到的GET請求返回region的取值集合
 """
 # 構造SQL語句
 sql = 'SELECT DISTINCT region FROM winstore_rank'
 # 默認regions的key和value相同
 regions = {}
 try:
  result = getDataFromSQL(sql)
  result = [r[0] for r in result]
  for key in result:
   regions[key] = key
 except Exception as e:
  print('getWinstoreRegions ERROR: ' + str(e))
  regions['EN-US'] = 'EN-US'
 return JsonResponse(regions)

獲取排名數據

def getWinstoreRank(request):
 """
 根據接收到的GET請求返回對應app的排名數據
 """
 # 從GET請求中獲取參數
 region = request.GET.get("region", "EN-US")
 chart = request.GET.get("chart", "Free")
 category = request.GET.get("category", "Education")
 beginDate = request.GET.get("beginDate", "2018-01-22")
 endDate = request.GET.get("endDate", "2018-02-02")
 appNames = request.GET.get("appNames", "QQ").split("@")
 # 構造SQL語句
 sqlTemp = 'SELECT the_date, rank FROM winstore_rank WHERE ' \
    'region="%s" AND chart="%s" AND category="%s" AND ' \
    'the_date BETWEEN "%s" AND "%s" AND ' \
    'appName=' % (region, chart, category, beginDate, endDate)

 # 以每個appName作為key,對應的排名數據列表作為value
 appRank = {}
 for appName in appNames:
  sql = sqlTemp + '"' + appName + '"'
  try:
   result = getDataFromSQL(sql)
   # 根據數據庫返回的結果將缺少rank數據的日期補0
   result = addZeroToRank(beginDate, endDate, result)
   appRank[appName] = result
  except Exception as e:
   print('getWinstoreRank ERROR: ' + str(e))
 return JsonResponse(appRank)


def addZeroToRank(beginDate, endDate, result):
 """
 以beginDate和endDate為日期的起始,將result中缺少的日期補全,同時設定排名為0
 Param:
  beginDate: 開始日期字符串,“2018-01-23”
  endDate: 結束日期字符串, “2018-02-02”
  result: 形如[(date, 23L), (date, 12L), [date, 3L]......]
 Return:
  按照日期順序排列的排名數據,缺省排名為0
 """
 # 將日期字符串轉變為date類型數據,方便日期加減
 y, m, d = [int(i) for i in beginDate.split("-")]
 begin = datetime.date(y, m, d)
 y, m, d = [int(i) for i in endDate.split("-")]
 end = datetime.date(y, m, d)
 current = begin
 # 獲取result中的日期,方便進行判斷
 resultTemp = [r[0] for r in result]
 while current <= end:
  if not (current in resultTemp):
   result.append((current, 0))
  current += datetime.timedelta(days=1)
 result.sort(key=lambda x: x[0])
 return [int(r[1]) for r in result]

這里主要就是構造SQL語句,然后訪問數據庫獲取對應的數據集合。其中getDataFromSQL() 是對訪問MySQL數據庫的簡單封裝,具體代碼如下:

def getDataFromSQL(sql):
 """
 根據sql語句獲取數據庫的返回數據
 """
 cursor = connection.cursor()
 cursor.execute(sql)
 return list(cursor.fetchall())

一些涉及到的引用可以參考文末給出的項目代碼。

最終綁定一下首頁

def index(request):
 """
 綁定網站首頁
 """
 return render(request, 'rank.html')

3. MySQL數據庫

實際應用時,相關的rank數據是通過爬蟲獲取的。在這里,就直接填充一些隨機的rank數據進去了,不影響最終的結果。

最終成果展示

首頁

怎么在Django中利用Highcharts 實現數據可視化

rank數據展示

怎么在Django中利用Highcharts 實現數據可視化

可以看到雖然前端頁面很簡陋,但是功能是實現了。不過有個問題 就是重新點擊query按鈕后,highcharts提供的右側頁面中間下載圖片的那個三道杠會出現并排的兩個。

上述內容就是怎么在Django中利用Highcharts 實現數據可視化,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

酒泉市| 民县| 麦盖提县| 开平市| 江达县| 桂东县| 砚山县| 西安市| 彭州市| 临江市| 卢湾区| 体育| 海丰县| 抚远县| 高台县| 嘉祥县| 东乡| 定远县| 阿坝县| 沁水县| 武穴市| 吴堡县| 太谷县| 浏阳市| 新丰县| 汝阳县| 蒲江县| 北海市| 株洲市| 邓州市| 抚州市| 巨野县| 锡林郭勒盟| 崇信县| 县级市| 阳东县| 寿阳县| 千阳县| 南雄市| 金山区| 理塘县|