mixins.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425
  1. /* 图表配置设置 */
  2. import Highcharts from 'highcharts';
  3. import { defaultOpts, seasonOptions,getTerminal,browser } from '@/utils/defaultOptions';
  4. // 散点x轴
  5. const scatterXAxis = {
  6. tickPosition: 'inside',
  7. lineColor: '#bfbfbf',
  8. tickColor: '#bfbfbf',
  9. tickLength:5,
  10. ordinal: false,
  11. type: 'linear'
  12. }
  13. // y轴静态配置
  14. const basicYAxis = {
  15. tickLength: 5,
  16. lineWidth: 1,
  17. lineColor: '#bfbfbf',
  18. tickColor: '#bfbfbf',
  19. // offset: 0,
  20. visible: true,
  21. gridLineWidth: 0,
  22. tickPosition: 'inside',
  23. endOnTick: false,
  24. startOnTick: false,
  25. showLastLabel: true,
  26. tickPixelInterval: 50,
  27. }
  28. export default {
  29. data() {
  30. return {
  31. bgList:[
  32. {image_url:require('@/assets/img/ppt_m/bg3.jpg')},
  33. {image_url:require('@/assets/img/ppt_m/bg4.jpg')},
  34. {image_url:require('@/assets/img/ppt_m/bg5.jpg')},
  35. // {image_url:'https://hzstatic.hzinsights.com/ppt/bg3.jpg'},
  36. // {image_url:'https://hzstatic.hzinsights.com/ppt/bg4.jpg'},
  37. // {image_url:'https://hzstatic.hzinsights.com/ppt/bg5.jpg'},
  38. ],//首页背景
  39. //领先频度对应英文
  40. leadUnitEnMap: {
  41. '年': 'Y',
  42. '季': 'Q',
  43. '月': 'M',
  44. '周': 'W',
  45. '天': 'D',
  46. },
  47. /* 奇怪柱形图 */
  48. barDateList: [],//柱形图的绘图数据
  49. barXIdData: [],//柱形图的x轴
  50. barEdbData: [],//柱形图的表格数据 只用于取值
  51. chartLimit: {},
  52. /* 商品价格曲线 */
  53. commodityChartData: [],
  54. commodityXData: [],
  55. commodityEdbList: [],
  56. /* 时间截面散点图 */
  57. sectionScatterData: {},
  58. relevanceChartData:null,//相关性图表
  59. relevanceUnitEnMap:{
  60. '年': 'Year',
  61. '季': 'Season',
  62. '月': 'Month',
  63. '周': 'Week',
  64. '天': 'Day',
  65. },
  66. /* 统计频率图 */
  67. statisticFrequencyData: {}
  68. }
  69. },
  70. methods: {
  71. /* 设置options 曲线图 季节图*/
  72. setOptions() {
  73. // ChartType: 1曲线图 2季节图 3面积 4柱状 5散点 6组合 季节图中公历和农历数据结构不同
  74. const chartSetMap = {
  75. 1: this.setDefaultChart,
  76. 2: this.setSeasonChart,
  77. 3: this.setStackOrCombinChart,
  78. 4: this.setStackOrCombinChart,
  79. 5: this.setScatterChart,
  80. 6: this.setStackOrCombinChart
  81. };
  82. chartSetMap[this.chartInfo.ChartType]&&chartSetMap[this.chartInfo.ChartType]()
  83. },
  84. /* 曲线 */
  85. setDefaultChart() {
  86. //拼接标题 数据列
  87. let data = [],
  88. ydata = [];
  89. let rightTwoIndex = this.dataList.findIndex((item) => item.IsAxis ===2);
  90. // const chartData = _.cloneDeep(this.dataList);
  91. let chartData = this.dataList.some(_ =>_.IsAxis===2) ? this.changeEdbOrder(this.dataList) : _.cloneDeep(this.dataList);
  92. chartData.forEach((item, index) => {
  93. //轴位置值相同的下标
  94. let sameSideIndex = chartData.findIndex(i => i.IsAxis === item.IsAxis);
  95. //y轴
  96. let yItem = {
  97. ...basicYAxis,
  98. title: {
  99. text: item.Unit,
  100. textCh:item.Unit,//中文单位
  101. textEn:item.Unit?item.UnitEn:'',//英文单位,但如果无中文单位则不显示
  102. // text: null,
  103. align: 'high',
  104. rotation: 0,
  105. y: -15,
  106. x: (item.IsAxis===0 && rightTwoIndex>-1) ? -chartData[rightTwoIndex].Unit.length*12 : 0,
  107. textAlign: item.IsAxis===1 ? 'left' : 'right',
  108. reserveSpace: false
  109. },
  110. labels: {
  111. formatter: function (ctx) {
  112. let val = ctx.value;
  113. return val;
  114. },
  115. align: 'center',
  116. x: [0,2].includes(item.IsAxis) ? 5 : -5,
  117. style: {
  118. fontSize: '10px',
  119. },
  120. },
  121. opposite: [0,2].includes(item.IsAxis),
  122. reversed: item.IsOrder,
  123. min: Number(item.MinData),
  124. max: Number(item.MaxData),
  125. tickWidth: 1,
  126. visible: sameSideIndex === index
  127. };
  128. // //拼接标题 判断相同指标名称拼接来源
  129. let dynamic_title = item.EdbName;
  130. let dynamic_arr = chartData.filter(
  131. (item) => dynamic_title === item.EdbName
  132. );
  133. // 拼接配置 IsAxis左轴1 右轴0 IsOrder正序false 逆序true EdbInfoType是否是领先指标
  134. let dynamic_tag = this.concatDynamicTag(item);
  135. let dynamic_tag_en = this.concatDynamicTag(item,'en');
  136. //预测指标配置
  137. let predict_params = item.EdbInfoCategoryType === 1 ? this.getPredictParams(item) : {};
  138. //中英文名称
  139. const nameCh = dynamic_arr.length > 1
  140. ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
  141. : `${item.EdbName}${dynamic_tag}`
  142. const nameEn = item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:''
  143. //数据列
  144. let obj = {
  145. data: [],
  146. type: 'spline',
  147. yAxis: sameSideIndex,
  148. name:nameCh,
  149. nameCh:nameCh,
  150. nameEn:nameEn,
  151. color: item.ChartColor,
  152. lineWidth: Number(item.ChartWidth),
  153. ...predict_params
  154. };
  155. item.DataList = item.DataList || [];
  156. for (let i of item.DataList) {
  157. obj.data.push([i.DataTimestamp, i.Value]);
  158. }
  159. data.push(obj);
  160. ydata.push(yItem);
  161. });
  162. // 范围为1年内 x轴显示为月/日 否则默认年/月
  163. this.xTimeDiffer();
  164. this.options = {
  165. series: data,
  166. yAxis: ydata
  167. };
  168. //滚动相关性独立tooltip
  169. if(this.chartInfo.Source === 4) {
  170. const { LeadValue,LeadUnit } = this.relevanceChartData.CorrelationChartInfo;
  171. let relevanceUnitEnMap = this.relevanceUnitEnMap;
  172. this.options.tooltip = {
  173. formatter: function() {
  174. let str = `${Highcharts.dateFormat('%Y/%m/%d',this.x)}<br><p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${LeadValue+LeadUnit}</p>`
  175. return str
  176. },
  177. formatterCh: function() {
  178. let str = `${Highcharts.dateFormat('%Y/%m/%d',this.x)}<br><p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${LeadValue+LeadUnit}</p>`
  179. return str
  180. },
  181. formatterEn: function() {
  182. let str = `${Highcharts.dateFormat('%Y/%m/%d',this.x)}<br><p>Correlation coefficient:${this.y.toFixed(4)}</p><br><p>lead${LeadValue+relevanceUnitEnMap[LeadUnit]}</p>`
  183. return str
  184. }
  185. }
  186. }
  187. },
  188. /* 堆叠柱 堆叠面积 组合图 */
  189. setStackOrCombinChart() {
  190. const chartTypeMap = {
  191. 3: 'areaspline',
  192. 4: 'column',
  193. 6: ''
  194. };
  195. let chartStyle = chartTypeMap[this.chartInfo.ChartType];
  196. //拼接标题 数据列
  197. let data = [],
  198. ydata = [];
  199. let chartData = this.dataList.some(_ =>_.IsAxis===2) ? this.changeEdbOrder(this.dataList) : _.cloneDeep(this.dataList);
  200. chartData.forEach((item, index) => {
  201. //轴位置值相同的下标
  202. let sameSideIndex = chartData.findIndex(i => i.IsAxis === item.IsAxis);
  203. //堆叠图的yAxis必须一致 数据列所对应的y轴
  204. let serie_yIndex = index;
  205. if([3,4].includes(this.chartInfo.ChartType)) {
  206. // 类型为堆叠图时公用第一个指标y轴
  207. serie_yIndex = 0;
  208. } else if(this.chartInfo.ChartType ===6 && ['areaspline','column'].includes(item.ChartStyle)) {
  209. // 组合图找第一个堆叠柱状或面积的作为公用
  210. serie_yIndex = chartData.findIndex(i => i.ChartStyle === item.ChartStyle);
  211. }
  212. //数据对应的y轴是公用轴则配置也共享
  213. item.IsAxis = serie_yIndex === index ? item.IsAxis : chartData[serie_yIndex].IsAxis;
  214. item.IsOrder = serie_yIndex === index ? item.IsOrder : chartData[serie_yIndex].IsOrder;
  215. let rightTwoIndex = [3,4].includes(this.chartInfo.ChartType)
  216. ? -1
  217. : this.dataList.findIndex((item) => item.IsAxis===2);
  218. //y轴
  219. let yItem = {
  220. ...basicYAxis,
  221. title: {
  222. //text: sameSideIndex !== index ? '' : `${item.Unit}`,
  223. text:item.Unit,
  224. textCh:item.Unit,//中文单位
  225. textEn:item.Unit?item.UnitEn:'',//英文单位,但如果无中文单位则不显示
  226. // text: null,
  227. align: 'high',
  228. rotation: 0,
  229. y: -15,
  230. x: (item.IsAxis===0 && rightTwoIndex>-1) ? -chartData[rightTwoIndex].Unit.length*12 : 0,
  231. textAlign: item.IsAxis===1 ? 'left' : 'right',
  232. reserveSpace: false
  233. },
  234. labels: {
  235. formatter: function (ctx) {
  236. let val = ctx.value;
  237. return sameSideIndex !== index ? '' : val;
  238. },
  239. align: 'center',
  240. x: [0,2].includes(item.IsAxis) ? 5 : -5,
  241. style: {
  242. fontSize: '10px',
  243. },
  244. },
  245. opposite: [0,2].includes(item.IsAxis),
  246. reversed: item.IsOrder,
  247. min: Number(chartData[sameSideIndex].MinData),
  248. max: Number(chartData[sameSideIndex].MaxData),
  249. tickWidth: sameSideIndex !== index ? 0 : 1,
  250. visible: serie_yIndex === index && sameSideIndex ===index
  251. };
  252. // //拼接标题 判断相同指标名称拼接来源
  253. let dynamic_title = item.EdbName;
  254. let dynamic_arr = chartData.filter(
  255. (item) => dynamic_title === item.EdbName
  256. );
  257. // 拼接配置 IsAxis左轴1 右轴0 IsOrder正序false 逆序true EdbInfoType是否是领先指标
  258. let dynamic_tag = this.concatDynamicTag(item);
  259. let dynamic_tag_en = this.concatDynamicTag(item,'en');
  260. //预测指标配置
  261. let predict_params = item.EdbInfoCategoryType === 1 ? this.getPredictParams(item,chartStyle) : {};
  262. //中英文名称
  263. const nameCh = dynamic_arr.length > 1
  264. ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
  265. : `${item.EdbName}${dynamic_tag}`
  266. const nameEn = item.EdbNameEn?`${item.EdbNameEn}${dynamic_tag_en}`:''
  267. //数据列
  268. let obj = {
  269. data: [],
  270. type: chartStyle || item.ChartStyle,
  271. yAxis: serie_yIndex,
  272. name:nameCh,
  273. nameCh:nameCh,
  274. nameEn:nameEn,
  275. color: item.ChartColor,
  276. lineWidth: (this.chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? Number(item.ChartWidth) : 0,
  277. fillColor: (this.chartInfo.ChartType === 3 || (this.chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
  278. borderWidth: 1,
  279. borderColor: item.ChartColor,
  280. zIndex: (this.chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? 1 : 0, //防止组合图曲线被遮住
  281. ...predict_params
  282. };
  283. item.DataList = item.DataList || [];
  284. for (let i of item.DataList) {
  285. obj.data.push([i.DataTimestamp, i.Value]);
  286. }
  287. data.push(obj);
  288. ydata.push(yItem);
  289. });
  290. // 范围为1年内 x轴显示为月/日 否则默认年/月
  291. this.xTimeDiffer()
  292. this.options = {
  293. series: data,
  294. yAxis: ydata
  295. };
  296. },
  297. /* 季节图配置 */
  298. setSeasonChart() {
  299. /* 季节性图的图表配置 */
  300. const chartData = this.dataList[0];
  301. let seasonYdata = [],
  302. seasonData = [],
  303. chart = {
  304. spacing: [5, 8, 2, 8],
  305. };
  306. /* 公历数据处理 处理数据列 y轴 */
  307. if (this.chartInfo.Calendar === '公历')
  308. for (let j of chartData.DataList) {
  309. //预测指标配置
  310. let predict_params = chartData.EdbInfoCategoryType === 1 ? this.getSeasonPredictParams(j.CuttingDataTimestamp) : {};
  311. let serie_item = {
  312. data: [],
  313. type: chartData.ChartStyle,
  314. yAxis: 0,
  315. name: j.Year,
  316. ...predict_params
  317. };
  318. const data_array = _.cloneDeep(j.DataList);
  319. data_array &&
  320. data_array.forEach((item) => {
  321. serie_item.data.push([item.DataTimestamp, item.Value]);
  322. });
  323. const index = chartData.DataList.findIndex(
  324. (item) => item.Year === j.Year
  325. );
  326. const s_yItem = {
  327. title: {
  328. text: `${chartData.Unit}`,
  329. textCh:chartData.Unit,
  330. textEn:chartData.Unit?chartData.UnitEn:'',
  331. // text: null,
  332. align: 'high',
  333. rotation: 0,
  334. y: -15,
  335. offset: -(12 * chartData.Unit.length),
  336. },
  337. labels: {
  338. formatter: function (ctx) {
  339. let val = ctx.value;
  340. return index !== 0 ? '' : val;
  341. },
  342. align: 'center',
  343. style: {
  344. fontSize: '10px',
  345. },
  346. x: -5,
  347. },
  348. max: Number(chartData.MaxData),
  349. min: Number(chartData.MinData),
  350. ...seasonOptions.yAxis,
  351. };
  352. seasonData.push(serie_item);
  353. seasonYdata.push(s_yItem);
  354. }
  355. /* 农历数据处理 */
  356. let filterArr =
  357. this.chartInfo.Calendar === '农历'
  358. ? chartData.DataList.List.filter((item, index) => index > 0)
  359. : [];
  360. if (this.chartInfo.Calendar === '农历')
  361. for (let j of filterArr) {
  362. //预测指标配置
  363. let predict_params = chartData.EdbInfoCategoryType === 1 ? this.getSeasonPredictParams(j.CuttingDataTimestamp) : {};
  364. let serie_item = {
  365. data: [],
  366. type: chartData.ChartStyle,
  367. yAxis: 0,
  368. name: j.Year,
  369. ...predict_params
  370. };
  371. const data_array = _.cloneDeep(j.Items);
  372. data_array &&
  373. data_array.forEach((item) => {
  374. serie_item.data.push([item.DataTimestamp, item.Value]);
  375. });
  376. const index = filterArr.findIndex((item) => item.Year === j.Year);
  377. const s_yItem = {
  378. title: {
  379. text: `${chartData.Unit}`,
  380. textCh:chartData.Unit,
  381. textEn:chartData.Unit?chartData.UnitEn:'',
  382. // text: null,
  383. align: 'high',
  384. rotation: 0,
  385. y: -15,
  386. offset: -(12 * chartData.Unit.length),
  387. },
  388. labels: {
  389. formatter: function (ctx) {
  390. let val = ctx.value;
  391. return index !== 0 ? '' : val;
  392. },
  393. align: 'center',
  394. style: {
  395. fontSize: '10px',
  396. },
  397. x: -5,
  398. },
  399. max: Number(chartData.MaxData),
  400. min: Number(chartData.MinData),
  401. ...seasonOptions.yAxis,
  402. };
  403. seasonData.push(serie_item);
  404. seasonYdata.push(s_yItem);
  405. }
  406. // 季节图x轴显示月/日 周度指标额外处理时间轴显示
  407. const xAxis = {
  408. ...defaultOpts.xAxis,
  409. labels: {
  410. formatter: function (ctx) {
  411. return Highcharts.dateFormat('%m/%d', ctx.value);
  412. },
  413. style: {
  414. fontSize: '10px',
  415. },
  416. },
  417. };
  418. // 季节图提示框显示 月/日
  419. defaultOpts.tooltip = {
  420. split: false,
  421. shared: true,
  422. dateTimeLabelFormats: {
  423. // 时间格式化字符
  424. day: '%m/%d',
  425. week: '%m/%d',
  426. month: '%m/%d',
  427. year: '%m/%d',
  428. },
  429. xDateFormat: '%m/%d',
  430. valueDecimals: 2,
  431. };
  432. //农历默认选中一年数据并隐藏按钮 公历显示全部数据
  433. let rangeSelector =
  434. this.chartInfo.Calendar === '农历'
  435. ? {
  436. enabled: true,
  437. selected: 0,
  438. inputStyle: {
  439. display: 'none',
  440. },
  441. labelStyle: {
  442. display: 'none',
  443. },
  444. buttonTheme: {
  445. style: {
  446. display: 'none',
  447. },
  448. },
  449. buttons: [
  450. {
  451. type: 'month',
  452. count: 12,
  453. text: '12月',
  454. },
  455. {
  456. type: 'month',
  457. count: 15,
  458. text: '15月',
  459. },
  460. {
  461. type: 'all',
  462. text: '全部',
  463. },
  464. ],
  465. }
  466. : {
  467. enabled: false,
  468. };
  469. this.options = {
  470. colors:
  471. this.chartInfo.Calendar === '公历'
  472. ? seasonOptions.colors.slice(-chartData.DataList.length)
  473. : seasonOptions.colors.slice(-filterArr.length),
  474. series: seasonData,
  475. yAxis: seasonYdata,
  476. xAxis,
  477. rangeSelector
  478. };
  479. },
  480. /* 散点图设置 只允许2指标画图第一个指标值为x轴 第二个指标为y轴 */
  481. setScatterChart() {
  482. const chartData = _.cloneDeep(this.dataList);
  483. // 取2个指标中日期相同的数据
  484. let real_data = [];
  485. let tmpData_date = {};//用来取点对应的日期
  486. let data1 = _.cloneDeep(chartData)[0].DataList || [];
  487. let data2 = _.cloneDeep(chartData)[1].DataList || [];
  488. data1.forEach(_item => {
  489. data2.forEach(_item2 => {
  490. if(_item.DataTimestamp === _item2.DataTimestamp) {
  491. _item.DataTime = _item.DataTime.replace(/-/g,'/');
  492. //日期
  493. let itemIndex =_item.Value + "_" +_item2.Value
  494. if(tmpData_date[itemIndex]) {
  495. tmpData_date[itemIndex].push(_item.DataTime)
  496. } else {
  497. tmpData_date[itemIndex] = [_item.DataTime]
  498. }
  499. //值
  500. real_data.push({
  501. x: _item.Value,
  502. y: _item2.Value
  503. })
  504. }
  505. })
  506. })
  507. real_data.sort((x,y) => x-y);
  508. //悬浮窗 拼接日期 原始指标名称
  509. let tooltip = {
  510. formatter: function() {
  511. return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
  512. ${chartData[0].EdbName}: <span style="font-weight: 600"> ${this.x}</span><br>
  513. ${chartData[1].EdbName}: <span style="font-weight: 600"> ${this.y}</span>
  514. `
  515. },
  516. // 中文
  517. formatterCh: function() {
  518. return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
  519. ${chartData[0].EdbName}: <span style="font-weight: 600"> ${this.x}</span><br>
  520. ${chartData[1].EdbName}: <span style="font-weight: 600"> ${this.y}</span>
  521. `
  522. },
  523. // 英文
  524. formatterEn: function() {
  525. let str1 = `${chartData[0].EdbNameEn}`
  526. let str2 = `${chartData[1].EdbNameEn}`
  527. return `<strong>${ tmpData_date[this.x+'_'+this.y].length > 4 ? tmpData_date[this.x+'_'+this.y].slice(0,4).join()+'...' : tmpData_date[this.x+'_'+this.y].join() }</strong><br>
  528. ${str1}: <span style="font-weight: 600"> ${this.x}</span><br>
  529. ${str2}: <span style="font-weight: 600"> ${this.y}</span>
  530. `
  531. }
  532. }
  533. const { IsOrder,ChartColor,MaxData,MinData } = chartData[0];
  534. //y轴
  535. let yAxis = {
  536. title: {
  537. text: `${chartData[1].Unit}`,
  538. textCh:chartData[1].Unit,
  539. textEn:chartData[1].Unit?chartData[1].UnitEn:'',
  540. // text: null,
  541. align: 'high',
  542. rotation: 0,
  543. y: -15,
  544. offset: -(12 * chartData[1].Unit.length),
  545. },
  546. labels: {
  547. formatter: function (ctx) {
  548. return ctx.value;
  549. },
  550. align: 'center',
  551. },
  552. opposite: false,
  553. reversed: IsOrder,
  554. min: Number(MinData),
  555. max: Number(MaxData),
  556. tickWidth: 1,
  557. tickLength: 5,
  558. lineWidth: 1,
  559. lineColor: '#bfbfbf',
  560. tickColor: '#bfbfbf',
  561. offset: 0,
  562. visible: true,
  563. gridLineWidth: 0,
  564. tickPosition: 'inside',
  565. endOnTick: false,
  566. startOnTick: false,
  567. showLastLabel: true,
  568. tickPixelInterval: 50
  569. }
  570. //数据列
  571. let series = {
  572. data: [],
  573. type: 'scatter',
  574. name: `${this.chartInfo.ChartName}${IsOrder ? '(逆序)' : ''}`,
  575. nameCh:`${this.chartInfo.ChartName}${IsOrder ? '(逆序)' : ''}`,
  576. nameEn:this.chartInfo.ChartNameEn?`${this.chartInfo.ChartNameEn}${IsOrder ? '(reverse)' : ''}`:'',
  577. color: ChartColor,
  578. lineWidth: 0
  579. }
  580. real_data.forEach(_ => {
  581. series.data.push([_.x,_.y])
  582. })
  583. this.options = {
  584. title: {
  585. text:''
  586. },
  587. series: [ series ],
  588. yAxis,
  589. xAxis: {
  590. ...scatterXAxis,
  591. title: {
  592. text: `${chartData[0].Unit}`,
  593. textCh:chartData[0].Unit,
  594. textEn:chartData[0].Unit?chartData[0].UnitEn:'',
  595. // text: null,
  596. align: 'high',
  597. rotation: 0,
  598. x: 0,
  599. offset: 15,
  600. },
  601. },
  602. tooltip
  603. }
  604. },
  605. /* 奇怪柱状图 和以上逻辑无公用点 依赖数据为单独的数据
  606. x轴为指标名称的柱形图 以日期作为series
  607. */
  608. setBarChart() {
  609. let seriesData = [];
  610. const data = _.cloneDeep(this.barDateList);
  611. //x轴
  612. let xAxis = {
  613. ...scatterXAxis,
  614. categories: this.barXIdData.map(_ => this.barEdbData.find(edb => edb.EdbInfoId===_).EdbAliasName),
  615. tickWidth: 1,
  616. title: {
  617. text: ``,
  618. align: 'high',
  619. rotation: 0,
  620. x: 0,
  621. offset: 20,
  622. },
  623. }
  624. const { max,min } = this.chartLimit;
  625. //y轴
  626. let yAxis = {
  627. ...basicYAxis,
  628. title: {
  629. text: this.chartInfo.Unit,
  630. textCh: this.chartInfo.Unit,
  631. textEn: this.chartInfo.UnitEn,
  632. align: 'high',
  633. rotation: 0,
  634. y: -15,
  635. offset: 0,
  636. },
  637. labels: {
  638. formatter: function (ctx) {
  639. let val = ctx.value;
  640. return val;
  641. },
  642. align: 'center',
  643. },
  644. min: Number(min),
  645. max: Number(max),
  646. opposite: false,
  647. tickWidth: 1,
  648. }
  649. //数据列
  650. data.forEach(item => {
  651. let serie_item = {
  652. data: item.Value,
  653. type: 'column',
  654. yAxis: 0,
  655. name: item.Name || item.Date,
  656. nameCh: item.Name || item.Date,
  657. nameEn: item.Date,
  658. color: item.Color,
  659. chartType: 'linear'
  660. };
  661. seriesData.push(serie_item)
  662. })
  663. this.options = {
  664. title: {
  665. text:'',
  666. },
  667. plotOptions: {
  668. column:{
  669. stacking: null,
  670. },
  671. },
  672. series: seriesData,
  673. yAxis: [ yAxis ],
  674. xAxis
  675. }
  676. },
  677. /* 获取图表详情后赋值柱状图数据 */
  678. initBarData(data) {
  679. const { XEdbIdValue,YDataList,EdbInfoList,ChartInfo } = data;
  680. // let xData = XEdbIdValue.map(_ => EdbInfoList.find(edb => edb.EdbInfoId===_).EdbAliasName)
  681. this.barDateList = YDataList;
  682. this.barXIdData = XEdbIdValue;
  683. this.barEdbData = EdbInfoList;
  684. this.chartLimit = {
  685. min: Number(ChartInfo.LeftMin),
  686. max: Number(ChartInfo.LeftMax)
  687. }
  688. this.setBarChart();
  689. },
  690. /* 商品价格曲线设置 绘图逻辑同奇怪柱形图*/
  691. setCommodityChart() {
  692. let seriesData = [];
  693. const data = _.cloneDeep(this.commodityChartData);
  694. //x轴
  695. let xAxis = {
  696. ...scatterXAxis,
  697. categories: this.commodityXData.map(_ =>_.Name),
  698. tickWidth: 1,
  699. title: {
  700. text: ``,
  701. align: 'high',
  702. rotation: 0,
  703. x: 0,
  704. offset: 20,
  705. },
  706. }
  707. const { max,min } = this.chartLimit;
  708. //y轴
  709. let yAxis = {
  710. ...basicYAxis,
  711. title: {
  712. text: this.commodityEdbList[0].Unit,
  713. textCh: this.commodityEdbList[0].Unit,
  714. textEn: this.commodityEdbList[0].Unit?(this.commodityEdbList[0].UnitEn||'英文单位'):'',
  715. align: 'high',
  716. rotation: 0,
  717. y: -15,
  718. offset: 0,
  719. },
  720. labels: {
  721. formatter: function (ctx) {
  722. let val = ctx.value;
  723. return val;
  724. },
  725. align: 'center',
  726. },
  727. min: Number(min),
  728. max: Number(max),
  729. opposite: false,
  730. tickWidth: 1,
  731. }
  732. //数据列
  733. data.forEach(item => {
  734. //处理首或/尾全是无效数据的以null填充
  735. let filterData = this.filterInvalidData(item)
  736. let serie_item = {
  737. data: filterData,
  738. type: 'spline',
  739. yAxis: 0,
  740. name: item.Name,
  741. nameCh: item.Name,
  742. nameEn: item.NameEn,
  743. color: item.Color,
  744. chartType: 'linear',
  745. lineWidth: 3,
  746. marker: {
  747. enabled: false
  748. }
  749. };
  750. seriesData.push(serie_item)
  751. })
  752. //tooltip
  753. let commodityEdbList = this.commodityEdbList;
  754. let commodityXData = this.commodityXData;
  755. let chartInfo = this.chartInfo;
  756. let tooltip = {
  757. formatter: function() {
  758. let str = '';
  759. this.points.forEach(item => {
  760. let obj_item = data.find(_ => _.Name === item.series.name);
  761. let index = commodityXData.findIndex(_ => _.Name === this.x);
  762. //合约显示
  763. let haveContract = obj_item.XEdbInfoIdList[index];
  764. if(haveContract) {
  765. // 利润曲线指标名
  766. let edb_name = chartInfo.Source === 5
  767. ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
  768. : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
  769. str+=`<b>${ edb_name }</b>`
  770. if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
  771. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
  772. }else {
  773. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
  774. }
  775. }
  776. })
  777. return str||'无合约'
  778. },
  779. formatterCh: function() {
  780. let str = '';
  781. this.points.forEach(item => {
  782. let obj_item = data.find(_ => _.Name === item.series.name);
  783. let index = commodityXData.findIndex(_ => _.Name === this.x);
  784. //合约显示
  785. let haveContract = obj_item.XEdbInfoIdList[index];
  786. if(haveContract) {
  787. // 利润曲线指标名
  788. let edb_name = chartInfo.Source === 5
  789. ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitName}(${obj_item.NameList[index]})`)
  790. : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbName;
  791. str+=`<b>${ edb_name }</b>`
  792. if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
  793. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
  794. }else {
  795. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
  796. }
  797. }
  798. })
  799. return str||'无合约'
  800. },
  801. formatterEn: function() {
  802. let str = '';
  803. this.points.forEach(item => {
  804. let obj_item = data.find(_ => _.NameEn === item.series.name);
  805. let index = commodityXData.findIndex(_ => _.NameEn === this.x);
  806. //合约显示
  807. let haveContract = obj_item.XEdbInfoIdList[index];
  808. if(haveContract) {
  809. // 利润曲线指标名
  810. let edb_name = chartInfo.Source === 5
  811. ? (index === 0 ? obj_item.NameList[index] : `${chartInfo.ProfitNameEn}(${obj_item.NameList[index]})`)
  812. : commodityEdbList.find(_ => _.EdbInfoId === obj_item.XEdbInfoIdList[index]).EdbNameEn;
  813. str+=`<b>${ edb_name }</b>`
  814. if(!obj_item.NoDataEdbList.includes(obj_item.XEdbInfoIdList[index])) {
  815. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: ${item.y}<br>`
  816. }else {
  817. str += `<br><span style="color:${item.color}">\u25CF</span>${obj_item.Date}: 无<br>`
  818. }
  819. }
  820. })
  821. return str||'无合约'
  822. },
  823. shared: true
  824. }
  825. this.options = {
  826. title: {
  827. text:''
  828. },
  829. series: seriesData,
  830. yAxis: [ yAxis ],
  831. xAxis,
  832. tooltip
  833. }
  834. },
  835. /* 处理无效数据为null */
  836. filterInvalidData(item) {
  837. //找出第一个有效数据和最后一个有效数据的index index1 index2
  838. //0到index1全填null index2到最后一个全为null
  839. let validateArr = item.XEdbInfoIdList.filter(_ =>_&&!item.NoDataEdbList.includes(_));
  840. let first_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[0]);
  841. let last_index = item.XEdbInfoIdList.findIndex(_ => _ === validateArr[validateArr.length-1]);
  842. console.log('first_index',first_index)
  843. console.log('last_index',last_index)
  844. let arr = item.Value.map((item,index) => {
  845. if(index < first_index || index > last_index) {
  846. return null
  847. }else {
  848. return item
  849. }
  850. })
  851. return arr;
  852. },
  853. /* 商品价格曲线获取详情赋值 */
  854. initCommodityData(data) {
  855. const { XDataList,YDataList,EdbInfoList,ChartInfo,DataResp } = data;
  856. this.commodityEdbList = EdbInfoList;
  857. this.commodityChartData = ChartInfo.Source===5?DataResp.YDataList:YDataList;
  858. this.commodityXData = ChartInfo.Source===5?DataResp.XDataList:XDataList;
  859. this.chartLimit = {
  860. min: Number(ChartInfo.LeftMin),
  861. max: Number(ChartInfo.LeftMax)
  862. }
  863. this.setCommodityChart()
  864. },
  865. /* 相关性图表初始化 */
  866. initRelevanceChartData(){
  867. // 处理X轴
  868. let xAxis={
  869. categories: this.relevanceChartData.XEdbIdValue,
  870. tickWidth: 1,
  871. title: {
  872. text: this.relevanceChartData.ChartInfo.Source===3 ?`期数(${this.relevanceChartData.CorrelationChartInfo.LeadUnit})` : null,
  873. textCh:this.relevanceChartData.ChartInfo.Source===3 ? `期数(${this.relevanceChartData.CorrelationChartInfo.LeadUnit})`:null,
  874. textEn:this.relevanceChartData.ChartInfo.Source===3 ? `stage(${this.relevanceUnitEnMap[this.relevanceChartData.CorrelationChartInfo.LeadUnit]})`:null,
  875. align: 'high',
  876. rotation: 0,
  877. x: 0,
  878. y:10,
  879. offset: 20,
  880. },
  881. tickInterval: 1,
  882. offset:0,
  883. tickmarkPlacement:'on'
  884. }
  885. // 处理Y轴
  886. let yAxis={
  887. ...basicYAxis,
  888. title: {
  889. text: '相关性系数',
  890. textCh: '相关性系数',
  891. textEn: 'Correlation coefficient',
  892. align: 'high',
  893. rotation: 0,
  894. y: -15,
  895. offset: 0,
  896. },
  897. labels: {
  898. formatter: function (ctx) {
  899. let val = ctx.value;
  900. return val;
  901. },
  902. align: 'center',
  903. },
  904. // min: -1,
  905. // max: 1,
  906. opposite: false,
  907. tickWidth: 1,
  908. // tickInterval:0.2,
  909. }
  910. //处理series
  911. let seriesData=[]
  912. this.relevanceChartData.YDataList.forEach(item=>{
  913. let serie_item = {
  914. data: item.Value,
  915. type: 'spline',
  916. yAxis: 0,
  917. name: item.Name,
  918. nameCh: item.Name,
  919. nameEn: item.NameEn,
  920. color: item.Color,
  921. chartType: 'linear',
  922. lineWidth: 3,
  923. marker: {
  924. enabled: false
  925. }
  926. };
  927. seriesData.push(serie_item)
  928. })
  929. const { LeadValue,LeadUnit } = this.relevanceChartData.CorrelationChartInfo;
  930. const { Source } = this.relevanceChartData.ChartInfo;
  931. let relevanceUnitEnMap = this.relevanceUnitEnMap;
  932. let tooltip = {
  933. formatter: function() {
  934. let str = `<p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${ Source===3 ?this.x+'期' : LeadValue+LeadUnit}</p>`
  935. return str
  936. },
  937. formatterCh: function() {
  938. let str = `<p>相关性系数:${this.y.toFixed(4)}</p><br><p>领先${ Source===3 ?this.x+'期' : LeadValue+LeadUnit}</p>`
  939. return str
  940. },
  941. formatterEn: function() {
  942. let str = `<p>Correlation coefficient:${this.y.toFixed(4)}</p><br><p>lead${ Source===3 ? this.x+'stage' : LeadValue+relevanceUnitEnMap[LeadUnit]}</p>`
  943. return str
  944. }
  945. }
  946. this.options = {
  947. isRelevanceChart: Source===3,
  948. title: {
  949. text:''
  950. },
  951. series: seriesData,
  952. yAxis: [yAxis] ,
  953. xAxis:xAxis,
  954. tooltip
  955. }
  956. },
  957. /* 截面散点图获取详情赋值 */
  958. initSectionScatterData({ DataResp }) {
  959. this.chartLimit = {
  960. min: Number(DataResp.YMinValue),
  961. max: Number(DataResp.YMaxValue),
  962. x_min: Number(DataResp.XMinValue),
  963. x_max: Number(DataResp.XMaxValue)
  964. }
  965. this.sectionScatterData = DataResp;
  966. this.setSectionScatterChart();
  967. },
  968. /* 截面散点图设置 sectionScatterData */
  969. setSectionScatterChart() {
  970. const { DataList,XName,XNameEn,XUnitName,XUnitNameEn,YName,YNameEn,YUnitName,YUnitNameEn } = this.sectionScatterData;
  971. const { min,max,x_min,x_max } = this.chartLimit;
  972. //y轴
  973. let yAxis = {
  974. ...basicYAxis,
  975. title: {
  976. text: YName,
  977. textCh:YName,// 中文
  978. textEn:YNameEn,
  979. style:{},
  980. styleEn:{cursor:'pointer'},
  981. align: 'middle',
  982. },
  983. opposite: false,
  984. reversed: false,
  985. min: Number(min),
  986. max: Number(max),
  987. tickWidth: 1,
  988. }
  989. //x轴
  990. let xAxis = {
  991. ...scatterXAxis,
  992. title: {
  993. text: XName,
  994. textCh:XName,// 中文
  995. textEn:XNameEn,
  996. style:{},
  997. styleEn:{cursor:'pointer'},
  998. align: 'middle',
  999. },
  1000. min: Number(x_min),
  1001. max: Number(x_max),
  1002. }
  1003. //数据列
  1004. let series = [];
  1005. DataList.forEach(item => {
  1006. //数据列
  1007. let series_item = {
  1008. data: [],
  1009. type: 'scatter',
  1010. name: item.Name,
  1011. nameCh: item.Name,
  1012. nameEn: item.NameEn,
  1013. color: item.Color,
  1014. lineWidth: 0,
  1015. chartType: 'linear',
  1016. zIndex:1
  1017. }
  1018. item.EdbInfoList.forEach(_ => {
  1019. series_item.data.push({
  1020. x: _.XValue,
  1021. y: _.YValue,
  1022. dataLabels: {
  1023. enabled: _.IsShow,
  1024. allowOverlap: true,
  1025. align: 'left',
  1026. format: _.Name,
  1027. formatCh: _.Name,
  1028. formatEn: _.NameEn
  1029. }
  1030. })
  1031. })
  1032. series.push(series_item);
  1033. //趋势线
  1034. if(item.ShowTrendLine) {
  1035. let trend_data = item.TrendLimitData.map((_,_index) => (
  1036. _index === item.TrendLimitData.length-1 ? {
  1037. x: _.X,
  1038. y: _.Y,
  1039. dataLabels: {
  1040. enabled: item.ShowRSquare || item.ShowFitEquation,
  1041. align: 'left',
  1042. color: '#666',
  1043. x: 20,
  1044. y: 30,
  1045. zIndex: 9,
  1046. allowOverlap: true,
  1047. formatter: function(){
  1048. let tag = '';
  1049. item.ShowRSquare && item.ShowFitEquation
  1050. ? tag =`<span>${item.TrendLine}</span><br><span>R²=${item.RSquare}</span>`
  1051. : item.ShowRSquare && !item.ShowFitEquation
  1052. ? tag =`<span>R²=${item.RSquare}</span>`
  1053. : item.ShowFitEquation && !item.ShowRSquare
  1054. ? tag =`<span>${item.TrendLine}</span>`
  1055. : ''
  1056. return tag
  1057. }
  1058. }
  1059. } : {
  1060. x: _.X,
  1061. y: _.Y,
  1062. }
  1063. ))
  1064. let trend_item = {
  1065. data: trend_data,
  1066. type: 'spline',
  1067. linkedTo: ':previous',
  1068. color: item.Color,
  1069. lineWidth: 1,
  1070. chartType: 'linear',
  1071. enableMouseTracking: false,
  1072. dashStyle:'Dash',
  1073. zIndex: 2,
  1074. marker: {
  1075. enabled: false
  1076. }
  1077. }
  1078. series.push(trend_item)
  1079. }
  1080. })
  1081. let tooltip = {
  1082. formatter: function() {
  1083. let series_obj = DataList.find(_ => _.Name === this.series.name);
  1084. let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
  1085. let str=`<b>${ ponit_obj.Name }</b>`;
  1086. str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XName}: ${this.x} ${ponit_obj.XDate}<br>`;
  1087. str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YName}: ${this.y} ${ponit_obj.YDate}`;
  1088. return str
  1089. },
  1090. formatterCh: function() {
  1091. let series_obj = DataList.find(_ => _.Name === this.series.name);
  1092. let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
  1093. let str=`<b>${ ponit_obj.Name }</b>`;
  1094. str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XName}: ${this.x} ${ponit_obj.XDate}<br>`;
  1095. str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YName}: ${this.y} ${ponit_obj.YDate}`;
  1096. return str
  1097. },
  1098. formatterEn: function() {
  1099. let series_obj = DataList.find(_ => _.NameEn === this.series.name);
  1100. let ponit_obj = series_obj.EdbInfoList.find(_ => _.XValue ===this.x && _.YValue===this.y);
  1101. let str=`<b>${ ponit_obj.NameEn }</b>`;
  1102. str += `<br><span style="color:${this.color}">\u25CF</span>${ponit_obj.XNameEn}: ${this.x} ${ponit_obj.XDate}<br>`;
  1103. str += `<span style="color:${this.color}">\u25CF</span>${ponit_obj.YNameEn}: ${this.y} ${ponit_obj.YDate}`;
  1104. return str
  1105. }
  1106. }
  1107. this.options = {
  1108. title: {
  1109. text:''
  1110. },
  1111. series,
  1112. yAxis: [yAxis],
  1113. xAxis,
  1114. tooltip
  1115. }
  1116. },
  1117. /* 统计频率图 */
  1118. setStatisticFrequency() {
  1119. const { DataList,LeftMaxValue,LeftMinValue,RightMaxValue,RightMinValue } = this.statisticFrequencyData;
  1120. let xAxis = {
  1121. ...scatterXAxis,
  1122. tickWidth: 1,
  1123. title: {
  1124. text: ``,
  1125. align: 'high',
  1126. rotation: 0,
  1127. x: 0,
  1128. offset: 20,
  1129. }
  1130. }
  1131. //y和系列
  1132. let yAxis = [],series = [];
  1133. DataList.forEach((item,index) => {
  1134. let y_item = {
  1135. ...basicYAxis,
  1136. title: {
  1137. text: item.Unit,
  1138. textCh:item.Unit,// 中文
  1139. textEn:item.UnitEn||item.Unit,
  1140. align: 'high',
  1141. rotation: 0,
  1142. y: -15,
  1143. offset: 0,
  1144. },
  1145. opposite: item.IsAxis===1?false:true,
  1146. min: index===0? Number(LeftMinValue):Number(RightMinValue),
  1147. max: index===0? Number(LeftMaxValue):Number(RightMaxValue),
  1148. tickWidth: 1,
  1149. }
  1150. let series_item = {
  1151. data: item.Value.map(_ =>[_.X,_.Y]),
  1152. type: 'spline',
  1153. yAxis: index,
  1154. name: item.Name,
  1155. nameCh: item.Name,
  1156. nameEn: item.NameEn||item.Name,
  1157. color: item.Color,
  1158. lineWidth: 3,
  1159. chartType: 'linear',
  1160. zIndex:1
  1161. }
  1162. series.push(series_item);
  1163. yAxis.push(y_item)
  1164. })
  1165. let tooltip = {
  1166. formatter: function() {
  1167. let xList = DataList[0].Value.map(_ =>_.X);
  1168. let step = xList[1]-xList[0];
  1169. let data_interval = `[${this.x},${this.x+step}]`;
  1170. let str=`<b>${ data_interval }</b>`;
  1171. this.points.forEach(item => {
  1172. str += `<br><span style="color:${item.color}">\u25CF</span>${item.series.name}: ${item.y}%<br>`
  1173. })
  1174. return str
  1175. },
  1176. shared: true
  1177. }
  1178. this.options = {
  1179. title: {
  1180. text:''
  1181. },
  1182. tooltip,
  1183. series,
  1184. yAxis,
  1185. xAxis
  1186. }
  1187. },
  1188. /* 查询范围为1年内 x轴显示为月/日 否则默认年/月 */
  1189. xTimeDiffer() {
  1190. const end_date =
  1191. this.chartInfo.DateType === 5
  1192. ? this.chartInfo.EndDate
  1193. : this.chartInfo.DateType === 6
  1194. ? new Date()
  1195. : '';
  1196. //年限差
  1197. const year_differ = this.$moment(end_date).diff(
  1198. this.$moment(this.chartInfo.StartDate),
  1199. 'years',
  1200. true
  1201. );
  1202. // console.log(year_differ)
  1203. if ([5, 6].includes(this.chartInfo.DateType) && year_differ <= 1) {
  1204. // return true;
  1205. defaultOpts.xAxis.labels = {
  1206. formatter: function () {
  1207. return Highcharts.dateFormat('%m/%d', this.value);
  1208. },
  1209. style: {
  1210. fontSize: '10px',
  1211. },
  1212. };
  1213. } else {
  1214. // return false;
  1215. defaultOpts.xAxis.labels = {
  1216. style: {
  1217. fontSize: '10px',
  1218. },
  1219. };
  1220. }
  1221. },
  1222. /* 拼接动态的指标名称小标签 */
  1223. concatDynamicTag({ IsAxis,IsOrder,EdbInfoType,LeadValue,LeadUnit },lang='ch') {
  1224. // IsAxis左轴1 右轴0 2右2轴
  1225. //IsOrder正序false 逆序true
  1226. //EdbInfoType是否是领先指标
  1227. // lang ch 中文 en 英文
  1228. const axisLabelMap = lang=='ch'?{
  1229. 0: '右轴',
  1230. 2: '右2轴'
  1231. }:{
  1232. 0: 'RHS',
  1233. 2: '2-RHS'
  1234. }
  1235. const orderLabelMap = lang=='ch'?{
  1236. 1: '逆序'
  1237. }:{
  1238. 1: 'REV'
  1239. }
  1240. const edbInfoMap = lang=='ch'?{
  1241. 0: '领先'
  1242. }:{
  1243. 0: 'Lead'
  1244. }
  1245. //英文领先单位转换
  1246. const leadUnit = lang==='ch' ? LeadUnit : this.leadUnitEnMap[LeadUnit];
  1247. let axis_tag = axisLabelMap[IsAxis] || '';
  1248. //逆序拼接
  1249. let order_tag = orderLabelMap[Number(IsOrder)] ? `${axis_tag ? ',': ''}${orderLabelMap[Number(IsOrder)]}` : ''
  1250. //领先拼接
  1251. let edb_tag = edbInfoMap[EdbInfoType] ? `${(axis_tag||order_tag) ? ',' : '' }${edbInfoMap[EdbInfoType]} ${LeadValue}${leadUnit}` : '';
  1252. return (axis_tag || order_tag || edb_tag) ? `(${axis_tag}${order_tag}${edb_tag})` : ''
  1253. },
  1254. /* 指标顺序调整 IsAxis: 0右轴 1左轴 2右2*/
  1255. changeEdbOrder(data) {
  1256. // 左轴指标
  1257. let left_edbs = data.filter(_ => _.IsAxis===1);
  1258. //右轴指标
  1259. let right_edbs = data.filter(_ => !_.IsAxis);
  1260. // 右2轴指标
  1261. let right_two_edbs = data.filter(_ => _.IsAxis === 2);
  1262. // 按 左 右 右2顺序排列
  1263. return [left_edbs,right_edbs,right_two_edbs].flat(Infinity);
  1264. },
  1265. /* 获取轴数值的最大长度 通过真实数据推测而已 也不准确 */
  1266. getLabelMaxLen(data) {
  1267. let value_arr = data.map(_ => String(Math.abs(_.Value)));
  1268. let max_len_value = value_arr.reduce((a,b)=> (a.length > b.length ? a : b))
  1269. let num = Number(max_len_value) > 1 ? String(parseInt(Number(max_len_value))) : max_len_value
  1270. return num.length
  1271. },
  1272. /* 预测配置 分区 */
  1273. getPredictParams({LatestDate,MoveLatestDate,PredictChartColor,ChartStyle},chartStyle='') {
  1274. return {
  1275. zoneAxis: 'x',
  1276. zones: [{
  1277. value: new Date(MoveLatestDate||LatestDate).getTime()+1
  1278. }, {
  1279. dashStyle: 'ShortDot',
  1280. color:(ChartStyle==='column' || chartStyle==='column') ? 'transparent' : PredictChartColor
  1281. }],
  1282. }
  1283. },
  1284. /* 季节图预测数据 年份=分割点年份做分割 年份>分割点年份全为预测 */
  1285. getSeasonPredictParams(timestamp) {
  1286. return timestamp
  1287. ? {
  1288. zoneAxis: 'x',
  1289. zones: [{
  1290. value: new Date(timestamp).getTime()+1,
  1291. }, {
  1292. dashStyle: 'ShortDot',
  1293. }]
  1294. }
  1295. : {}
  1296. }
  1297. },
  1298. };