以上是最終成功效果。出現過的問題是: 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、傳輸的數據要最小化,帶寬太大基本用不完,可以考慮前端組裝數據。前端有簡單實用的解決案例。前端方案比服務器端方案容易。(第二選)