顯示具有 pyecharts 標籤的文章。 顯示所有文章
顯示具有 pyecharts 標籤的文章。 顯示所有文章

2025年5月15日 星期四

[pythonanywhere] 製作水果交易網站(一) -在Django中用pyecharts製作圖表

參考文章:[ django pyecharts ] 製作水果交易網站(一) -在Django中用pyecharts製作圖表

1.在pythonanywhere上新增一個Django app,命名為mysite。

2.在consoles頁面中,利用Bash命令列,新增一個 fruitsapp app。

python manage.py startapp fruitsapp

3.修改mysite/mysite/settings.py

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
"""
Django settings for mysite project.

Generated by 'django-admin startproject' using Django 4.0.6.

For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-e91+!(y*$%$wb_e=)hxkkbpx9dw0&=(383ca6lhx1r$o)p57r-'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['chengmin.pythonanywhere.com']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_echarts',
    'fruitsapp',
]



MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'mysite.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'mysite.wsgi.application'


# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# default static files settings for PythonAnywhere.
# see https://help.pythonanywhere.com/pages/DjangoStaticFiles for more info
MEDIA_ROOT = '/home/chengmin/mysite/media'
MEDIA_URL = '/media/'
STATIC_ROOT = '/home/chengmin/mysite/static'
STATIC_URL = '/static/'

4.修改mysite/urls.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
"""mysite URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from fruitsapp.views import index
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', index)
]

5.修改mysite/fruitsapp/views.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#from jinja2 import Environment, FileSystemLoader
#from pyecharts.globals import CurrentConfig
from django.http import HttpResponse

#CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))

from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType


def index(request):
    bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

    bar.add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
    bar.add_yaxis("台北一", [29.3, 51.5, 40.3, 21.6, 24.0, 61.5, 34.2])
    bar.add_yaxis("台北二", [32.3, 51.4, 53.7, 24.7, 42.3, 23.4, 35.9])
    bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

    return HttpResponse(bar.render_embed())


6.執行結果:


2019年12月10日 星期二

[ pyecharts ] 善用開放式資料,讀取股票交易資料,製作統計圖表

在2019年1月2日,我們以僅十行指令用某支股票的代碼來查詢某個月份的交易情形,其程式碼如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import requests
import json
url = 'http://www.twse.com.tw/exchangeReport/STOCK_DAY?date=%s&stockNo=%s' % ( '20181201', '2892')
r = requests.get(url)
print(r.text)
data =json.loads(r.text)
print(data['title'])
print(data['fields'])
for row in data['data']:
    print(row)

2019年11月16曾介紹pyecharts套件的使用,在"初體驗! 使用pyecharts以水果交易行情為例"文章中,僅9行程式就能畫出台北一和台北二果菜場的交易,其程式如下:
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

bar.add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
bar.add_yaxis("台北一", [29.3, 51.5, 40.3, 21.6, 24.0, 61.5, 34.2])
bar.add_yaxis("台北二", [32.3, 51.4, 53.7, 24.7, 42.3, 23.4, 35.9])
bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

bar.render()


我們把兩支程式合併,運用串列資料把股票交易日期當成x軸,再把開盤價、最高價、'最低價、以及'收盤價當成y軸來繪製圖表,其程式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import requests
import json

url = 'http://www.twse.com.tw/exchangeReport/STOCK_DAY?date=%s&stockNo=%s' % ( '20181201', '2892')
r = requests.get(url)
print(r.text)
data =json.loads(r.text)

print(data['title'])
print(data['fields'])

price=data['fields'][3:7]
xaxis=[]
yaxis=[[],[],[],[]]

for row in data['data']:
    print(row)
    xaxis.append(row[0])
    for i, y in enumerate(yaxis):
        y.append(row[i+3])

from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

bar.add_xaxis(xaxis)
for i, y in enumerate(yaxis):
    bar.add_yaxis(price[i], y)

bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

bar.render()

執行結果:

2019年12月9日 星期一

[ pyecharts ] 善用開放式資料,讀取果菜市場交易資料,製作統計圖表

近兩年來南開科技大學執行教育部「南投百香果資源永續之煉銀網平台」,用百香果故鄉南投縣埔里鎮合成里為題設計一系列Python程式設計教材百香果USR之Python程式設計教材」,其中有一篇文章"用Python來撰寫顯示今天百香果市場交易情形的程式",介紹如何使用requests以及json套件來取得當日百香果市場交易情形,其程式如下:
import requests
import json
r = requests.get('http://data.coa.gov.tw/Service/OpenData/FromM/FarmTransData.aspx')
text = json.loads(r.text)
for row in text:
    if '百香果' in row['作物名稱']:
        print ('交易日期:'+row['交易日期'])
        print ('作物名稱:'+row['作物名稱'])
        print ('市場名稱:'+row['市場名稱'])
        print ('平均價:'+str(row['平均價']))
        print ('交易量:'+str(row['交易量']))

