|
@@ -42,6 +42,7 @@ import Highcharts from 'highcharts';
|
|
|
import { defaultOpts, seasonOptions } from '@/utils/chartOptions';
|
|
|
import moment from 'moment';
|
|
|
|
|
|
+// 散点x
|
|
|
const scatterXAxis = {
|
|
|
tickPosition: 'inside',
|
|
|
lineColor: '#bfbfbf',
|
|
@@ -51,6 +52,21 @@ const scatterXAxis = {
|
|
|
type: 'linear',
|
|
|
}
|
|
|
|
|
|
+//基础y轴
|
|
|
+const basicYAxis = {
|
|
|
+ tickLength:5,
|
|
|
+ lineWidth: 1,
|
|
|
+ lineColor: '#bfbfbf',
|
|
|
+ tickColor: '#bfbfbf',
|
|
|
+ offset: 0,
|
|
|
+ visible: true,
|
|
|
+ gridLineWidth: 0,
|
|
|
+ tickPosition: 'inside',
|
|
|
+ endOnTick: false,
|
|
|
+ startOnTick: false,
|
|
|
+ showLastLabel: true
|
|
|
+}
|
|
|
+
|
|
|
export default defineComponent({
|
|
|
components: {
|
|
|
chart,
|
|
@@ -145,19 +161,141 @@ export default defineComponent({
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /* 曲线图 面积 组合 柱状图.. */
|
|
|
+ /* 曲线图 */
|
|
|
const setDefaultLineOptions = () => {
|
|
|
const { dataList,chartInfo } = state;
|
|
|
|
|
|
+ //拼接标题 数据列
|
|
|
+ let data = [] as any[],ydata = [] as any[],minTimeArr: number[] = [],maxTimeArr: number[] = [];
|
|
|
+ const chartData = _.cloneDeep(dataList);
|
|
|
+
|
|
|
+ chartData.forEach((item:IDataProps ,index:number) => {
|
|
|
+
|
|
|
+ //轴位置值相同的下标
|
|
|
+ let sameSideIndex = chartData.findIndex(
|
|
|
+ (i:IDataProps) => i.IsAxis === item.IsAxis
|
|
|
+ );
|
|
|
+ //y轴
|
|
|
+ let yItem = {
|
|
|
+ ...basicYAxis,
|
|
|
+ labels: {
|
|
|
+ formatter: function (ctx: any) {
|
|
|
+ let val = ctx.value < 1000 ? ctx.value : ctx.value / 1000 + 'k';
|
|
|
+ return sameSideIndex !== index ? '' : val;
|
|
|
+ },
|
|
|
+ align: 'center',
|
|
|
+ x: item.IsAxis === 0 ? 5 : -5,
|
|
|
+ style: {
|
|
|
+ fontSize: '10px',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ title: {
|
|
|
+ // text: sameSideIndex !== index ? '' : `单位:${item.Unit}`,
|
|
|
+ text: null,
|
|
|
+ align: 'high',
|
|
|
+ rotation: 0,
|
|
|
+ y: -15,
|
|
|
+ offset: 0,
|
|
|
+ },
|
|
|
+ opposite: item.IsAxis === 0,
|
|
|
+ reversed: item.IsOrder,
|
|
|
+ min: Number(chartData[sameSideIndex].MinData),
|
|
|
+ max: Number(chartData[sameSideIndex].MaxData),
|
|
|
+ tickWidth: sameSideIndex !== index ? 0 : 1,
|
|
|
+ }
|
|
|
+
|
|
|
+ // //拼接标题 判断相同指标名称拼接来源
|
|
|
+ let dynamic_title = item.EdbName;
|
|
|
+ let dynamic_arr = chartData.filter(
|
|
|
+ (item: IDataProps) => dynamic_title === item.EdbName
|
|
|
+ );
|
|
|
+
|
|
|
+ // 拼接配置 IsAxis左轴1 右轴0 IsOrder正序false 逆序true EdbInfoType是否是领先指标
|
|
|
+ let dynamic_tag = concatDynamicTag(item)
|
|
|
+
|
|
|
+ //数据列
|
|
|
+ let obj = {
|
|
|
+ data: [] as any[],
|
|
|
+ type: 'spline',
|
|
|
+ yAxis: index,
|
|
|
+ name:
|
|
|
+ dynamic_arr.length > 1
|
|
|
+ ? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
|
|
|
+ : `${item.EdbName}${dynamic_tag}`,
|
|
|
+ color: item.ChartColor,
|
|
|
+ lineWidth: Number(item.ChartWidth)
|
|
|
+ };
|
|
|
+ item.DataList = item.DataList || []
|
|
|
+ for (let i of item.DataList) {
|
|
|
+ obj.data.push([i.DataTimestamp, i.Value]);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(item.DataList.length){
|
|
|
+ minTimeArr.push(item.DataList[0].DataTimestamp)
|
|
|
+ maxTimeArr.push(item.DataList[item.DataList.length-1].DataTimestamp)
|
|
|
+ }
|
|
|
+
|
|
|
+ data.push(obj);
|
|
|
+ ydata.push(yItem);
|
|
|
+ })
|
|
|
+
|
|
|
+ // 范围为1年内 x轴显示为月/日 否则默认年/月
|
|
|
+ let xAxis:any = {};
|
|
|
+ const bool_time:boolean = xTimeDiffer();
|
|
|
+ let minTime: number=Math.min(...minTimeArr);
|
|
|
+ let maxTime=Math.max(...maxTimeArr);
|
|
|
+
|
|
|
+ let step = setXaxisStep(maxTime-minTime);
|
|
|
+
|
|
|
+ xAxis = bool_time ? {
|
|
|
+ ...defaultOpts.xAxis,
|
|
|
+ tickInterval: screen.value === 'phone' ? step : undefined,
|
|
|
+ labels: {
|
|
|
+ formatter: function (ctx: any) {
|
|
|
+ return Highcharts.dateFormat('%m/%d', ctx.value);
|
|
|
+ },
|
|
|
+ style: {
|
|
|
+ fontSize: '10px',
|
|
|
+ },
|
|
|
+ }
|
|
|
+ } : {
|
|
|
+ ...defaultOpts.xAxis,
|
|
|
+ tickInterval: screen.value === 'phone' ? step : undefined,
|
|
|
+ labels: {
|
|
|
+ style: {
|
|
|
+ fontSize: '10px',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+
|
|
|
+ state.options = {
|
|
|
+ series: data,
|
|
|
+ yAxis: ydata,
|
|
|
+ xAxis
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 设置x轴步长 刻度数量多一点 */
|
|
|
+ const setXaxisStep = (timestamp: number) => {
|
|
|
+ // return timestamp / 6 < 24 * 3600 * 1000 * 30 ? 24 * 3600 * 1000 * 30 : timestamp / 6;
|
|
|
+ return timestamp / 6;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* 堆叠图/组合图设置
|
|
|
+ 本来和曲线图逻辑基本一致兼容下即可 为了以后便于维护和阅读还是拆开写吧
|
|
|
+ */
|
|
|
+ const setStackOrCombinChart = () => {
|
|
|
+ const { dataList,chartInfo } = state;
|
|
|
+
|
|
|
//拼接标题 数据列
|
|
|
let data = [] as any[],ydata = [] as any[],minTimeArr: number[] = [],maxTimeArr: number[] = [];
|
|
|
const chartData = _.cloneDeep(dataList);
|
|
|
|
|
|
//支持的图表类型
|
|
|
const chartTypeMap: IChartType = {
|
|
|
- 1: 'spline',
|
|
|
3: 'areaspline',
|
|
|
4: 'column',
|
|
|
+ 6: ''
|
|
|
};
|
|
|
let chartStyle = chartTypeMap[chartInfo.ChartType];
|
|
|
|
|
@@ -167,8 +305,23 @@ export default defineComponent({
|
|
|
let sameSideIndex = chartData.findIndex(
|
|
|
(i:IDataProps) => i.IsAxis === item.IsAxis
|
|
|
);
|
|
|
+
|
|
|
+ //堆叠图的yAxis必须一致 数据列所对应的y轴
|
|
|
+ let serie_yIndex = index;
|
|
|
+ if([3,4].includes(chartInfo.ChartType)) {
|
|
|
+ // 类型为堆叠图时公用第一个指标y轴
|
|
|
+ serie_yIndex = 0;
|
|
|
+ } else if(chartInfo.ChartType ===6 && ['areaspline','column'].includes(item.ChartStyle)) {
|
|
|
+ // 组合图找第一个堆叠柱状或面积的作为公用
|
|
|
+ serie_yIndex = chartData.findIndex((i:IDataProps) => i.ChartStyle === item.ChartStyle);
|
|
|
+ }
|
|
|
+ //数据对应的y轴是公用轴则配置也共享
|
|
|
+ item.IsAxis = serie_yIndex === index ? item.IsAxis : chartData[serie_yIndex].IsAxis;
|
|
|
+ item.IsOrder = serie_yIndex === index ? item.IsOrder : chartData[serie_yIndex].IsOrder;
|
|
|
+
|
|
|
//y轴
|
|
|
let yItem = {
|
|
|
+ ...basicYAxis,
|
|
|
labels: {
|
|
|
formatter: function (ctx: any) {
|
|
|
let val = ctx.value < 1000 ? ctx.value : ctx.value / 1000 + 'k';
|
|
@@ -193,17 +346,7 @@ export default defineComponent({
|
|
|
min: Number(chartData[sameSideIndex].MinData),
|
|
|
max: Number(chartData[sameSideIndex].MaxData),
|
|
|
tickWidth: sameSideIndex !== index ? 0 : 1,
|
|
|
- tickLength:5,
|
|
|
- lineWidth: 1,
|
|
|
- lineColor: '#bfbfbf',
|
|
|
- tickColor: '#bfbfbf',
|
|
|
- offset: 0,
|
|
|
- visible: true,
|
|
|
- gridLineWidth: 0,
|
|
|
- tickPosition: 'inside',
|
|
|
- endOnTick: false,
|
|
|
- startOnTick: false,
|
|
|
- showLastLabel: true
|
|
|
+ visible: serie_yIndex === index ? true : false
|
|
|
}
|
|
|
|
|
|
// //拼接标题 判断相同指标名称拼接来源
|
|
@@ -213,34 +356,21 @@ export default defineComponent({
|
|
|
);
|
|
|
|
|
|
// 拼接配置 IsAxis左轴1 右轴0 IsOrder正序false 逆序true EdbInfoType是否是领先指标
|
|
|
- let dynamic_tag: string = item.IsAxis && item.IsOrder && item.EdbInfoType
|
|
|
- ? '(逆序)'
|
|
|
- : !item.IsAxis && item.IsOrder && item.EdbInfoType
|
|
|
- ? '(右轴,逆序)'
|
|
|
- : !item.IsAxis && !item.IsOrder && item.EdbInfoType
|
|
|
- ? '(右轴)'
|
|
|
- : !item.IsAxis && !item.IsOrder && !item.EdbInfoType
|
|
|
- ? `(右轴,领先${item.LeadValue}${item.LeadUnit})`
|
|
|
- : !item.IsAxis && item.IsOrder && !item.EdbInfoType
|
|
|
- ? `(右轴,逆序,领先${item.LeadValue}${item.LeadUnit})`
|
|
|
- : item.IsAxis && item.IsOrder && !item.EdbInfoType
|
|
|
- ? `(逆序,领先${item.LeadValue}${item.LeadUnit})`
|
|
|
- : item.IsAxis && !item.IsOrder && !item.EdbInfoType
|
|
|
- ? `(领先${item.LeadValue}${item.LeadUnit})`
|
|
|
- : '';
|
|
|
+ let dynamic_tag = concatDynamicTag(item)
|
|
|
|
|
|
//数据列
|
|
|
let obj = {
|
|
|
data: [] as any[],
|
|
|
- type: chartInfo.ChartType === 6 ? item.ChartStyle : chartStyle,
|
|
|
- yAxis: index,
|
|
|
+ type: chartStyle || item.ChartStyle,
|
|
|
+ yAxis: serie_yIndex,
|
|
|
name:
|
|
|
dynamic_arr.length > 1
|
|
|
? `${item.EdbName}(${item.SourceName})${dynamic_tag}`
|
|
|
: `${item.EdbName}${dynamic_tag}`,
|
|
|
color: item.ChartColor,
|
|
|
- lineWidth: (chartInfo.ChartType === 1 || (chartInfo.ChartType === 6 && item.ChartStyle === 'spline')) ? Number(item.ChartWidth) : 0,
|
|
|
- fillColor: (chartInfo.ChartType === 3 || (chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined
|
|
|
+ lineWidth: (chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? Number(item.ChartWidth) : 0,
|
|
|
+ fillColor: (chartInfo.ChartType === 3 || (chartInfo.ChartType === 6 && item.ChartStyle === 'areaspline')) ? item.ChartColor : undefined,
|
|
|
+ zIndex: (chartInfo.ChartType === 6 && item.ChartStyle === 'spline') ? 1 : 0 //防止组合图曲线被遮住
|
|
|
|
|
|
};
|
|
|
item.DataList = item.DataList || []
|
|
@@ -293,12 +423,6 @@ export default defineComponent({
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- /* 设置x轴步长 刻度数量多一点 */
|
|
|
- const setXaxisStep = (timestamp: number) => {
|
|
|
- // return timestamp / 6 < 24 * 3600 * 1000 * 30 ? 24 * 3600 * 1000 * 30 : timestamp / 6;
|
|
|
- return timestamp / 6;
|
|
|
- }
|
|
|
-
|
|
|
/* 季节图 */
|
|
|
const setSeasonOptions = () => {
|
|
|
const chartData = state.dataList[0];
|
|
@@ -602,15 +726,35 @@ export default defineComponent({
|
|
|
const chartSetMap: any = {
|
|
|
1: setDefaultLineOptions,
|
|
|
2: setSeasonOptions,
|
|
|
- 3: setDefaultLineOptions,
|
|
|
- 4: setDefaultLineOptions,
|
|
|
+ 3: setStackOrCombinChart,
|
|
|
+ 4: setStackOrCombinChart,
|
|
|
5: setScatterChartOptions,
|
|
|
- 6: setDefaultLineOptions
|
|
|
+ 6: setStackOrCombinChart
|
|
|
};
|
|
|
|
|
|
chartSetMap[chartInfo.ChartType]()
|
|
|
};
|
|
|
|
|
|
+ /* 拼接动态的指标名称小标签 */
|
|
|
+ const concatDynamicTag = ({ IsAxis,IsOrder,EdbInfoType,LeadValue,LeadUnit }: IDataProps ): string => {
|
|
|
+ // IsAxis左轴1 右轴0 IsOrder正序false 逆序true EdbInfoType是否是领先指标
|
|
|
+ return IsAxis && IsOrder && EdbInfoType
|
|
|
+ ? '(逆序)'
|
|
|
+ : !IsAxis && IsOrder && EdbInfoType
|
|
|
+ ? '(右轴,逆序)'
|
|
|
+ : !IsAxis && !IsOrder && EdbInfoType
|
|
|
+ ? '(右轴)'
|
|
|
+ : !IsAxis && !IsOrder && !EdbInfoType
|
|
|
+ ? `(右轴,领先${LeadValue}${LeadUnit})`
|
|
|
+ : !IsAxis && IsOrder && !EdbInfoType
|
|
|
+ ? `(右轴,逆序,领先${LeadValue}${LeadUnit})`
|
|
|
+ : IsAxis && IsOrder && !EdbInfoType
|
|
|
+ ? `(逆序,领先${LeadValue}${LeadUnit})`
|
|
|
+ : IsAxis && !IsOrder && !EdbInfoType
|
|
|
+ ? `(领先${LeadValue}${LeadUnit})`
|
|
|
+ : '';
|
|
|
+ }
|
|
|
+
|
|
|
/* 分享链接 */
|
|
|
const copyUrl = () => {
|
|
|
let input = document.createElement("input");
|