<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>上市公司全景概览 - 大屏数据可视化案例</title>
<link rel="stylesheet" type="text/css" href="css/app.css" />
</head>
<body>
<header id="header">
<h3 class="header-title">上市公司全景概览</h3>
<div class="header-info header-info-l">数据来源:上交所 & 深交所</div>
<div class="header-info header-info-r">数据日期:<span id="nowDate"></span></div>
</header>
<footer id="footer"></footer>
<div id="container">
<div id="flexCon">
<div class="flex-row">
<div class="flex-cell flex-cell-l">
<div class="chart-wrapper">
<h3 class="chart-title">市价总值排行Top10</h3>
<div class="chart-div" id="rankChart">
<div class="chart-loader"><div class="loader"></div></div>
</div>
</div>
</div>
<div class="flex-cell flex-cell-c" style="padding-right:0;">
<div class="chart-wrapper">
<h3 class="chart-title">统计数据</h3>
<div class="chart-div chart-done">
<table class="data-t">
<tr>
<th><img src="img/icon-01.png" /></th>
<td>
<p><span id="listedCompany">0</span></p>
<p>上市公司数</p>
</td>
<th><img src="img/icon-02.png" /></th>
<td>
<p><span id="listedSecurity">0</span></p>
<p>上市证券数</p>
</td>
</tr>
<tr>
<th><img src="img/icon-03.png" /></th>
<td>
<p><span id="totalMarket">0</span></p>
<p>股票总市值(亿元)</p>
</td>
<th><img src="img/icon-04.png" /></th>
<td>
<p><span id="circulationMarket">0</span></p>
<p>股票流通市值(亿元)</p>
</td>
</tr>
<tr>
<th><img src="img/icon-05.png" /></th>
<td>
<p><span id="shRatio">0</span></p>
<p>上市平均市盈率</p>
</td>
<th><img src="img/icon-06.png" /></th>
<td>
<p><span id="szRatio">0</span></p>
<p>深市平均市盈率</p>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="flex-cell flex-cell-r" style="padding-left:0;">
<div class="chart-wrapper">
<h3 class="chart-title">上市公司地域分布</h3>
<div class="chart-div" id="mapChart">
<div class="chart-loader"><div class="loader"></div></div>
</div>
</div>
</div>
</div>
<div class="flex-row">
<div class="flex-cell flex-cell-lc" style="padding-bottom:0;">
<div class="chart-wrapper">
<h3 class="chart-title">2018年月度股票情况及预测</h3>
<div class="chart-div" id="trendChart">
<div class="chart-loader"><div class="loader"></div></div>
</div>
</div>
</div>
<div class="flex-cell flex-cell-r" style="padding-bottom:0;">
<div class="chart-wrapper">
<h3 class="chart-title">CSRC行业分类</h3>
<div class="chart-div" id="csrcChart">
<div class="chart-loader"><div class="loader"></div></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="js/countUp.min.js"></script>
<script type="text/javascript" src="js/echarts.min.js"></script>
<script type="text/javascript" src="js/echarts-map-china.js"></script>
<script type="text/javascript" src="js/echarts-theme-shine.js"></script>
<script type="text/javascript">
$(function() {
(function() {
const now = new Date();
const year = now.getFullYear();
const month = now.getMonth()+1;
const day = now.getDate();
$("#nowDate").html(year+"年"+month+"月"+day+"日");
})();
$.ajax({
url: "data/count-data.json",
dataType: "json"
}).done(function(data) {
rollNum("listedCompany", 0, data.listed_companies_total);
rollNum("listedSecurity", 0, data.listed_securities_total);
rollNum("totalMarket", 0, data.total_market_value, 2);
rollNum("circulationMarket", 0, data.circulation_market_value, 2);
rollNum("shRatio", 0, data.sh_pe_ratio, 2);
rollNum("szRatio", 0, data.sz_pe_ratio, 2);
}).fail(function(jqXHR, textStatus) {
console.log("Ajax Error: ", textStatus);
});
const rankChart = echarts.init(document.getElementById("rankChart"), "shine");
const rankChartOpt = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
},
formatter: function(params) {
const param = params[0];
const marker = '<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#e6b600;"></span>';
const suffix = '<span style="margin-left:5px;font-size:12px;">亿元</span>';
return param.name + "<br />" +
marker + "排名:" + (param.dataIndex+1) + "<br />" +
marker + "市价总值:" + param.value + suffix;
}
},
grid: {
top: 10,
bottom: 10,
left: 60
},
xAxis: {
show: false,
type: "value"
},
yAxis: {
type: "category",
inverse: true,
axisLine: {show: false},
axisTick: {show: false},
axisLabel: {
fontSize: 12,
color: "#b0c2f9"
}
},
series: [{
name: "市价总值排行",
type: "bar",
barCategoryGap: "60%",
label: {
show: true,
position: "right",
fontSize: 12,
color: "#188df0",
emphasis: {
color: "#e6b600"
}
},
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0, 1, 1, 1,
[
{offset: 0, color: '#b0c2f9'},
{offset: 0.5, color: '#188df0'},
{offset: 1, color: '#185bff'}
]
)
},
emphasis: {
color: new echarts.graphic.LinearGradient(
0, 1, 1, 1,
[
{offset: 0, color: '#b0c2f9'},
{offset: 0.7, color: '#e6b600'},
{offset: 1, color: '#ceac09'}
]
)
}
}
}]
};
rankChart.setOption(rankChartOpt);
$.ajax({
url: "data/ranking-list.json",
dataType: "json"
}).done(function() {
$("#rankChart").addClass("chart-done");
}).done(function(data) {
const xData = [];
const yData = [];
for(let i in data) {
xData.push(data[i].market_capitalization);
yData.push(data[i].stock_name);
}
rankChart.setOption({
yAxis: {
data: yData
},
series: [{
name: "市价总值排行",
data: xData
}]
});
}).fail(function(jqXHR) {
console.log("Ajax Fail: ", jqXHR.status, jqXHR.statusText);
});
const mapChart = echarts.init(document.getElementById("mapChart"), "shine");
const mapChartOpt = {
tooltip: {
formatter: function(params) {
const data = params.data;
return data.name + "<br />上市公司数:" + data.value;
}
},
visualMap: {
type: "piecewise",
splitNumber: 6,
itemWidth: 10,
itemHeight: 10,
itemGap: 5,
textGap: 5,
textStyle: {
fontSize: 10,
color: "#b0c2f9"
},
min: 0,
max: 600,
calculable: true,
seriesIndex: [0]
},
geo: {
map: "china",
roam: true,
zoom: 1,
selectedMode: "single",
top: 10,
bottom: 10,
layoutCenter: ["50%", "50%"],
label: {
show: true,
fontSize: 10,
color: "#ceac09"
}
},
series: [{
name: "地域分布",
type: "map",
geoIndex: 0
}]
};
mapChart.setOption(mapChartOpt);
$.ajax({
url: "data/region-count.json",
dataType: "json"
}).done(function() {
$("#mapChart").addClass("chart-done");
}).done(function(data) {
const chartData = [];
for(let i in data) {
chartData.push({
name: data[i].region,
value: data[i].count
});
}
mapChart.setOption({
series: [{
name: "地域分布",
data: chartData
}]
});
}).fail(function(jqXHR) {
console.log("Ajax Fail: ", jqXHR.status, jqXHR.statusText);
});
const trendChart = echarts.init(document.getElementById("trendChart"), "shine");
const trendChartOpt = {
tooltip: {
trigger: "axis",
axisPointer: {
type: "none"
}
},
legend: {
left: "center",
bottom: 3,
itemWidth: 15,
itemHeight: 10,
textStyle: {
fontSize: 12,
color: "#b0c2f9"
},
data: ["市价总值", "成交总额", "平均市盈率"]
},
grid: {
top: 40,
bottom: 50,
left: 60,
right: 60
},
xAxis: {
type: "category",
axisLine: {
lineStyle: {color: "#b0c2f9"}
},
axisTick: {show: false},
axisLabel: {
fontSize: 12,
color: "#b0c2f9"
}
},
yAxis: [{
name: "金额",
type: "value",
splitNumber: 5,
axisLine: {
lineStyle: {color: "#b0c2f9"}
},
splitLine: {show: false},
axisTick: {color: "#b0c2f9"},
axisLabel: {
fontSize: 12,
color: "#b0c2f9",
formatter: (value, index) => {
return parseInt(value / 10000) + "万亿";
}
}
}, {
name: "市盈率",
type: "value",
splitNumber: 5,
maxInterval: 5,
minInterval: 5,
interval: 5,
axisLine: {
lineStyle: {color: "#b0c2f9"}
},
splitLine: {show: false},
axisTick: {color: "#b0c2f9"},
axisLabel: {
fontSize: 12,
color: "#b0c2f9"
}
}],
visualMap: {
show: false,
seriesIndex: 2,
dimension: 0,
pieces: [{
lte: 9,
color: "rgba(176, 58, 91, 1)"
}, {
gt: 9,
lte: 11,
color: "rgba(176, 58, 91, 0.5)"
}]
},
series: [{
name: "市价总值",
type: "pictorialBar",
symbol: 'path://d="M150 50 L130 130 L170 130 Z"',
barCategoryGap: "40%",
itemStyle: {
color: function(params) {
if(params.dataIndex >= 10) {
return "rgba(119, 96, 246, 0.5)";
}
return "rgba(119, 96, 246, 1)";
}
},
markPoint: {
itemStyle: {
color: "rgba(119, 96, 246, 1)"
},
data: [{
name: "最大值",
type: "max"
}]
},
markLine: {
lineStyle: {
color: "rgba(119, 96, 246, 1)"
},
label: {
position: "middle",
formatter: "月度平均市价总值:{c}亿元"
},
data: [{
name: "平均值",
type: "average"
}]
}
}, {
name: "成交总额",
type: "pictorialBar",
symbol: 'path://d="M150 50 L130 130 L170 130 Z"',
barCategoryGap: "40%",
itemStyle: {
color: function(params) {
if(params.dataIndex >= 10) {
return "rgba(230, 182, 0, 0.5)";
}
return "rgba(230, 182, 0, 1)";
}
},
markPoint: {
itemStyle: {
color: "rgba(230, 182, 0, 1)"
},
data: [{
name: "最大值",
type: "max"
}]
},
markLine: {
lineStyle: {
color: "rgba(230, 182, 0, 1)"
},
label: {
position: "middle",
formatter: "月度平均成交总额:{c}亿元"
},
data: [{
name: "平均值",
type: "average"
}]
}
}, {
name: "平均市盈率",
type: "line",
yAxisIndex: 1
}]
};
trendChart.setOption(trendChartOpt);
$.ajax({
url: "data/month-count.json",
dataType: "json"
}).done(function() {
$("#trendChart").addClass("chart-done");
}).done(function(data) {
const xData = [];
const yData1 = [];
const yData2 = [];
const yData3 = [];
for(let i in data) {
xData.push(data[i].month);
yData1.push(data[i].sh_market_capitalization);
yData2.push(data[i].sh_transaction_amount);
yData3.push(data[i].sh_pe_ratio);
}
trendChart.setOption({
xAxis: {
data: xData,
},
series: [{
name: "市价总值",
data: yData1
}, {
name: "成交总额",
data: yData2
}, {
name: "平均市盈率",
data: yData3
}]
});
}).fail(function(jqXHR) {
console.log("Ajax Fail: ", jqXHR.status, jqXHR.statusText);
});
const csrcChart = echarts.init(document.getElementById("csrcChart"), "shine");
const csrcChartOpt = {
tooltip: {
trigger: "item",
formatter: "{b0}<br />股票数:{c0}<br />占比:{d0}%"
},
legend: {
type: "scroll",
orient: "vertical",
padding: 0,
top: 15,
right: 0,
itemGap: 5,
itemWidth: 10,
itemHeight: 10,
textStyle: {
fontSize: 10,
color: "#b0c2f9"
}
},
series: [{
name: "CSRC行业分类",
type: "pie",
center: ["47%", "55%"],
radius: ["30%", "85%"]
}]
};
csrcChart.setOption(csrcChartOpt);
$.ajax({
url: "data/csrc-industry.json",
dataType: "json"
}).done(function() {
$("#csrcChart").addClass("chart-done");
}).done(function(data) {
const chartData = [];
for(let i in data) {
chartData.push({
name: data[i].alias,
value: data[i].stock
});
}
csrcChart.setOption({
series: [{
name: "CSRC行业分类",
data: chartData
}]
});
}).fail(function(jqXHR) {
console.log("Ajax Fail: ", jqXHR.status, jqXHR.statusText);
});
$(window).resize(function() {
rankChart.resize();
mapChart.resize();
trendChart.resize();
csrcChart.resize();
});
});
function rollNum(elId, startVal, endVal, decimalNum) {
let n = decimalNum || 0;
let countUp = new CountUp(elId, startVal, endVal, n, 2.5, {
useEasing: true,
useGrouping: true,
separator: ',',
decimal: '.'
});
if(!countUp.error) {
countUp.start();
}else {
console.error(countUp.error);
}
}
</script>
</body>
</html>