2019年11月16曾介紹pyecharts套件的使用,在"初體驗! 使用pyecharts以水果交易行情為例"文章中,僅9行程式就能畫出台北一和台北二果菜場的交易,其程式如下:
from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

bar.add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
bar.add_yaxis("台北一", [29.3, 51.5, 40.3, 21.6, 24.0, 61.5, 34.2])
bar.add_yaxis("台北二", [32.3, 51.4, 53.7, 24.7, 42.3, 23.4, 35.9])
bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

bar.render()

從以上兩篇文章的程式即可以組合新的程式,程式技巧利用三個變數,分別來儲存X軸資料(作物名稱以及市場名場)以及兩個Y軸的資料(平均價和交易量),本範例的農作物改用玫瑰,其程式(黃底字是有改變的地方)如下:

import requests
import json
r = requests.get('http://data.coa.gov.tw/Service/OpenData/FromM/FarmTransData.aspx')
text = json.loads(r.text)
xaxis=[]
yaxis1=[]
yaxis2=[]
for row in text:
    if '玫瑰' in row['作物名稱']:
        print ('交易日期:'+row['交易日期'])
        print ('作物名稱:'+row['作物名稱'])
        print ('市場名稱:'+row['市場名稱'])
        print ('平均價:'+str(row['平均價']))
        print ('交易量:'+str(row['交易量']))
        xaxis.append(row['作物名稱']+row['市場名稱'])
        yaxis1.append(row['平均價'])
        yaxis2.append(row['交易量'])

from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

bar.add_xaxis(xaxis)
bar.add_yaxis("平均價", yaxis1)
bar.add_yaxis("交易量", yaxis2)
bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

bar.render()

執行結果:


2019年11月16日 星期六

[ django pyecharts ] 製作水果交易網站(四) - 定時增量更新圖表

承上一篇文章:

1.修訂index.html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>

</head>
<body>
    <div id="bar" style="width:1600px; height:800px;"></div>
    <script>
        var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});
        var old_data = [];
        $(
            function () {
                fetchData(chart);
                setInterval(fetchData, 2000);
            }
        );

        function fetchData() {
            $.ajax({
                type: "GET",
                url: "http://127.0.0.1:8000/index/bar",
                dataType: "json",
                success: function (result) {
                    var options = result.data;
                    chart.setOption(options);
                    old_data = chart.getOption().series[0].data;
                }
            });
        }

        function getDynamicData() {
            $.ajax({
                type: "GET",
                url: "http://127.0.0.1:8000/index/barUpdate",
                dataType: 'json',
                success: function (result) {
                    var options = result.data;
                    old_data.push([options.name, options.value]);
                    chart.setOption({
                        series: [{
                            data: old_data
                        }]
                    });
                }
            });
        }

    </script>
</body>
</html>

2.urls.py


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"""django_charts URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from fruitsapp.views import ChartView, IndexView, ChartUpdateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/bar/', ChartView.as_view()),
    path('index/', IndexView.as_view()),
    path('index/barUpdate/', ChartUpdateView.as_view()),
]

3.views.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
import json
from random import randrange

from django.http import HttpResponse
from rest_framework.views import APIView

from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType

# Create your views here.
def response_as_json(data):
    json_str = json.dumps(data)
    response = HttpResponse(
        json_str,
        content_type="application/json",
    )
    response["Access-Control-Allow-Origin"] = "*"
    return response


def json_response(data, code=200):
    data = {
        "code": code,
        "msg": "success",
        "data": data,
    }
    return response_as_json(data)


def json_error(error_string="error", code=500, **kwargs):
    data = {
        "code": code,
        "msg": error_string,
        "data": {}
    }
    data.update(kwargs)
    return response_as_json(data)


JsonResponse = json_response
JsonError = json_error


def bar_base() -> Bar:
    c = (
        Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
        .add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
        .add_yaxis("台北一", [randrange(20, 100) for _ in range(7)])
        .add_yaxis("台北二", [randrange(20, 100) for _ in range(7)])
        .set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))
        .dump_options_with_quotes()
    )
    return c


class ChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(bar_base()))


cnt = 9


class ChartUpdateView(APIView):
    def get(self, request, *args, **kwargs):
        global cnt
        cnt = cnt + 1
        return JsonResponse({"name": cnt, "value": randrange(0, 100)})

class IndexView(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse(content=open("./templates/index.html").read())

[ django pyecharts ] 製作水果交易網站(三) - 定時全量更新數據


請先參考前一篇文章:製作水果交易網站(二) - 前後台分離


在html中加入setInterval函式,即可達成定時全量更新數據,執行結果如上圖。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>

</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script>
        var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});

        $(
            function () {
                fetchData(chart);
                setInterval(fetchData, 2000);
            }
        );

        function fetchData() {
            $.ajax({
                type: "GET",
                url: "http://127.0.0.1:8000/index/bar",
                dataType: 'json',
                success: function (result) {
                    chart.setOption(result.data);
                }
            });
        }
    </script>
</body>
</html>

[ django pyecharts ] 製作水果交易網站(二) - 前後台分離

請先參考前一篇文章:製作水果交易網站(一) -在Django中用pyecharts製作圖表

1.安裝rest_framework套件
pip install djangorestframework

2.在settings.py新增rest_framework

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
"""
Django settings for django_charts project.

