function main(page: IPage, portlet: IFilterPortlet) {
init(page, portlet)
}
/**
* 场景:通过点击时间粒度选择器,刷新图形数据
* 实现:
* 1、添加一个echarts的曲线图:"图表",用于展示数据,并通过【组件设置-自定义属性】添加dataZoom控制条(具体请看资源)。
* 2、数据模型添加一个无用的参数,作为筛选器:”选择器“(列表单选:日、月、年),用于选择时间粒度,并通过宏设置样式、监听选择器值变化函数,触发时间范围变化,且不作用于任何组件;
* 3、拖拽一个时间字段作为筛选器:”日期“,用于作为当前日期即时间粒度中的结束日期,并通过宏添加监听值变化函数,触发时间范围变化,且作用于echarts图形组件;
* 4、拖拽上面的那个时间字段三个,分别作为筛选器:”日“、”月“、”年“,用于作为时间粒度范围中的开始日期,且作用于echarts图形组件。
* (由于只是为了让图形组件请求数据,所以这三个筛选器最终作图后可以选择隐藏组件,不展示在仪表盘中。)
*/
// 初始化选中
function init(page: IPage, portlet: IFilterPortlet) {
// 修改选择器样式
method.doRenderStyle(portlet)
// 选择器点击修改日期的开始时间
doSelectTime(page, portlet)
// 初始化选择器第一次选中
let selectorValue: any = portlet.getValue()
method.doAction(page, selectorValue[0])
}
// 点击选择器时更新年月日的值
function doSelectTime(page: IPage, startDatePortlet: IFilterPortlet) {
startDatePortlet.setFilterValueChangeHandler(value => {
if (value && value[0]) {
method.doAction(page, value[0])
}
return value
})
// 日期选择器修改日期时也需要更新开始时间
let endDateFilter: IFilterPortlet = method.getPortlet(page, method.dc.endDatePortletTitle)
if (!endDateFilter) return
endDateFilter.setFilterValueChangeHandler(value => {
let selectorValue = startDatePortlet.getValue()
if (value && value[0]) {
method.doAction(page, selectorValue[0])
}
return value
})
}
var method = {
// 字段信息常量
fc: {
DATEINDEX: 0,
VALUEINDEX: 1
},
// 组件标题常量
dc: {
endDatePortletTitle: '日期',
chartPortletTitle: '图表',
textSelectorPortlet: '选择器'
},
// 定义选择器
getSelectors() {
return [
{ label: '年', calc: method.calcYear, total: method.calcTotalYear },
{ label: '月', calc: method.calcMonth, total: method.calcTotalMonth },
{ label: '日', calc: method.calcDate, total: method.calcTotalDay, checked: true /**默认高亮 */ }
]
},
// 点击事件处理
doAction(page: IPage, type: string | any) {
let selectors: any = method.getSelectors()
let selector = selectors.find((el: any) => el.label === type)
if (!selector) return
let endDateValue = method.getBaseDateValue(page)
let endDate: Date = new Date(endDateValue)
let beginDate: Date = selector.calc(new Date(endDateValue))
method.setValues(page, beginDate, selector.label)
let bdate = SmartbiXMacro.utils.formatDate(beginDate, 'yyyy-MM-dd')
let edate = SmartbiXMacro.utils.formatDate(endDate, 'yyyy-MM-dd')
// ECharts图形
let portlet: IEChartsPortlet = method.getPortlet(page, method.dc.chartPortletTitle)
if (!portlet) return
let flag = false
page.doPortletRendered(portlet.getId(), () => {
if (flag) return
flag = true
let options = portlet.getChartOptions()
if (!options) return
options = method.updateSeries(options, bdate, edate, selector)
portlet.setChartOptions(options)
})
},
// 更新Series(做合计)
updateSeries(options: object | any, bdate: string, edate: string, selector: any) {
selector.total(options, bdate, edate)
return options
},
// 不足两位补全0
zeroFn(num: number | string) {
return num < 10 ? '0' + num : num + ''
},
// 计算合计:年
calcTotalYear(options: any, bdate: string, edate: string) {
let { tooltipInfos } = options
let keys = Object.keys(tooltipInfos) || []
let da = { start: new Date(bdate), end: new Date(edate) }
let y = { start: da.start.getFullYear(), end: da.end.getFullYear() }
let m = { start: da.start.getMonth() + 1, end: da.end.getMonth() + 1 }
let d = { start: da.start.getDate(), end: da.end.getDate() }
let zeroFn = method.zeroFn
let dataObj: any = {}
let curTotal = 0 // 合计
let newAxisData: string[] = [] // 新的Axis的data
let newTooltipInfos: any = {} // 新的tooltipInfos
let newSeriesData: any = [] // 新的series的data
keys.forEach((key, index) => {
let item = tooltipInfos[key]
let dateValue = item[method.fc.DATEINDEX].value
let dataValue = item[method.fc.VALUEINDEX].realValue
let date = new Date(dateValue)
let year = date.getFullYear()
let startDateValue = `${year}-01-01`
let startDate = new Date(startDateValue)
let endDateValue = `${year}-${zeroFn(m.end)}-${zeroFn(d.end)}`
let endDate = new Date(endDateValue)
let isInDate = date >= startDate && date <= endDate // 一年中指定的[开始时间(year-01-01),结束时间]
if (!dataObj[year]) {
dataObj[year] = true
curTotal = dataValue
// xAsix的data数据
newAxisData.push(endDateValue)
} else if (isInDate) {
curTotal += dataValue
}
let parseD = SmartbiXMacro.utils.formatDate(date, 'yyyy-MM-dd')
let parseEndD = SmartbiXMacro.utils.formatDate(endDate, 'yyyy-MM-dd')
// if (isInDate) {
// console.warn('isInDate', isInDate, date, startDate, endDate)
// console.log(parseD === parseEndD, (isInDate && index === keys.length - 1))
// }
if (parseD === parseEndD || (isInDate && index === keys.length - 1)) {
let newIndex = newAxisData.indexOf(parseD)
let find = newSeriesData.find(el => el.displayValue[0] === endDateValue)
// console.warn(date, curTotal, newIndex, newAxisData)
if (!find) {
// series的data数据
newSeriesData.push({
value: [newIndex, curTotal],
displayValue: [endDateValue, curTotal],
rowIndex: [newIndex, newIndex],
colIndex: 1
})
// tooltip的数据
item[method.fc.DATEINDEX].value = endDateValue
item[method.fc.DATEINDEX].realValue = new Date(endDateValue).getTime()
item[method.fc.VALUEINDEX].value = curTotal + ''
item[method.fc.VALUEINDEX].realValue = curTotal
let newTooltipInfosKey = newIndex + '_1'
if (!newTooltipInfos[newTooltipInfosKey]) {
newTooltipInfos[newTooltipInfosKey] = []
}
newTooltipInfos[newTooltipInfosKey][method.fc.DATEINDEX] = item[method.fc.DATEINDEX]
newTooltipInfos[newTooltipInfosKey][method.fc.VALUEINDEX] = item[method.fc.VALUEINDEX]
}
}
})
options.xAxis[0].data = newAxisData
options.series[0].data = newSeriesData
options.tooltipInfos = newTooltipInfos
// console.warn('newAxisData', newAxisData)
// console.warn('newSeriesData', newSeriesData)
// console.warn('tooltipInfos', tooltipInfos)
return options
},
// 计算合计:月
calcTotalMonth(options: any, bdate: string, edate: string) {
let { tooltipInfos } = options
let keys = Object.keys(tooltipInfos) || []
let startMonth = new Date(bdate).getMonth()
let endDay = new Date(edate).getDate()
let zeroFn = method.zeroFn
let dataObj: any = {}
let newAxisData: string[] = []
let newTooltipInfos: any = {}
let newSeriesData: any = []
let curTotal = 0 // 合计
keys.forEach((key) => {
let item = tooltipInfos[key]
let dateValue = item[method.fc.DATEINDEX].value
let dataValue = item[method.fc.VALUEINDEX].realValue
let date = new Date(dateValue)
let year = date.getFullYear()
let month: number | string = zeroFn(date.getMonth() + 1)
let axisKey = `${year}-${month}`
let endDateValue = axisKey + '-' + zeroFn(endDay) // 每个月的同一天为合计截止日期
let isEndDay = method.isEndDay(dateValue, endDateValue) // 获取指定每个月的最后一天
// 月份总计total
if (!dataObj[axisKey]) {
dataObj[axisKey] = true
curTotal = dataValue
} else {
if (isEndDay || !(new Date(dateValue) > new Date(endDateValue))) {
curTotal += dataValue
}
}
// 结束时间(每个月最后一天不一样,所以要做判断,如果不一致需要更新endDateValue)
if (isEndDay) {
endDateValue = dateValue
// xAsix的data数据
let flag = newAxisData.indexOf(endDateValue) !== -1
if (flag) return
newAxisData.push(endDateValue)
// tooltip的数据
item[method.fc.DATEINDEX].value = endDateValue
item[method.fc.DATEINDEX].realValue = new Date(endDateValue).getTime()
item[method.fc.VALUEINDEX].value = curTotal + ''
item[method.fc.VALUEINDEX].realValue = curTotal
let newIndex = newAxisData.length - 1
let newTooltipInfosKey = newIndex + '_1'
if (!newTooltipInfos[newTooltipInfosKey]) {
newTooltipInfos[newTooltipInfosKey] = []
}
newTooltipInfos[newTooltipInfosKey][method.fc.DATEINDEX] = item[method.fc.DATEINDEX]
newTooltipInfos[newTooltipInfosKey][method.fc.VALUEINDEX] = item[method.fc.VALUEINDEX]
// series的data数据
newSeriesData.push({
value: [newIndex, curTotal],
displayValue: [item[method.fc.DATEINDEX].value, item[method.fc.VALUEINDEX].value],
rowIndex: [newIndex, newIndex],
colIndex: 1
})
}
})
options.xAxis[0].data = newAxisData
options.series[0].data = newSeriesData
options.tooltipInfos = newTooltipInfos
// console.warn('newAxisData', newAxisData)
// console.warn('newSeriesData', newSeriesData)
// console.warn('tooltipInfos', tooltipInfos)
return options
},
// 计算合计:日,这里不需要计算,写个空方法直接返回options
calcTotalDay(options: any, bdate: string, edate: string) {
return options
},
isEndDay(currentDate: string, endDate: string) {
let monthLastDay = method.getMonthEndDay(currentDate)
if (currentDate === endDate) return true
let cdate = new Date(currentDate)
let edate = new Date(endDate)
if (cdate > edate) {
return false
}
// 当前判断的日期
let cDay = cdate.getDate()
if (cDay === monthLastDay) return true
return false
},
// 根据标题获取组件
getPortlet<T>(page: IPage, title: string): T {
let portlets: T[] = page.getPortletsByTitle(title)
let portlet: T = portlets[0]
return portlet
},
// 获取自定义当前时间筛选器的值
getBaseDateValue(page: IPage) {
let filter: IFilterPortlet = method.getPortlet(page, method.dc.endDatePortletTitle)
if (!filter) return ''
let value = filter.getValue()
if (!value || !value.length) return ''
return value[0]
},
/**
* 选择“年”:
* 数据区间选取 当前日期 至 前一年,且根据当前所选的日,
* 每年选取年的第一天 至 当日(如2020-02-29,2019-02-28),
* 展示所选日期对应每年的当月日,根据年汇总。
*/
calcYear(baseDate: Date) {
let year = baseDate.getFullYear();
let num = 1;
year -= 1num;
let resultDate = new Date(`${year}-01-01`)
return resultDate
},
/**
* 选择“月”:
* 数据区间选取 当前月份 至 往前12个月,
* 且根据所选日期的日(如30号),
* 每个月选取 月的第1天 至 当日(如2月则是1-28号),
* 展示为所选日期对应每月的当日(如选2020-03-30,展示2020-02-29,2020-01-30),
* 根据月汇总。
*/
calcMonth(baseDate: Date) {
let month = baseDate.getMonth();
let num = 12;
month -= num;
method.setMonth(baseDate, month, num)
baseDate.setDate(1);
return baseDate
},
/**
* 选择“日”:
* 数据区间选取 当前日期 至 往前40天。
*/
calcDate(baseDate: Date) {
let date = baseDate.getDate();
let num = 40;
date -= 40num;
baseDate.setDate(date)
return baseDate
},
setMonth(currentDate: Date, month: number, num: number) {
let day = currentDate.getDate();
currentDate.setMonth(month);
if (num && day !== currentDate.getDate()) {
let currentMonthLastDay = new Date(currentDate.getTime() - 1000 * 60 * 60 * 24 * currentDate.getDate());
currentDate.setYear(currentMonthLastDay.getFullYear());
currentDate.setMonth(currentMonthLastDay.getMonth());
currentDate.setDate(currentMonthLastDay.getDate());
}
},
// 获取每个月最后一天
getMonthEndDay(currentDate: string) {
let clastdate = new Date(currentDate)
let year = clastdate.getFullYear()
let month = clastdate.getMonth() + 1
if (month > 12) {
month -= 1
year += 1
}
let lateDate = new Date(year, month, 1);
let lastDay = (new Date(lateDate.getTime() - 1000 * 60 * 60 * 24)).getDate();
return lastDay
},
// 单选设置值
setValues(page: IPage, currentDate: Date, selectorLabel: any) {
let selectors = method.getSelectors()
let value = SmartbiXMacro.utils.formatDate(currentDate, 'yyyy-MM-dd') + ' 00:00:00'
selectors.forEach(el => {
let portlet: IFilterPortlet = method.getPortlet(page, el.label)
if (!portlet) return
if (el.label === selectorLabel) {
setTimeout(() => { portlet.setValue([value]) }, 0)
} else {
setTimeout(() => { portlet.setValue([]) }, 0)
}
})
},
/**
* 调整筛选器样式
*/
doRenderStyle(portlet: IFilterPortlet) {
portlet.appendCss('.el-radio-group table', `{display: inline-flex;}`)
portlet.appendCss('.filter-list__td', `{padding: 0px;}`)
portlet.appendCss(`.filter-wrapper .el-radio-group .el-radio`, `{
background-color: #eeeeee;
width: 30px;
height: 30px;
justify-content: center;
padding: 0px;
}`)
portlet.appendCss('.filter-wrapper .el-radio-group .el-radio.is-checked', `{background-color: rgb(188, 139, 42);}`)
portlet.appendCss('.filter-wrapper .el-radio-group .el-radio.is-checked .el-radio__label', `{color: #fff;}`)
portlet.appendCss('.el-radio .el-radio__input', `{display: none; }`)
portlet.appendCss('.el-radio__label', `{padding-left: 0px;}`)
}
}
|