【问题标题】:Highcharts graph not displaying in Django template htmlHighcharts 图表未显示在 Django 模板 html 中
【发布时间】:2019-12-04 17:42:39
【问题描述】:

我正在使用 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 轴的数据类型(所有浮点值)都是浮点数。 y 轴的数据类型都是整数,以纪元毫秒为单位(从 YYYY-MM-DD HH:MM:SS 形式的时间戳转换)。两个列表的数据中都没有错误。我已经在命令行上手动检查了这个。我只是无法弄清楚为什么图表不会显示。理论上应该。我在这个问题上花了大约 8 个多小时。真的很郁闷。

【问题讨论】:

    标签: python django highcharts


    【解决方案1】:

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

    修复:我必须将数据传递给上下文中的 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
    

    【讨论】:

      猜你喜欢
      • 2013-04-05
      • 2021-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 2019-11-25
      • 2022-01-21
      • 1970-01-01
      相关资源
      最近更新 更多