Generated by 'django-admin startproject' using Django 2.2.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#ju)%^4hug_+ncl-aa4x7d413^abre=aq3_8@cxv&28l_9r&hk'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'fruitsapp',
    'rest_framework',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'django_charts.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'django_charts.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'

3.在urls.py新增路徑

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
"""django_charts URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from fruitsapp.views import ChartView, IndexView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/bar/', ChartView.as_view()),
    path('index/', IndexView.as_view()),
]

3.修改views.py程式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import json
from random import randrange

from django.http import HttpResponse
from rest_framework.views import APIView

from pyecharts.charts import Bar
from pyecharts import options as opts
from pyecharts.globals import ThemeType


# Create your views here.
def response_as_json(data):
    json_str = json.dumps(data)
    response = HttpResponse(
        json_str,
        content_type="application/json",
    )
    response["Access-Control-Allow-Origin"] = "*"
    return response


def json_response(data, code=200):
    data = {
        "code": code,
        "msg": "success",
        "data": data,
    }
    return response_as_json(data)


def json_error(error_string="error", code=500, **kwargs):
    data = {
        "code": code,
        "msg": error_string,
        "data": {}
    }
    data.update(kwargs)
    return response_as_json(data)


JsonResponse = json_response
JsonError = json_error


def bar_base() -> Bar:
    c = (
        Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
        .add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
        .add_yaxis("台北一", [randrange(20, 100) for _ in range(7)])
        .add_yaxis("台北二", [randrange(20, 100) for _ in range(7)])
        .set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))
        .dump_options_with_quotes()
    )
    return c


class ChartView(APIView):
    def get(self, request, *args, **kwargs):
        return JsonResponse(json.loads(bar_base()))


class IndexView(APIView):
    def get(self, request, *args, **kwargs):
        return HttpResponse(content=open("./templates/index.html").read())

4.新增index.html,請儲存在templates目錄下。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Awesome-pyecharts</title>
    <script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://assets.pyecharts.org/assets/echarts.min.js"></script>

</head>
<body>
    <div id="bar" style="width:1000px; height:600px;"></div>
    <script>
        var chart = echarts.init(document.getElementById('bar'), 'white', {renderer: 'canvas'});

        $(
            function () {
                fetchData(chart);
            }
        );

        function fetchData() {
            $.ajax({
                type: "GET",
                url: "http://127.0.0.1:8000/index/bar",
                dataType: 'json',
                success: function (result) {
                    chart.setOption(result.data);
                }
            });
        }
    </script>
</body>
</html>

5.啟動執行

6. 結果

[ django pyecharts ] 製作水果交易網站(一) -在Django中用pyecharts製作圖表

1.建置虛擬環境
mkvirtualenv django_charts

2.安裝django套件
pip install django

3.建立django_charts專案
django-admin startproject django_charts
cd django_charts

4.建立fruitsapp專案

5.在settings.py中設定APP名稱,在第40行程式

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
Django settings for django_charts project.

Generated by 'django-admin startproject' using Django 2.2.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '#ju)%^4hug_+ncl-aa4x7d413^abre=aq3_8@cxv&28l_9r&hk'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'fruitsapp',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'django_charts.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'django_charts.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'

5.新增路徑到urls.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"""django_charts URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
from fruitsapp.views import demo

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', demo),
]

6.在views中新增demo函式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from django.shortcuts import render
from jinja2 import Environment, FileSystemLoader
from pyecharts.globals import CurrentConfig

from django.http import HttpResponse

CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))

from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.globals import ThemeType

# Create your views here.
def demo(request):

    bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))

    bar.add_xaxis(["椪柑", "蘋果 富士進口", "番石榴 珍珠芭", "香蕉", "木瓜 網室紅肉", "甜橙 柳橙", "火龍果 紅肉"])
    bar.add_yaxis("台北一", [29.3, 51.5, 40.3, 21.6, 24.0, 61.5, 34.2])
    bar.add_yaxis("台北二", [32.3, 51.4, 53.7, 24.7, 42.3, 23.4, 35.9])
    bar.set_global_opts(title_opts=opts.TitleOpts(title="平均價", subtitle="元"))

    return HttpResponse(bar.render_embed())

7. 安裝pyecharts套件
pip install pyecharts

8. 執行migrate指令,資料同步

9.執行程式

10.查看結果