Web开发Node实现Web图表功能(ECharts.js,Vue3)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Web开发Node实现Web图表功能(ECharts.js,Vue3)相关的知识,希望对你有一定的参考价值。
1、简介
官网地址: https://echarts.apache.org/zh/index.html
ECharts 是一个使用 javascript 实现的开源可视化库,涵盖各行业图表,满足各种需求。
ECharts 遵循 Apache-2.0 开源协议,免费商用。
ECharts 兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等)及兼容多种设备,可随时随地任性展示。
2、安装
2.1 安装node
2.2 安装echarts
https://echarts.apache.org/zh/download.html
从哪里获取 ECharts ? 获取 ECharts 的路径有以下几种,请根据您的情况进行选择:
- 最直接的方法是在 ECharts 的官方网站中挑选适合您的版本进行下载,不同的打包下载应用于不同的开发者功能与体积的需求,或者您也可以直接下载完整版本;开发环境建议下载源代码版本,包含了常见的错误提示和警告。
- 也可以在 ECharts 的 GitHub 上下载最新的 release 版本,解压出来的文件夹里的 dist 目录里可以找到最新版本的 echarts 库。
- 或者通过 npm 获取 echarts,npm install echarts --save,详见“在 webpack 中使用 echarts”
- 由 cdn 引入,你可以在 cdnjs,npmcdn 或者国内的 bootcdn 上找到 ECharts 的最新版本。
npm install echarts
# or
npm install echarts --save
# or
npm install -g cnpm --registry=https://registry.npm.taobao.org
cnpm install echarts --save
2.3 安装vue
2.3.1 npm方式(Vite)
开发的前提条件:
- 熟悉命令行
- 已安装 16.0 或更高版本的 Node.js
新建vue工程,命令如下:
mkdir test_vue
cd test_vue
# 要使用 Vite 来创建一个 Vue 项目,非常简单:
# 这个命令会安装和执行 create-vue,它是 Vue 提供的官方脚手架工具。
npm init vue@latest
在项目被创建后,通过以下步骤安装依赖并启动开发服务器:
# cd <your-project-name>
cd vue-project
npm install
npm run dev
命令行执行情况如下: vue工程的文件夹情况如下: 浏览器访问上面命令行中的测试网址:
http://127.0.0.1:5173/
你现在应该已经运行起来了你的第一个 Vue 项目!请注意,生成的项目中的示例组件使用的是组合式 API 和 <script setup>,而非选项式 API。
Vite(法语单词,“快” 的意思)是一种新型的前端构建工具
最初是配合 Vue3.0 一起使用的,后来适配了各种前端项目,目前提供了 Vue、React、Preact 框架模板。
目前来说,Vue 使用的是 vue-cli 脚手架,React 一般使用 create-react-app 脚手架。
虽然脚手架工具不一样,但是内部的打包工具都是 Webpack。
为什么要开发一个全新的构建工具,是 Webpack 不香了吗?
当你准备将应用发布到生产环境时,请运行:
npm run build
此命令会在 ./dist 文件夹中为你的应用创建一个生产环境的构建版本。
2.3.2 npm方式(Vue CLI)
https://cli.vuejs.org/zh/ Vue CLI 是官方提供的基于 Webpack 的 Vue 工具链,它现在处于维护模式。我们建议使用 Vite 开始新的项目,除非你依赖特定的 Webpack 的特性。在大多数情况下,Vite 将提供更优秀的开发体验。
- 安装vue:
npm install -g @vue/cli
# OR
yarn global add @vue/cli
- 创建一个项目:
vue create my-project
# OR
vue ui
CLI (@vue/cli) 是一个全局安装的 npm 包,提供了终端里的 vue 命令。它可以通过 vue create 快速搭建一个新项目,或者直接通过 vue serve 构建新想法的原型。你也可以通过 vue ui 通过一套图形化界面管理你的所有项目。
2.3.3 CDN方式
你可以借助 script 标签直接通过 CDN 来使用 Vue:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
这里我们使用了 unpkg,但你也可以使用任何提供 npm 包服务的 CDN,例如 jsdelivr 或 cdnjs。当然,你也可以下载此文件并自行提供服务。
<font color=blue>通过 CDN 使用 Vue 时,不涉及“构建步骤”。这使得设置更加简单,并且可以用于增强静态的 html 或与后端框架集成。但是,你将无法使用单文件组件 (SFC) 语法。</font>
- 使用全局构建版本 该版本的所有顶层 API 都以属性的形式暴露在了全局的 Vue 对象上。这里有一个使用全局构建版本的例子:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue App</title>
</head>
<body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app"> message </div>
<script>
const createApp = Vue
createApp(
data()
return
message: Hello Vue! Test by 爱看书的小沐!
).mount(#app)
</script>
</body>
</html>
- 使用 ES 模块构建版本 在本文档的其余部分我们使用的主要是 ES 模块语法。现代浏览器大多都已原生支持 ES 模块。因此我们可以像这样通过 CDN 以及原生 ES 模块使用 Vue:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue App</title>
</head>
<body>
<div id="app"> message </div>
<script type="module">
import createApp from https://unpkg.com/vue@3/dist/vue.esm-browser.js
createApp(
data()
return
message: Hello Vue! 爱看书的小沐!
).mount(#app)
</script>
</body>
</html>
- 启用 Import maps 我们可以使用导入映射表 (Import Maps) 来告诉浏览器如何定位到导入的 vue:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue App</title>
</head>
<body>
<script type="importmap">
"imports":
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
</script>
<div id="app"> message </div>
<script type="module">
import createApp from vue
createApp(
data()
return
message: Hello Vue! 爱看书的小沐!
).mount(#app)
</script>
</body>
</html>
- 拆分模块 随着对这份指南的逐步深入,我们可能需要将代码分割成单独的 JavaScript 文件,以便更容易管理。例如:
<!-- index.html -->
<script type="module">
import createApp from vue
import MyComponent from ./my-component.js
createApp(MyComponent).mount(#app)
</script>
// my-component.js
export default
data()
return count: 0
,
template: `<div>爱看书的小沐今天看了几本书: count </div>`
如果直接在浏览器中打开了上面的 index.html,你会发现它抛出了一个错误,因为 ES 模块不能通过 file:// 协议工作。为了使其工作,你需要使用本地 HTTP 服务器通过 http:// 协议提供 index.html。
要启动一个本地的 HTTP 服务器,请先安装 Node.js,然后通过命令行在 HTML 文件所在文件夹下运行 npx serve。你也可以使用其他任何可以基于正确的 MIME 类型服务静态文件的 HTTP 服务器。
简单来说,npm 是一个 node 包管理器,npx 是一个 Node 包执行器。
NPM 是 Node 包管理器。NPM 内置在 Node.js 中,通过命令行工具 CLI 来和线上 NPM 数据库进行交互,这个数据库被称为 NPM Register,
NPX 是一个 Node 包执行器,该 Node 包可以是本地也可以是远程的。允许开发者在无需安装的情况下执行任意 Node 包。
执行本地 Node 包时,NPX 会到node_modules/.bin路径和环境变量 $PATH 里面,检查命令是否存在。
执行远程 Node 包时,NPX 会将 Node 包下载到一个临时目录中,使用以后再删除。
修改上面的index.html如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue App</title>
<script type="importmap">
"imports":
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
</script>
</head>
<body id="app">
</body>
<!-- index.html -->
<script type="module">
import createApp from vue
import MyComponent from ./my-component.js
createApp(MyComponent).mount(#app)
</script>
</html>
命令行执行如下: 浏览器访问如下:
2.3.3 生命周期
3、测试(vue)
3.1 修改App.vue(hello world)
App.vue:
<script>
export default
data()
return
msg: Hello World!
</script>
<template>
msg
<input v-model="msg">
</template>
执行命令如下:
npm run dev
浏览器访问如下: 另一个例子:
<script>
export default
data()
return
greeting: Hello World! 爱看书的小沐!
</script>
<template>
<p class="greeting"> greeting </p>
</template>
<style>
.greeting
color: blue;
font-weight: bold;
</style>
3.2 修改App.vue(计数器)
App.vue:
<script>
export default
data()
return
count: 1
,
// `mounted` is a lifecycle hook which we will explain later
mounted()
// `this` refers to the component instance.
console.log(this.count) // => 1
// data can be mutated as well
this.count = 2
</script>
<template>
爱看书的小沐今天看了几本书: count
</template>
浏览器访问如下:
3.3 修改App.vue(按钮button)
App.vue:
<script>
export default
data()
return
count: 0
,
methods:
increment()
this.count++
,
mounted()
this.increment()
</script>
<template>
<button @click="increment">爱看书的小沐今天看了几本书: count </button>
<br>
<button @click="increment">爱看书的小沐今天看了几本书: count </button>
<br>
<button @click="increment">爱看书的小沐今天看了几本书: count </button>
<br>
</template>
浏览器访问如下:
3.4 修改App.vue(列表li)
App.vue:
<script>
export default
data()
return
author:
name: John Doe,
books: [
Vue 2 - Advanced Guide,
Vue 3 - Basic Guide,
Vue 4 - The Mystery
]
,
items: [ message: Foo , message: Bar ]
,
computed:
// 一个计算属性的 getter
publishedBooksMessage()
// `this` 指向当前组件实例
return this.author.books.length > 0 ? Yes : No
</script>
<template>
<p>爱看书的小沐的书架:</p>
<span> publishedBooksMessage </span>
<li v-for="book in author.books">
book
</li>
<br>
<li v-for="(item, index) in items">
author.name - index - item.message
</li>
</template>
浏览器访问如下:
3.5 修改App.vue(事件@click)
App.vue:
<script>
export default
data()
return
name: Vue.js
,
methods:
greet(event)
// `this` inside methods points to the current active instance
alert(`Hello $this.name!`)
// `event` is the native DOM event
if (event)
alert(event.target.tagName)
,
say(message)
alert(message)
</script>
<template>
<button @click="greet">Greet</button>
<button @click="say(hi)">Say hi</button>
<button @click="say(what)">Say what</button>
</template>
浏览器访问如下:
3.6 修改App.vue(侦听器watch)
App.vue:
<script>
export default
data()
return
question: ,
answer: Questions usually contain a question mark. ;-)
,
watch:
// whenever question changes, this function will run
question(newQuestion, oldQuestion)
if (newQuestion.indexOf(?) > -1)
this.getAnswer()
,
methods:
async getAnswer()
this.answer = Thinking...
try
const res = await fetch(https://api.apiopen.top/api/sentences)
this.answer = (await res.json()).result
catch (error)
this.answer = Error! Could not reach the API. + error
</script>
<template>
<p>
爱看书的小沐随机背一首古诗:
<input v-model="question" />
</p>
<p>作者: answer.from </p>
<p>诗句: answer.name </p>
</template>
浏览器访问如下:
3.7 修改App.vue(路由route,多组件)
App.vue:
<script>
import Home from ./Home.vue
import About from ./About.vue
import NotFound from ./NotFound.vue
const routes =
/: Home,
/about: About
export default
data()
return
currentPath: window.location.hash
,
computed:
currentView()
return routes[this.currentPath.slice(1) || /] || NotFound
,
mounted()
window.addEventListener(hashchange, () =>
this.currentPath = window.location.hash
)
</script>
<template>
<a rel="nofollow" href="#/">Home</a> |
<a rel="nofollow" href="#/about">About</a> |
<a rel="nofollow" href="#/non-existent-path">Broken Link</a>
<component :is="currentView" />
</template>
Home.vue:
<template>
Home
</template>
About.vue:
<template>
About
</template>
NotFound.vue:
<template>
404
</template>
浏览器访问如下: 工程文件组织如下:
3.8 修改App.vue(状态管理,多组件)
理论上来说,每一个 Vue 组件实例都已经在“管理”它自己的响应式状态了。 它是一个独立的单元,由以下几个部分组成:
- 状态:驱动整个应用的数据源;
- 视图:对状态的一种声明式映射;
- 交互:状态根据用户在视图中的输入而作出相应变更的可能方式。 然而,当我们有多个组件共享一个共同的状态时,就没有这么简单了: 多个视图可能都依赖于同一份状态。 来自不同视图的交互也可能需要更改同一份状态。
App.vue:
<script>
import ComponentA from ./ComponentA.vue
import ComponentB from ./ComponentB.vue
export default
components:
ComponentA,
ComponentB
</script>
<template>
<ComponentA />
<ComponentB />
</template>
ComponentA.vue:
<script>
import store from ./store.js
export default
data()
return
store
</script>
<template>
<div>
<button @click="store.increment()">
来自 A: store.count
</button>
</div>
</template>
ComponentB.vue:
<script>
import store from ./store.js
export default
data()
return
store
</script>
<template>
<div>
<button @click="store.increment()">
来自 B: store.count
</button>
</div>
</template>
store.js:
import reactive from vue
export const store = reactive(
count: 0,
increment()
this.count++
)
4、测试(vue+echarts)
4.1 修改App.vue(折线图)
安装echarts库:
npm install echarts --save
不通过main.js,直接在App.vue中使用echarts的页面直接引入。 App.vue修改如下:
<script>
import * as echarts from "echarts";
import ref, onMounted,onUnmounted from vue
export default
name: "echartsBox",
setup()
let echart = echarts;
onMounted(() =>
initChart();
);
onUnmounted(() =>
echart.dispose;
);
function initChart()
let chart = echart.init(document.getElementById("myEcharts"), "dark");
chart.setOption(
title :
show:true,
text: 爱看书的小沐的每月步数,
,
xAxis:
type: "category",
data: [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月"
]
,
tooltip:
trigger: "axis"
,
yAxis:
type: "value"
,
series: [
name: 工作量,
data: [
1820,
932,
901,
3934,
1290,
1330,
1320,
801,
1102,
230,
4321,
2129
],
type: "line",
smooth: true
]
);
window.onresize = function()
chart.resize();
;
return initChart ;
;
</script>
<template>
<div class="echarts-box">
<div id="myEcharts" :style=" width: 900px, height: 300px "></div>
</div>
</template>
浏览器访问如下:
4.2 修改App.vue(柱状图)
安装echarts库:
npm install echarts --save
App.vue修改如下:
<script>
//引入echarts组件
import * as echarts from echarts
import defineComponent, onMounted from vue
export default defineComponent(
setup()
onMounted(() =>
let myChart = echarts.init(document.getElementById("myChart"));
myChart.setOption(
title :
show:true,
text: 爱看书的小沐测试柱状图,
,
tooltip: ,
xAxis:
data: [衬衫, 羊毛衫, 雪纺衫, 裤子, 高跟鞋, 袜子]
,
yAxis: ,
series: [
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20, 20, 36, 10, 10, 20],
,
]
);
)
)
</script>
<template>
<div class="echarts-box">
<div id="myChart" :style=" width: 900px, height: 300px "></div>
</div>
</template>
浏览器访问如下:
4.3 修改App.vue(面积图,provide / inject)
安装echarts库:
npm install echarts --save
npm install node-sass
npm install sass --save-dev
App.vue修改如下:
<template>
<div>
<InjectCom ></InjectCom>
</div>
</template>
<script>
import provide, reactive from vue
import * as echarts from echarts
import InjectCom from "./InjectCom.vue"
export default
setup()
provide(echarts, echarts)
,
components:
InjectCom
;
</script>
InjectCom.vue:
<template>
<div class="echart" ref="chartDom"></div>
</template>
<script setup>
//按需导入需要用到的 vue函数 和echarts
import ref, inject, onMounted, reactive from "vue";
const echarts = inject("echarts");
//获取 dom 和 父组件数据 并定义"myChart"用于初始化图表
const chartDom = ref();
// const props = defineProps(
// option: Object,
// )
let myChart = null;
let option = reactive (
title: text: "爱看书的小沐测试" ,
tooltip: ,
xAxis:
data: ["12-3", "12-4", "12-5", "12-6", "12-7", "12-8"],
,
yAxis: ,
series: [
name: "用户量",
type: "line",
data: [5, 20, 36, 10, 10, 20],
areaStyle:
normal:
,
],
)
//页面成功渲染,开始绘制图表
onMounted(() =>
myChart = echarts.init(chartDom.value)
myChart.setOption(option, true);
// myChart.setOption(props.option, true);
)
</script>
<style lang="scss" scoped>
.echart
width: 800px;
height: 500px;
</style>
浏览器访问如下:
4.4 修改App.vue / main.js(饼状图,getCurrentInstance)
vue3.0的写法,在组件中使用。 安装echarts库:
npm install echarts --save
# npm i -s echarts
main.js修改如下:
// import createApp from vue
// import App from ./App.vue
// import ./assets/main.css
// createApp(App).mount(#app)
import createApp from vue
import App from ./App.vue
// 引入 echarts
import * as echarts from echarts
const app = createApp(App)
// 全局挂载 echarts
app.config.globalProperties.$echarts = echarts
app.mount(#app)
App.vue修改如下:
<template>
<div
ref="myChart"
id="myChart"
:style=" width: 800px, height: 300px "
></div>
</template>
<script>
import getCurrentInstance, onMounted from vue;
export default
setup()
// 通过 internalInstance.appContext.config.globalProperties 获取全局属性或方法
let internalInstance = getCurrentInstance();
let echarts = internalInstance.appContext.config.globalProperties.$echarts;
onMounted(() =>
const dom = document.getElementById(myChart);
const myChart = echarts.init(dom); // 初始化echarts实例
const option =
title: text: "爱看书的小沐测试" ,
series : [
name: 访问来源,
type: pie,
radius: 55%,
roseType: angle,
data:[
value:235, name:视频广告,
value:274, name:联盟广告,
value:310, name:邮件营销,
value:335, name:直接访问,
value:400, name:搜索引擎
]
]
;
// 设置实例参数
myChart.setOption(option);
);
return ;
;
</script>
浏览器访问如下: 全局挂载后,在组件中以 vue2 的写法。 App.vue修改如下:
<template>
<div
ref="myChart"
id="myChart"
:style=" width: 800px, height: 400px "
></div>
</template>
<script>
export default
mounted()
this.drawLine();
,
methods:
drawLine()
const dom = this.$refs[myChart];
const myChart = this.$echarts.init(dom); // 初始化echarts实例
const option =
title: text: "爱看书的小沐测试" ,
series:
type: sunburst,
data: [
name: A,
value: 10,
children: [
value: 3,
name: Aa,
itemStyle:
color: red
,
value: 5,
name: Ab
]
,
name: B,
children: [
name: Ba,
value: 4
,
name: Bb,
value: 2
],
itemStyle:
color: red
,
name: C,
value: 3
],
itemStyle:
color: #aaa
,
levels: [
// 留给数据下钻的节点属性
,
itemStyle:
color: blue
]
;
// 设置实例参数
myChart.setOption(option);
;
</script>
直接在组件中引入echarts。 App.vue修改如下:
<template>
<div
ref="myChart"
id="myChart"
:style=" width: 800px, height: 400px "
></div>
</template>
<script>
// 方式二:直接在组件中引入echarts
import * as echarts from echarts;
export default
mounted()
const dom = this.$refs[myChart]; // 获取dom节点
const myChart = echarts.init(dom); // 初始化echarts实例
const option =
title: text: "爱看书的小沐测试" ,
legend: ,
tooltip: ,
dataset:
// 这里指定了维度名的顺序,从而可以利用默认的维度到坐标轴的映射。
// 如果不指定 dimensions,也可以通过指定 series.encode 完成映射,参见后文。
dimensions: [product, 2015, 2016, 2017],
source: [
product: Matcha Latte, 2015: 43.3, 2016: 85.8, 2017: 93.7,
product: Milk Tea, 2015: 83.1, 2016: 73.4, 2017: 55.1,
product: Cheese Cocoa, 2015: 86.4, 2016: 65.2, 2017: 82.5,
product: Walnut Brownie, 2015: 72.4, 2016: 53.9, 2017: 39.1
]
,
xAxis: type: category,
yAxis: ,
series: [
type: bar,
type: bar,
type: bar
]
;
// 设置实例参数
myChart.setOption(option);
;
</script>
<img src="https://img-blog.csdnimg.cn/d878f607f5fb4e149f57b9c0aba18b25.png" width="45%"><br>
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
Web开发Python实现Web图表功能(pyecharts,Flask)
<font color=purple face=华文行楷 size="5">"柳丝榆荚自芳菲,不管桃飘与李飞;"
1、简介
2、Flask + pyecharts
2.1 Flask 模板渲染
$ mkdir pyecharts-flask-demo
$ cd pyecharts-flask-demo
$ mkdir templates
将 pyecharts 模板,位于 pyecharts.render.templates 拷贝至刚新建的 templates 文件夹。
- server.py
from flask import Flask
from jinja2 import Environment, FileSystemLoader
from pyecharts.globals import CurrentConfig
from markupsafe import Markup
# 关于 CurrentConfig,可参考 [基本使用-全局变量]
CurrentConfig.GLOBAL_ENV = Environment(loader=FileSystemLoader("./templates"))
from pyecharts import options as opts
from pyecharts.charts import Bar
app = Flask(__name__, static_folder="templates")
def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
.add_yaxis("商家A", [5, 20, 36, 10, 75, 90])
.add_yaxis("商家B", [15, 25, 16, 55, 48, 8])
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="爱看书的小沐"))
)
return c
@app.route("/")
def index():
c = bar_base()
return Markup(c.render_embed())
if __name__ == "__main__":
app.run()
2.2 Flask 前后端分离
新建一个 HTML 文件。 新建 HTML 文件保存位于项目根目录的 templates 文件夹,这里以如下 index.html 为例. 主要用到了 jquery 和 pyecharts 管理的 echarts.min.js 依赖。
- index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>动态更新数据</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>
(
function ()
var result_json = result_json|tojson ;
// var result = JSON.parse(result_json);
var chart = echarts.init(document.getElementById(bar), gray, renderer: canvas);
$.ajax(
type: "GET",
url: "http://127.0.0.1:5000/barChart",
dataType: json,
data: result: result_json,
success: function (result)
chart.setOption(result);
);
)
</script>
</body>
</html>
- app.py:
from random import randrange
from flask import Flask, render_template
from pyecharts import options as opts
from pyecharts.charts import Bar
app = Flask(__name__, static_folder="templates")
def bar_base() -> Bar:
c = (
Bar()
.add_xaxis(["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"])
.add_yaxis("商家A", [randrange(0, 100) for _ in range(6)])
.add_yaxis("商家B", [randrange(0, 100) for _ in range(6)])
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-基本示例", subtitle="我是副标题"))
)
return c
@app.route("/")
def index():
return render_template("index.html")
@app.route("/barChart")
def get_bar_chart():
c = bar_base()
return c.dump_options_with_quotes()
if __name__ == "__main__":
app.run()
2.3 定时全量更新图表
前端主动向后端进行数据刷新 定时刷新的核心在于 HTML 的 setInterval 方法。
- index.html:
<!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:5000/barChart",
dataType: json,
success: function (result)
chart.setOption(result);
);
</script>
</body>
</html>
- app.py: 代码同上。
2.4 定时增量更新图表
- index.html:
<!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);
var old_data = [];
$(
function ()
fetchData(chart);
setInterval(getDynamicData, 2000);
);
function fetchData()
$.ajax(
type: "GET",
url: "http://127.0.0.1:5000/lineChart",
dataType: "json",
success: function (result)
chart.setOption(result);
old_data = chart.getOption().series[0].data;
);
function getDynamicData()
$.ajax(
type: "GET",
url: "http://127.0.0.1:5000/lineDynamicData",
dataType: "json",
success: function (result)
old_data.push([result.name, result.value]);
chart.setOption(
series: [data: old_data]
);
);
</script>
</body>
</html>
- app.py:
from random import randrange
from flask.json import jsonify
from flask import Flask, render_template
from pyecharts import options as opts
from pyecharts.charts import Line
app = Flask(__name__, static_folder="templates")
def line_base() -> Line:
line = (
Line()
.add_xaxis(["".format(i) for i in range(10)])
.add_yaxis(
series_name="",
y_axis=[randrange(50, 80) for _ in range(10)],
is_smooth=True,
label_opts=opts.LabelOpts(is_show=False),
)
.set_global_opts(
title_opts=opts.TitleOpts(title="动态数据"),
xaxis_opts=opts.AxisOpts(type_="value"),
yaxis_opts=opts.AxisOpts(type_="value"),
)
)
return line
@app.route("/")
def index():
return render_template("index.html")
@app.route("/lineChart")
def get_line_chart():
c = line_base()
return c.dump_options_with_quotes()
idx = 9
@app.route("/lineDynamicData")
def update_line_data():
global idx
idx = idx + 1
return jsonify("name": idx, "value": randrange(50, 80))
if __name__ == "__main__":
app.run()
3、Flask + echarts.js
3.1 直接渲染
- app.py:
from flask import Flask, render_template
app = Flask(__name__)
@app.route(/)
def index():
return render_template(index.html)
if __name__ == __main__:
app.run(debug=True)
- index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个 ECharts 实例</title>
<!-- 引入 echarts.js -->
<script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(main));
// 指定图表的配置项和数据
var option =
legend: ,
tooltip: ,
dataset:
source: [
[product, 2012, 2013, 2014, 2015],
[Matcha Latte, 41.1, 30.4, 65.1, 53.3],
[Milk Tea, 86.5, 92.1, 85.7, 83.1],
[Cheese Cocoa, 24.1, 67.2, 79.5, 86.4]
]
,
xAxis: [
type: category, gridIndex: 0,
type: category, gridIndex: 1
],
yAxis: [
gridIndex: 0,
gridIndex: 1
],
grid: [
bottom: 55%,
top: 55%
],
series: [
// 这几个系列会在第一个直角坐标系中,每个系列对应到 dataset 的每一行。
type: bar, seriesLayoutBy: row,
type: bar, seriesLayoutBy: row,
type: bar, seriesLayoutBy: row,
// 这几个系列会在第二个直角坐标系中,每个系列对应到 dataset 的每一列。
type: bar, xAxisIndex: 1, yAxisIndex: 1,
type: bar, xAxisIndex: 1, yAxisIndex: 1,
type: bar, xAxisIndex: 1, yAxisIndex: 1,
type: bar, xAxisIndex: 1, yAxisIndex: 1
]
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
3.2 模板渲染
- app.py:
import pandas as pd
from flask import Flask, render_template
datas =
datas2 =
df = pd.read_csv(data/datum_shift.csv)
df = df.sort_values(AREA_SOUTH_BOUND_LAT, ascending=False)
for item in df.head().values:
datas[item[0]] = item[1]
datas2[item[0]] = item[2]
app = Flask(__name__)
@app.route(/)
def index():
return render_template(index.html, datas=datas)
if __name__ == __main__:
app.run(debug=True)
- index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>房源占比前五的饼图</title>
<script src="./static/js/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width:1000px;height:400px"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(main));
option =
title:
text: datum_shift,
subtext: 饼图练习,
left: center
,
tooltip:
trigger: item
,
legend:
orient: vertical,
left: left
,
series: [
name: 各项占比,
type: pie,
radius: 50%,
data: [
% for data in datas %
value: datas[data] , name: data,
% endfor %
],
emphasis:
itemStyle:
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: rgba(0, 0, 0, 0.5)
]
;
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
</script>
</body>
</html>
3.3 异步请求$.ajax
创建目录如下:
- test_flask.py:
import json
from flask import Flask, request, jsonify,render_template
app = Flask(__name__)
@app.route(/test)
def hello_world():
return Hello World,爱看书的小沐!
@app.route("/")
def index():
return render_template("index.html")
@app.route(/getdata_bar)
def getdata_bar():
language = [python, java, c, c++, c#, php]
value = [100, 150, 100, 90, 80, 90]
return json.dumps(language:language,value:value,ensure_ascii=False)
@app.route(/getdata_pie)
def getdata_pie():
data = [
"value": 235, "name": 视频广告,
"value": 274, "name": 联盟广告,
"value": 310, "name": 邮件营销,
"value": 335, "name": 直接访问,
"value": 400, "name": 搜索引擎,
"value": 90, "name": 其他,
],
return json.dumps(data:data,ensure_ascii=False)
if __name__ == __main__:
app.run(host="0.0.0.0", port=8080)
- index.html:
<head>
<meta charset="UTF-8">
<title>Echarts</title>
<script src="https://cdn.bootcss.com/jquery/3.0.0/jquery.min.js"></script>
<script src="/static/js/echarts.min.js"></script>
<style>
body
margin: 100px;
.flex-div
display: flex;
width: auto;
</style>
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div class="flex-div">
<div id="echarts_lang" style="width: 600px;height:400px;"></div>
<div id="echarts_ad" style="width: 600px;height:400px;"></div>
<script type="text/javascript">
$(function ()
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(echarts_lang));
$.ajax(
url:/getdata_bar,
success:function (data)
json_data=JSON.parse(data)
console.info(json_data[language])
console.info(json_data[value])
var option =
title:
text: 人数统计
,
tooltip: ,
legend:
data:[2022年销量]
,
xAxis:
data: json_data[language]
,
yAxis: ,
series: [
name: 2022年销量,
type: bar,
data: json_data[value]
]
;
myChart.setOption(option);
)
)
$(function ()
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(echarts_ad));
$.ajax(
url:/getdata_pie,
success:function (data)
json_data=JSON.parse(data)
console.info(json_data[data])
option =
series : [
name: 访问来源,
type: pie,
radius: 55%,
data: json_data[data][0],
roseType: angle,
itemStyle:
normal:
shadowBlur: 200,
shadowColor: rgba(0, 0, 0, 0.5)
],
;
console.info(option)
myChart.setOption(option);
)
)
</script>
</body>
3.4 异步请求$.get
- app.py:
from flask import Flask, request, jsonify,render_template
app = Flask(__name__)
categories=["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
data=[5, 20, 36, 10, 10, 20]
data2=[111, 222, 80, 150, 75, 55]
app = Flask (__name__)
@app.route(/test)
def hello_world():
return Hello World,爱看书的小沐!
@app.route(/, methods=["GET"])
def index():
return render_template("index.html")
@app.route(/echarts, methods=["GET"])
def echarts():
return jsonify(categories = categories,data = data, data2 = data2)
if __name__ == __main__:
app.run(host="0.0.0.0", port=8080)
- index.html:
<!DOCTYPE html>
<html style="height: 100%" lang="en">
<head>
<meta charset="utf-8">
<title>My Finance</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script src="https://cdn.staticfile.org/echarts/4.8.0/echarts.min.js"></script>
<!-- 引入 vintage 主题 -->
</head>
<body>
<!-- 为ECharts准备一个具备大小(宽高)的Dom -->
<div id="main" style="width:1000px;height:300px;"></div>
<script type="text/javascript">
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById(main));
myChart.setOption(
title:
text: $.get异步数据加载示例(爱看书的小沐)
,
tooltip: ,
legend:
data: [1月销量, 2月销量]
,
xAxis:
data: []
,
yAxis: ,
series: [
name: 1月销量,
type: bar,
data: []
,
name: 2月销量,
type: bar,
data: []
]
);
// 异步加载数据
$.get(/echarts).done(function (data)
// 填入数据
myChart.setOption(
xAxis:
data: data.categories
,
axisLabel:
show: true,
interval: 0,
rotate: 40,
textStyle:
color: #333
,
series: [
name: 1月销量,
data: data.data
,
name: 2月销量,
data: data.data2
]
);
);
myChart.setOption(option);
</script>
</body>
</html>
3.5 Flask + nodejs + vue
对于 Vue 3,你应该使用 npm 上可用的 Vue CLI v4.5 作为 @vue/cli。要升级,你应该需要全局重新安装最新版本的 @vue/cli:
# 全局安装 vue-cli
yarn global add @vue/cli
# 或
cnpm install -g @vue/cli
安装完后查看版本:
$ vue --version
然后在 Vue 项目中运行:
vue upgrade --next
vue create、vue ui、vue init三种方式创建Vue项目。
创建项目:
vue init webpack vue3-test
cd vue3-test
npm run dev
访问网址:http://localhost:8080
npm install --save echarts vue-jsonp vue-resource
- D:\\0627\\vue3-test\\src\\main.js:
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from vue
import App from ./App.vue
import VueResource from vue-resource
import * as VueJsonp from vue-jsonp
// import echarts from echarts
import * as echarts from echarts;
Vue.use(VueJsonp)
Vue.use(VueResource)
Vue.prototype.$echarts = echarts
new Vue(
el: #app,
render: h => h(App)
)
- D:\\0627\\vue3-test\\src\\App.vue:
<template>
<div class="main">
<chart1 />
</div>
</template>
<script>
import chart1 from "./components/chart1.vue";
export default
components:
chart1,
,
;
</script>
- D:\\0627\\vue3-test\\src\\components\\chart1.vue:
<template>
<div>
<div id="echartContainer" style="width: 100%; height: 500px"></div>
</div>
</template>
<script>
export default
name: "chart1",
data()
return ;
,
methods:
draw()
var myChart = this.$echarts.init(
document.getElementById("echartContainer"),
"infographic"
);
myChart.setOption(
xAxis: ,
yAxis: ,
series: [
symbolSize: 5,
data: [],
type: "bar",
,
],
);
this.$http
.get("http://localhost:5000/api/demo/",
headers: "Access-Control-Allow-Origin": "*" ,
)
.then((res) =>
console.log(res.data);
myChart.hideLoading();
myChart.setOption( series: [ data: res.data.product ] );
);
,
,
mounted()
this.draw();
,
;
</script>
<style></style>
- test_flask:
from flask import Flask, jsonify, render_template
from flask.helpers import make_response
from flask_cors import CORS
app = Flask(__name__,
static_folder=./dist, #设置静态文件夹目录
template_folder = "./dist",
static_url_path="") #设置vue编译输出目录dist文件夹,为Flask模板文件目录
CORS(app, resources=r/*)
@app.route(/, methods=["GET"])
def index():
return render_template("index.html")
@app.route(/api/demo/)
def api_test():
ans = jsonify(
"product": [5, 20, 36, 10, 10, 20]
)
return make_response(ans)
if __name__ == __main__:
app.run(debug=True)
cd vue3-test
npm run build
npm run dev
访问:http://localhost:8080/ 以上是开启了两个web服务器(Flask、nodejs). 以下是开一个web服务器(Flask)的方法: 将上面打包的dist文件复制到Flask的主文件夹里,然后运行test_flask.py如下。
结语
如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;
╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地
//(ㄒoㄒ)//,就在评论处留言,作者继续改进;
o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;
(✿◡‿◡)
感谢各位大佬童鞋们的支持!
( ´ ▽´ )ノ ( ´ ▽´)っ!!!
<font color=purple face=华文行楷 size="5">"侬今葬花人笑痴,他年葬侬知是谁?"
以上是关于Web开发Node实现Web图表功能(ECharts.js,Vue3)的主要内容,如果未能解决你的问题,请参考以下文章