
以上是最終成功效果。出現過的問題是: X軸日期顯示順序錯誤問題;X軸與Y軸數據不對應問題;
data 是 裝滿對象的數組。
注意: 疊加柱狀圖需要賦值 xData,而曲線可要可不要。
initChart3 是初始化疊加柱狀圖
initChart2 是初始化 曲線圖
var chart3, chart2
function initChart3(data) {
var chartId = "chart3" ;
//$("#" + chartId).height(400);
var chart = echarts.init(document.getElementById(chartId), 'light');
var yAxisName = "微博數量3";
var color;
var titleText="";
chart3 = chart;
var series = [];
//方式一
var xData0 = arrayObjectDistinctReturnKey(data, 'YearAndMonth');//日期去重
//解決日期排序問題
var xData = sortData2(xData0, "order");//僅對日期排序
//疊加柱狀圖需要賦值 xData,而曲線可要可不要。
//方式二
//var data = sortData(data2, "order", "YearAndMonth");//data2指數據源,這里對整個數據源排序
//var xData = arrayObjectDistinctReturnKey(data2, 'YearAndMonth');
//console.log('data', data);
//console.log('xData', xData);
for (let i = 0; i < typeValueList.length; i++) {
var arr1 = [];
for (var j = 0; j < data.length; j++) {
var item = data[j];
if (item["WeiboType"] == typeValueList[i]) {
arr1.push([item["YearAndMonth"], item["Number"]]);
}
}
var seriesData = [];
series.push({
name: typeLabelList[i],
type: 'bar',
data: arr1,
//barWidth: 21,
stack: '疊加標志',
//itemStyle: {//柱狀圖上方顯示數值
// normal: {
// label: {
// show: true, //開啟顯示
// position: 'top', //在上方顯示
// textStyle: { //數值樣式
// color: 'black',
// fontSize: 16
// }
// }
// }
//}
})
}
//console.log('series', series);
var option=
{
color: ['rgb(255,219,92)', 'rgb(55,162,218)', 'rgb(224,98,174)', 'rgb(255,159,127)'],
title: [
{
top: 14,
text: titleText,
show: true,
left: "center"
}
],
tooltip: {
trigger: 'axis',
confine: true,
formatter: function (data) {
return TooltipFormatterX(data);//解決日期排序問題
}
},
legend: {
top: 30,
type: 'scroll',
left: '13%',
data: typeLabelList
},
toolbox: {
right: '20px',
// left: 'right',
feature: {
dataView: {
show: true,
title: '數據視圖',
lang: ['<div class="table-header-title" >' + titleText + '</div>', '關閉'],
readOnly: true, // 點擊刷新按鈕會導致第二列數據消失,此處設置只讀是為了隱藏刷新按鈕。
optionToContent: function (opt) {
// console.log('bar-opt', opt)
return ToolboxDataViewX(opt, xData);//解決日期排序問題
}
},
saveAsImage: { show: true }
}
},
grid: {
top: 70,
left: '3%',
right: '4%',
bottom: '5%',
// bottom: '10%',
containLabel: true,
},
xAxis: [
{
type: 'category',
data: xData,
axisLabel: {
interval: 0, //坐標軸刻度標簽的顯示間隔.設置成 0 強制顯示所有標簽。設置為 1,隔一個標簽顯示一個標簽。
rotate: 45,//傾斜度 -90 至 90 默認為0
//textStyle: {
// fontWeight: "bold", //加粗
// color: "#000000" //黑色
//},
},
}
],
yAxis: [
{
type: 'value',
name: yAxisName,
//min: 0,
//max:500
//min: function (value) {
// return value.min;
//},
//max: function (value) {
// return value.max;
//}
}
],
series: series,
}
chart.setOption(option);//必須加true,否則疊加狀態只更新部分值,而不去覆蓋。
}
function initChart2(data) {
var chartId = "chart2" ;
//$("#" + chartId).height(400);
var chart = echarts.init(document.getElementById(chartId), 'light');
var yAxisName = "情感分值";
var color;
var titleText="";
chart1 = chart;
var series = [];
//var data = sortData(data, "order", "YearAndMonth");
//var xData = arrayObjectDistinctReturnKey(data, 'YearAndMonth');
var xData0 = arrayObjectDistinctReturnKey(data, 'YearAndMonth');
var xData = sortData2(xData0, "order");//解決日期排序問題
for (let i = 0; i < typeValueArr.length; i++) {
var arr1 = [];
for (var j = 0; j < data.length; j++) {
var item = data[j];
if (item["WeiboType"] == typeValueArr[i]) {
arr1.push([item["YearAndMonth"], item["EmotionAnalysis"]]);//解決日期排序問題
}
}
//console.log('arr1',arr1);
var seriesData=[];
series.push({
name: typeLabelArr[i],
type: 'line',
data: arr1,
smooth: true, //這句就是讓曲線變平滑的
connectNulls: true,
//barWidth: 21,
//stack: '疊加標志',
//itemStyle: {//柱狀圖上方顯示數值
// normal: {
// label: {
// show: true, //開啟顯示
// position: 'top', //在上方顯示
// textStyle: { //數值樣式
// color: 'black',
// fontSize: 16
// }
// }
// }
//}
})
}
// console.log('series', series);
var option=
{
color: ['rgb(175,238,238)', 'rgb(255,219,92)', 'rgb(55,162,218)', 'rgb(224,98,174)', 'rgb(255,159,127)'],
title: [
{
top: 14,
text: titleText,
show: true,
left: "center"
}
],
tooltip: {
trigger: 'axis',
confine: true,
formatter: function (data) {
return TooltipFormatterX(data);//解決日期排序問題
}
},
legend: {
top: 30,
type: 'scroll',
left: '13%',
data: typeLabelArr
},
toolbox: {
right: '20px',
// left: 'right',
feature: {
dataView: {
show: true,
title: '數據視圖',
lang: ['<div class="table-header-title" >' + titleText + '</div>', '關閉'],
readOnly: true, // 點擊刷新按鈕會導致第二列數據消失,此處設置只讀是為了隱藏刷新按鈕。
optionToContent: function (opt) {
// console.log('bar-opt', opt)
return ToolboxDataViewX(opt, xData);//解決日期排序問題
}
},
saveAsImage: { show: true }
}
},
grid: {
top: 70,
left: '3%',
right: '4%',
bottom: '5%',
// bottom: '10%',
containLabel: true,
},
xAxis: [
{
type: 'category',
// data: xData,
axisLabel: {
interval: 0, //坐標軸刻度標簽的顯示間隔.設置成 0 強制顯示所有標簽。設置為 1,隔一個標簽顯示一個標簽。
rotate: 45,//傾斜度 -90 至 90 默認為0
//textStyle: {
// fontWeight: "bold", //加粗
// color: "#000000" //黑色
//},
},
}
],
yAxis: [
{
type: 'value',
name: yAxisName,
//min: 0,
//max:500
//min: function (value) {
// return value.min;
//},
//max: function (value) {
// return value.max;
//}
}
],
series: series,
}
chart.setOption(option);//必須加true,否則疊加狀態只更新部分值,而不去覆蓋。
}
// X軸無值
function ToolboxDataViewX(opt, axisData) {
console.log("ToolboxDataViewX", opt);
var series = opt.series; //折線圖數據
var tdHeads = '<td style="padding: 0 10px">時間</td>'; //表頭第一列
var tdBodys = ''; //表數據
//餅圖
if (opt.series[0].type == "pie") {
//組裝表頭
for (var i = 0, len = series[0].data.length; i < len; i++) {
tdHeads += '<td style="padding: 0 10px">' + series[0].data[i].name + '</td>';
}
var table = '<table border="1" class="table-bordered table-striped" style="width:100%;text-align:center" ><tbody><tr>' + tdHeads + ' </tr>';
//行數
//列數
for (var i = 0, len = series[0].data.length; i < len; i++) {
var temp = series[0].data[i].value;
if (temp != null && temp != undefined) {
tdBodys += '<td>' + temp + '</td>';
} else {
tdBodys += '<td></td>';
}
}
table += '<tr><td style="padding: 0 10px">' + "合計" + '</td>' + tdBodys + '</tr>';
tdBodys = '';
} else { //柱狀圖 曲線圖
//組裝表頭
for (var i = 0; i < series.length; i++) {
tdHeads += '<td style="padding: 0 10px">' + series[i].name + '</td>';
}
var table = '<table border="1" class="table-bordered table-striped" style="width:100%;text-align:center" ><tbody><tr>' + tdHeads + ' </tr>';
//var axisData = opt.xAxis[0].data; //坐標數據
var sumObj = {};
var tdBodysSum = '';//合計行數據
//合計行數據 初始化為0
for (var j = 0; j < series.length ; j++) {
sumObj[series[j].name] = 0;
}
//console.log("sumObj0", sumObj);
//組裝表數據
//行數
for (var i = 0; i < axisData.length; i++) {
//列數
for (var j = 0; j < series.length ; j++) {
//返回日期相同項
for (let k = 0, len = series[j].data.length; k < len; k++) {
if (axisData[i] == series[j].data[k][0]) {
var temp = series[j].data[k][1];
if (temp != null && temp != undefined) {
tdBodys += '<td>' + temp + '</td>';
sumObj[series[j].name] += temp;
} else {
tdBodys += '<td></td>';
}
}
}
}
table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
tdBodys = '';
}
//console.log("sumObj", sumObj);
//拼接合計行表格
for (var j = 0; j < series.length ; j++) {
tdBodysSum += '<td>' + sumObj[series[j].name] + '</td>'
}
//console.log("tdBodysSum", tdBodysSum);
// table += '<tr><td style="padding: 0 10px">' + '合計' + '</td>' + tdBodysSum + '</tr>';
}
table += '</tbody></table>';
return table;
}
function ToolboxDataView(opt) {
console.log("ToolboxDataView", opt);
var series = opt.series; //折線圖數據
var tdHeads = '<td style="padding: 0 10px">時間</td>'; //表頭第一列
var tdBodys = ''; //表數據
//餅圖
if (opt.series[0].type == "pie") {
//組裝表頭
for (var i = 0,len= series[0].data.length; i <len; i++) {
tdHeads += '<td style="padding: 0 10px">' + series[0].data[i].name + '</td>';
}
var table = '<table border="1" class="table-bordered table-striped" style="width:100%;text-align:center" ><tbody><tr>' + tdHeads + ' </tr>';
//行數
//列數
for (var i = 0, len = series[0].data.length; i < len; i++) {
var temp = series[0].data[i].value;
if (temp != null && temp != undefined) {
tdBodys += '<td>' + temp + '</td>';
} else {
tdBodys += '<td></td>';
}
}
table += '<tr><td style="padding: 0 10px">' + "合計" + '</td>' + tdBodys + '</tr>';
tdBodys = '';
} else { //柱狀圖
//組裝表頭
for (var i = 0; i < series.length; i++) {
tdHeads += '<td style="padding: 0 10px">' + series[i].name + '</td>';
}
var table = '<table border="1" class="table-bordered table-striped" style="width:100%;text-align:center" ><tbody><tr>' + tdHeads + ' </tr>';
var axisData = opt.xAxis[0].data; //坐標數據
var sumObj = {};
var tdBodysSum = '';//合計行數據
//合計行數據 初始化為0
for (var j = 0; j < series.length ; j++) {
sumObj[series[j].name] = 0;
}
//console.log("sumObj0", sumObj);
//組裝表數據
//行數
for (var i = 0; i < axisData.length; i++) {
//列數
for (var j = 0; j < series.length ; j++) {
var temp = series[j].data[i];
if (temp != null && temp != undefined) {
tdBodys += '<td>' + temp + '</td>';
sumObj[series[j].name] += temp;
} else {
tdBodys += '<td></td>';
}
}
table += '<tr><td style="padding: 0 10px">' + axisData[i] + '</td>' + tdBodys + '</tr>';
tdBodys = '';
}
//console.log("sumObj", sumObj);
//拼接合計行表格
for (var j = 0; j < series.length ; j++) {
tdBodysSum += '<td>' + sumObj[series[j].name] + '</td>'
}
//console.log("tdBodysSum", tdBodysSum);
// table += '<tr><td style="padding: 0 10px">' + '合計' + '</td>' + tdBodysSum + '</tr>';
}
table += '</tbody></table>';
return table;
}
/**************************echarts 公用方法*********************
*****************************************/
function TooltipFormatter(data) {
var seriesNames = [];
var formateStrings = [];
var formateString = "";
if (data.length > 0) {
formateStrings.push(data[0].axisValue);
for (i in data) {
var item = data[i];
seriesNames.push(item.seriesName);
if (item.value != null) {
formateStrings.push(item.marker + item.seriesName + ": " + format45(item.value,1000));
}
}
formateString = formateStrings.join("<br />");
return formateString;
}
}
function TooltipFormatterX(data) {
//console.log('TooltipFormatterX', data);
var seriesNames = [];
var formateStrings = [];
var formateString = "";
if (data.length > 0) {
formateStrings.push(data[0].axisValue);
for (i in data) {
var item = data[i];
seriesNames.push(item.seriesName);
if (item.value != null && item.value.length>0) {
formateStrings.push(item.marker + item.seriesName + ": " + format45(item.value[1], 1000));
}
}
formateString = formateStrings.join("<br />");
return formateString;
}
}
沒有寫明的函數:
根據數組 對象的時間字符串排序(轉載)
https://www.cnblogs.com/hao-1234-1234/p/14269048.html
經驗教訓:
這個問題是由數據缺失造成的,所以我開始就去數據庫想要建一個新的視圖,然后右連接補充一個有類別核心字段為空的行。
但我發現好幾個類別的日期都不全,對數據庫函數、產量並不擅長。所以我選擇前端造成數據組裝。但又有兩個方法必須聯動。
其實最簡單的方法是服務器端 組裝數據!
去重查詢表所有日期
去重查詢表所有類別。
for 類別[
for日期[
根據類別和日期必須數據,有就賦值給對象a,沒有就新建對象a. 然后把類別和日期賦值和它,核心字段為空。
]
]
這樣前端代碼不用改,比前端組裝數據少改兩個方法!
不要上來就做,而是思考多種技術方案,然后選擇最容易的那種。
如果沒有想到方案,要有最優解模式:
1、有極致的性能要求或能馬上解決問題的sql方法,才考慮數據庫端。(最后選)
2、有一定代碼量或邏輯的,一定在服務器端解決。(首選)
3、傳輸的數據要最小化,帶寬太大基本用不完,可以考慮前端組裝數據。前端有簡單實用的解決案例。前端方案比服務器端方案容易。(第二選)
