Highcharts图未显示在Django模板html中

问题描述 投票:0回答:1

我正在使用Django / python / sqlite3创建网站。我还使用ebay-python-sdk查询ebay数据库并根据关键字获取信息。我正在尝试将时间戳转换为毫秒,并将这些值传递到Highcharts x轴,并将商品的最终售价传递到y轴。该图未显示在Django模板(称为“ graphs.html”)中。我的代码如下:

display_graphs / views.py

from django.shortcuts import render
from ebaysdk.finding import Connection as finding
import xmltodict
from json import loads, dumps
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import io
from matplotlib.backends.backend_agg import FigureCanvasAgg
from django.http import HttpResponse

content_df = pd.DataFrame()

def display_the_graphs(request):
    keywords = request.POST.get('search')
    api = finding(appid='JohnHein-homepage-PRD-392e94856-07aba7fe', config_file=None, siteid='EBAY-US')
    api_request = {'keywords':keywords, 'itemFilter':[{'name':'SoldItemsOnly', 'value':True},]}
    response = api.execute('findCompletedItems', api_request)
    content = response.content
    xml_dict = xmltodict.parse(content)
    content_dict = to_dict(xml_dict)
    count = content_dict['findCompletedItemsResponse']['searchResult']['@count']
    item_dict = content_dict['findCompletedItemsResponse']['searchResult']['item']
    print('count:', count)
    content_df = extract_values(item_dict)
    x_values = content_df['endPrice'].tolist()
    y_values_b = content_df['endTime'].tolist()
    y_values = convert_datetime(y_values_b)
    context = {
        'response': content_df.to_html(),
        'content_df': content_df,
        'x_v': x_values,
        'y_v': y_values
    }
    return render(request, 'display_graphs/graphs.html', context)
'''
def get_time_graph(request):
    fig, ax = plt.subplots()
    ax.set_title('Scatter plot of prices over time')
    ax.set_xlabel('dates')
    ax.set_ylabel('sell prices')
    ax.scatter(content_df.endDate.values, content_df.endPrice.values, s=10, label='sell prices over time')
    canvas = FigureCanvasAgg(fig)
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    plt.close(fig)
    response = HttpResponse(buf.getvalue(), content_type='image/png')
    canvas.print_png(response)
    context = {'first_graph':response}
    return render(request, 'display_graphs/graphs.html', context)
'''
def to_dict(input_ordered_dict):
    return loads(dumps(input_ordered_dict))

def extract_values(temp_dict):
    df = pd.DataFrame(columns=['itemId','title','endPrice','location','endTime'])
    a = []
    b = []
    c = []
    d = []
    f = []
    #print('\ntype of data:\n', type(temp_dict))
    length = len(temp_dict)
    print('\nlength:\n', length)
    for index in range(length):
        for key, value in temp_dict[index].items():
            print('temp_dict[index][key]:', key)
            if key == 'itemId':
                a.append(value)
            if key == 'title':
                b.append(value)
            if key == 'sellingStatus':
                c.append(temp_dict[index]['sellingStatus']['currentPrice']['#text'])
            if key == 'location':
                d.append(value)
            if key == 'listingInfo':
                f.append(temp_dict[index]['listingInfo']['endTime'])
    df = pd.DataFrame({'itemId':pd.Series(a),'title':pd.Series(b),'endPrice':pd.Series(c),'location':pd.Series(d),'endTime':pd.Series(f)})  
    #print('\ndf:\n', df)
    #print('\narray a:\n', a)
    #print('\narray b:\n', b)
    #print('\narray c:\n', c)
    #print('\narray d:\n', d)
    #print('\narray f:\n', f)
    df['endTime'] = pd.to_datetime(df['endTime']) # datetime ISO 8601 format ---> YYYY-MM-DD HH:MM:SS +HH:MM (NOTE: '+HH:MM' is UTC offset)
    df['endTimeOfDay'],df['endDate'] = df['endTime'].apply(lambda x:x.time()),df['endTime'].apply(lambda x:x.date())
    return df

def convert_datetime(arr):
    arr2 = []
    for i in arr:
        dateobj = str(i)
        dateobj = dateobj[:19]
        arr2.append(int(datetime.datetime.strptime(dateobj, "%Y-%m-%d %H:%M:%S").timestamp())*1000)
        print('convert_datetime ',arr2[-1])
        #print('dateobj:', dateobj)
    return arr2

display_graphs / graphs.html

