动态排名柱状图能很好的表达在某一个时间周期,随着时间的变化,各参数指标的增减变化,形象直观,让人很容易理解。
├─index.html …图表静态文件
├─start.exe …启动程序
├─css …样式表目录
│ ├─common.css …核心样式表
├─js …JS封装库
│ ├─config.js …图表常用参数配置文件
│ ├─echarts5.min.js …echarts封装库
│ ├─jquery-3.3.1.min.js …jquery封装库
├─data …数据文件
│ ├─lockdata.xls …源数据文件
│ ├─data.json …动态产生的JSON数据
/*
* *Created by Poleung
* *Email [email protected]
* *Create date 2021-10-08
* *Copyright LockDataV
* *Desc data visualization project based on echarts5.0.js.
*/
//标题名称;
var title = '各省市历年GDP数据可视化动态排名';
/*子标题*/
var subtext = '数据来源:全国1949-2016年GDP数据统计(纯属虚构)';
/*主标题字号*/
var titleSize = '20';
/*参数说明:更新间隔时间
* 根据数据量的多少调整
* 2*1000,代表2秒
* */
var updateFrequency = 2000;
/*参数说明:选择第N列数据
* 0代表选择Excel第1列数据作为排序指标
* */
var dimension = 0;
/*参数说明:Y轴显示数量
* 默认显示10条数据
* */
var maxData = 10;
/*参数说明:柱图颜色数组
* 根据数据唯一名称数量总数调整个数
* */
var barColors = [
'#C1232B', '#B5C334', '#FCCE10', '#E87C25', '#27727B',
'#FE8463', '#9BCA63', '#FAD860', '#F3A43B', '#60C0DD',
'#D7504B', '#C6E579', '#F4E001', '#F0805A', '#26C0C0',
'#ff7f50', '#87cefa', '#da70d6', '#32cd32', '#6495ed',
'#ff69b4', '#ba55d3', '#cd5c5c', '#ffa500', '#40e0d0',
'#1e90ff', '#ff6347', '#7b68ee', '#00fa9a', '#ffd700',
'#6b8e23', '#ff00ff', '#3cb371', '#b8860b', '#30e0e0'
];
/*参数说明:柱图文本标签显示位置
*参数选项:
'top'
'left'
'right'
'bottom'
'inside'
'insideLeft'
'insideRight'
'insideTop'
'insideBottom'
'insideTopLeft'
'insideBottomLeft'
'insideTopRight'
'insideBottomRight'
*/
var yPosition = 'insideRight';
//构建容器并初始化DOM;
var myChart = echarts.init(document.getElementById("container"));
//获取数据并加载;
$.when(
$.getJSON('data/data.json')
).done(function (res) {
//获取数据集;
var data = res;
//获取年份;
var years = [];
for (var i = 0; i < data.length; ++i) {
if (years.length === 0 || years[years.length - 1] !== data[i][4]) {
years.push(data[i][4]);
}
}
//开始年份;
var startIndex = 1;
var startYear = years[startIndex];
//图表配置项;
var option = {
title: {
x: 'center',
text: title,
subtext: subtext,
top: '2%',
textStyle: {
fontSize: titleSize,
color: 'rgba(121,121,121, 0.9)'
}
},
grid: {
left: '5%',
right: '5%',
top: '15%',
bottom: '10%',
containLabel: true
},
xAxis: {
max: 'dataMax',
label: {
formatter: function (n) {
return Math.round(n);
}
}
},
dataset: {
source: data.slice(1).filter(function (d) {
return d[4] === startYear;
})
},
yAxis: {
type: 'category',
inverse: true,
max: maxData,//显示柱图数量
axisLabel: {
show: true,
textStyle: {
fontSize: 14
},
formatter: function (value) {
return value;
}
},
animationDuration: 300,
animationDurationUpdate: 300
},
series: [{
realtimeSort: true,
seriesLayoutBy: 'column',
type: 'bar',
itemStyle: {
color: function (param) {
return barColors[param.dataIndex] || '#5470c6';
}
},
encode: {
x: dimension,
y: 3
},
label: {
show: true,
precision: 1,
position: yPosition,//文本标签显示位置
valueAnimation: true,
fontFamily: 'monospace'
}
}],
// Disable init animation.
animationDuration: 0,
animationDurationUpdate: updateFrequency,
animationEasing: 'linear',
animationEasingUpdate: 'linear',
graphic: {
elements: [{
type: 'text',
right: "5%",
bottom: "15%",
style: {
text: startYear,
font: 'bolder 80px monospace',
fill: 'rgba(100, 100, 100, 0.25)'
},
z: 100
}]
}
};
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
//循环数据;
for (var i = startIndex; i < years.length - 1; ++i) {
(function (i) {
setTimeout(function () {
updateYear(years[i + 1]);
}, (i - startIndex) * updateFrequency);
})(i);
}
//更新年份;
function updateYear(year) {
var source = data.slice(1).filter(function (d) {
return d[4] === year;
});
option.series[0].data = source;
option.graphic.elements[0].style.text = year;
myChart.setOption(option);
window.addEventListener("resize", function () {
myChart.resize();
});
}
})
# -*- coding: UTF-8 -*-
# @Time : 2021-10-09 8:29
# @File : start.py
# @Author : LockDataV
import xlrd
import os
import json
from http.server import HTTPServer, SimpleHTTPRequestHandler
import webbrowser
# 读取excel数据并将其转为js文件
filename = r'data/lockdata.xls'
# 判断文件是否存在
file_data = os.path.exists(filename)
if not file_data:
print("系统默认data.xls表格文件不存在.")
else:
print("系统获取到文件,处理中...")
data = xlrd.open_workbook(filename) # 文件名以及路径,如果路径或者文件名有中文给前面加一个r不转义。
# 获取你要sheet的名称
sheet_name = data.sheet_names()
# 根据sheet索引或者名称获取sheet内容
sheet = data.sheet_by_index(0)
# 获取整行和整列的值(列表)
rows = sheet.row_values(0) # 获取第1行内容
# 自定义数组
tables = []
data = {}
for rown in range(sheet.nrows):
array = [sheet.cell_value(rown, 0), sheet.cell_value(rown, 1), sheet.cell_value(rown, 2), sheet.cell_value(rown, 3), sheet.cell_value(rown, 4)]
tables.append(array)
# print(tables)
# 转为JSON
res = json.dumps(tables, ensure_ascii=False)
print(res)
# 生成对应的JSON数据文件
content = '{}'.format(res)
# 写入文件
with open(r'data/data.json', 'w', encoding="utf-8") as f:
f.write(content)
print("数据转换完成..")
# 创建http server
class GetHttpServer(SimpleHTTPRequestHandler):
protocol_version = "HTTP/1.0"
server_version = "PSHS/0.1"
sys_version = "Python/3.9.x"
target = "./" # 监听目录,配置项
def do_get(self):
SimpleHTTPRequestHandler.do_GET(self)
def do_post(self):
print("postmsg recv, path error")
data = self.rfile.read(int(self.headers["content-length"]))
data = json.loads(data)
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
rspstr = "recv ok, data = "
rspstr += json.dumps(data, ensure_ascii=False)
self.wfile.write(rspstr.encode("utf-8"))
def http_server():
ip = "localhost" # 监听IP,配置项
port = 8800 # 监听端口,配置项
index_url = "http://{}:{}/index.html".format(ip, port) # 监听主页url,配置项
server = HTTPServer((ip, port), GetHttpServer)
try:
# 弹出窗口
webbrowser.open(index_url)
# 输出信息
print("服务器监听地址: ", index_url)
server.serve_forever()
except KeyboardInterrupt:
server.socket.close()
# 执行服务器脚本
http_server()
lockdatav Done!