<!doctype html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static 'display_graphs/style.css' %}">
    <title>Display graphs page</title>
    <style>
        ul {
          list-style-type: none;
          margin: 0;
          padding: 0;
          overflow: hidden;
          background-color: #333;
        }

        li {
          float: left;
        }

        li a {
          display: block;
          color: white;
          text-align: center;
          padding: 14px 16px;
          text-decoration: none;
        }

        li a:hover:not(.active) {
          background-color: #111;
        }

        .active {
          background-color: #4CAF50;
        }
  </style>
  </head>
  <body>
      <div>
        <ul>
          <li><a class="active" href="/">Home</a></li>
          <li><a href="/blog">Blog</a></li>
          <li><a href="/contact">Contact Us</a></li>
          <li><a href="/about">About Us</a></li>
        </ul>
      </div>
      <div class="parallax5" align="center">
          <h1 style="background-color:white;align:center;color:red;padding:20px;width:50%;">Graph Page</h1>
              <p style="background-color:white;align:center;color:black;padding:50px;width:70%;">
                  Graphs are displayed below:</p><br>
                  <div id="container"></div>
                    <script src="https://code.highcharts.com/highcharts.src.js"></script>
                      <script>
                        Highcharts.chart('container', {
                            chart: {
                                type: 'scatter',
                                zoomtype:'xy'
                            },
                            title: {
                                text: 'Sell prices over time'
                            },
                            xAxis: {
                                title: {
                                    text: 'price'
                                },
                                type: 'datetime',
                            },
                            yAxis: {
                                title: {
                                    text: 'end date'
                                }
                            },
                            series: [{
                                data: x_v
                            }, {
                                data: y_v
                            }]
                        });
                      </script>

                  {% autoescape off %}
                      {{ response }}                    
                  {% endautoescape %}

              <br>

      </div>
  </body>
</html>

查询的示例日期为:2019-09-30 23:11:17 + 00:00对应的值自纪元以来已更改为毫秒:1569899477000

根据我所见过的所有文档和网站,图表应该显示,但不是。我不知道为什么。如果您需要更多信息,并且想看到目前为止的代码,那么这里是github存储库的链接:github repo link我想指出的是,我已经检查了x轴和y轴的所有值,数据类型和值计数。两个python列表的计数均为100。x轴(所有float值)的数据类型均为float。 y轴的数据类型都是整数,以纪元毫秒为单位(从YYYY-MM-DD HH:MM:SS格式的时间戳转换)。两个列表的数据看起来都没有错。我已经在命令行上手动检查了。我只是不知道为什么图表不会显示。理论上应该。我在这个问题上花费了大约8个多小时。真令人沮丧。

python django highcharts
1个回答
0
投票

所以我想出了如何在django模板上显示图表。错误一:我不得不将价格(浮动价格)从字符串更改为浮动数据类型。错误二:我将浮动价格(卖价)传递给x轴,而不是y轴。我把轴弄混了。错误三:我不得不将两个列表压缩成(x,y)对。具有两个元素的数组的列表。这使一个系列。数组中的第一个元素是x值,第二个值是y值。

FIX:我必须将数据传递给上下文脚本中的django模板,并将其传递给图表脚本部分中的变量。代码段如下:

<div id="container"></div>
                    <script src="https://code.highcharts.com/highcharts.js"></script>
                    <script src="https://code.highcharts.com/modules/series-label.js"></script>
                    <script src="https://code.highcharts.com/modules/exporting.js"></script>
                    <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
                      <script>
                        chart1 = {{ chart1|safe }};
                        Highcharts.chart('container', {
                            chart: {
                                type: 'spline'
                            },
                            title: {
                                text: 'Sell prices over time'
                            },
                            xAxis: {
                                type: 'datetime',
                                dateTimeLabelFormats: {
                                    month: '%e. %b',
                                    year: '%b'
                                },
                                title: {
                                    text: 'Date'
                                }
                            },
                            yAxis: {
                                title: {
                                    text: 'price'
                                },
                                min: 0
                            },
                            series: [{
                                data: chart1
                            }]
                        });
                      </script>

重要的代码段是这个:

chart1 = {{ chart1|safe }};

这是我对应的views.py中的代码:

from django.shortcuts import render
from ebaysdk.finding import Connection as finding
import xmltodict
from json import loads, dumps
import pandas as pd
import datetime
import matplotlib.pyplot as plt
import io
from matplotlib.backends.backend_agg import FigureCanvasAgg
from django.http import HttpResponse

content_df = pd.DataFrame()

def display_the_graphs(request):
    keywords = request.POST.get('search')
    api = finding(appid='JohnHein-homepage-PRD-392e94856-07aba7fe', config_file=None, siteid='EBAY-US')
    api_request = {'keywords':keywords, 'itemFilter':[{'name':'SoldItemsOnly', 'value':True},]}
    response = api.execute('findCompletedItems', api_request)
    content = response.content
    xml_dict = xmltodict.parse(content)
    content_dict = to_dict(xml_dict)
    count = content_dict['findCompletedItemsResponse']['searchResult']['@count']
    item_dict = content_dict['findCompletedItemsResponse']['searchResult']['item']
    print('count:', count)
    content_df = extract_values(item_dict)
    y_values = content_df['endPrice'].tolist()
    y_values = [float(i) for i in y_values]
    x_values_b = content_df['endTime'].tolist()
    x_values = convert_datetime(x_values_b)
    print('\nx_values: ', x_values,'\n')
    print('\ny_values: ', y_values,'\n')
    print('\nx_values count:', len(x_values),'\n')
    print('\ny_values count:', len(y_values),'\n')
    print('\nx_values type:', type(x_values[-1]),'\n')
    print('\ny_values type:', type(y_values[-1]),'\n')
    chart1_data = list(zip(x_values, y_values))
    print('chart1 data:', chart1_data)
    context = {
        'response': content_df.to_html(),
        'content_df': content_df,
        'chart1': chart1_data
    }
    return render(request, 'display_graphs/graphs.html', context)
'''
def get_time_graph(request):
    fig, ax = plt.subplots()
    ax.set_title('Scatter plot of prices over time')
    ax.set_xlabel('dates')
    ax.set_ylabel('sell prices')
    ax.scatter(content_df.endDate.values, content_df.endPrice.values, s=10, label='sell prices over time')
    canvas = FigureCanvasAgg(fig)
    buf = io.BytesIO()
    plt.savefig(buf, format='png')
    plt.close(fig)
    response = HttpResponse(buf.getvalue(), content_type='image/png')
    canvas.print_png(response)
    context = {'first_graph':response}
    return render(request, 'display_graphs/graphs.html', context)
'''
def to_dict(input_ordered_dict):
    return loads(dumps(input_ordered_dict))

def extract_values(temp_dict):
    df = pd.DataFrame(columns=['itemId','title','endPrice','location','endTime'])
    a = []
    b = []
    c = []
    d = []
    f = []
    #print('\ntype of data:\n', type(temp_dict))
    length = len(temp_dict)
    print('\nlength:\n', length)
    for index in range(length):
        for key, value in temp_dict[index].items():
            print('temp_dict[index][key]:', key)
            if key == 'itemId':
                a.append(value)
            if key == 'title':
                b.append(value)
            if key == 'sellingStatus':
                c.append(temp_dict[index]['sellingStatus']['currentPrice']['#text'])
            if key == 'location':
                d.append(value)
            if key == 'listingInfo':
                f.append(temp_dict[index]['listingInfo']['endTime'])
    df = pd.DataFrame({'itemId':pd.Series(a),'title':pd.Series(b),'endPrice':pd.Series(c),'location':pd.Series(d),'endTime':pd.Series(f)})  
    #print('\ndf:\n', df)
    #print('\narray a:\n', a)
    #print('\narray b:\n', b)
    #print('\narray c:\n', c)
    #print('\narray d:\n', d)
    #print('\narray f:\n', f)
    df['endTime'] = pd.to_datetime(df['endTime']) # datetime ISO 8601 format ---> YYYY-MM-DD HH:MM:SS +HH:MM (NOTE: '+HH:MM' is UTC offset)
    df['endTimeOfDay'],df['endDate'] = df['endTime'].apply(lambda x:x.time()),df['endTime'].apply(lambda x:x.date())
    return df

def convert_datetime(arr):
    arr2 = []
    for i in arr:
        dateobj = str(i)
        dateobj = dateobj[:19]
        arr2.append(int(datetime.datetime.strptime(dateobj, "%Y-%m-%d %H:%M:%S").timestamp())*1000)
        #print('convert_datetime ',arr2[-1])
        #print('dateobj:', dateobj)
    return arr2
© www.soinside.com 2019 - 2024. All rights reserved.