/* * << * Davinci * == * Copyright (C) 2016 - 2017 EDP * == * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * >> */ import { compose } from 'redux' import { getLastItemValueOfArray } from './util' import { RequireAtLeastOne } from 'utils/types' import WidgetAbstract, { DrillCharts, DrillType, WidgetDimensions, IDrillDetail, IDrillStrategies, ISourceDataFilter } from './types' import { IFilter } from '../Control/types' import { getValidColumnValue } from 'app/components/Control/util' import OperatingWidget, { operationWidgetProps, setDefaultReplaceNull } from './abstract/widgetOperating' import { IWidgetDimension } from 'containers/Widget/components/Widget' const setDefaultEmptyArray = setDefaultReplaceNull((f) => f, []) export const strategiesOfDrillUpHasDrillHistory = ( lastDrillHistory: IDrillDetail, currentWidgetProps: WidgetAbstract ) => ( widgetDimension: RequireAtLeastOne, sourceData?, sourceGroup?: string[] ) => { return { [DrillCharts.PIVOT]: (): IDrillDetail => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { widgetProps, filters } = drillStragegies const lastGroupOfCols = currentWidgetProps.cols && currentWidgetProps.cols.length !== 0 ? getLastItemValueOfArray(currentWidgetProps.cols, 'name') : null const lastGroupOfRows = currentWidgetProps.rows && currentWidgetProps.rows.length !== 0 ? getLastItemValueOfArray(currentWidgetProps.rows, 'name') : null return { ...drillStragegies, filters: mappingFilters( sourceData, lastGroupOfCols || lastGroupOfRows ).concat(filters) } }, [DrillCharts.COUSTOMTABLE]: (): IDrillStrategies => { // 缺少对 sourceDataGroup 的处理, sourceDataGroup 只是对cols有影响,对filters没有影响。cols又决定table的表头 const drillStragegies: IDrillStrategies = common.call( null, widgetDimension ) const coustomTableFilters = compose( combineFilters, collectKeyValue, setDefaultEmptyArray )(sourceData) return { ...drillStragegies, filters: coustomTableFilters.concat(drillStragegies.filters) } } } function common(): IDrillStrategies { const WP = operationWidgetProps const { groups, filters } = lastDrillHistory const widgetProps = WP.deleteWithSthRowsOrCols( WP.deleteWithSthRowsOrCols( currentWidgetProps, WidgetDimensions.ROW, widgetDimension ), WidgetDimensions.COL, widgetDimension ) return { cols: widgetProps.cols, rows: widgetProps.rows, type: DrillType.UP, groups: groups.filter((group) => group !== widgetDimension.name), filters, widgetProps, currentGroup: widgetDimension.name } } } export const strategiesOfDrillDownHasDrillHistory = ( lastDrillHistory: IDrillDetail, currentWidgetProps: WidgetAbstract ) => ( widgetDimension: RequireAtLeastOne, sourceData, sourceDataGroup ) => { const WP = operationWidgetProps const cursor: Pick = coustomTableCursor( sourceData, sourceDataGroup ) function common( widgetDimension: IWidgetDimension, currentWidgetProps: WidgetAbstract ): IDrillStrategies { const { cols, rows, groups, filters } = lastDrillHistory return { cols, rows, type: DrillType.DOWN, groups, filters, widgetProps: currentWidgetProps, currentGroup: widgetDimension.name } } return { [DrillCharts.PIVOTCOL]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { groups, filters, widgetProps } = drillStragegies const nextWidgetProps = WP.insertWithSthRowsOrCols( widgetProps, WidgetDimensions.COL, widgetDimension ) const lastGroup = groups[groups.length - 1] return { ...drillStragegies, widgetProps: nextWidgetProps, groups: groups.concat(widgetDimension.name), filters: mappingFilters(sourceData, lastGroup).concat(filters), cols: nextWidgetProps.cols, rows: nextWidgetProps.rows } }, [DrillCharts.PIVOTROW]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { groups, filters, widgetProps } = drillStragegies const nextWidgetProps = WP.insertWithSthRowsOrCols( widgetProps, WidgetDimensions.ROW, widgetDimension ) const lastGroup = groups[groups.length - 1] return { ...drillStragegies, widgetProps: nextWidgetProps, groups: groups.concat(widgetDimension.name), filters: mappingFilters(sourceData, lastGroup).concat(filters), cols: nextWidgetProps.cols, rows: nextWidgetProps.rows } }, [DrillCharts.COUSTOMTABLE]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { groups, filters, widgetProps } = drillStragegies const nextWidgetProps = WP.insertWithSthRowsOrCols( widgetProps, WidgetDimensions.COL, widgetDimension, cursor ) const coustomTableFilters = compose( combineFilters, collectKeyValue, setDefaultEmptyArray )(sourceData) return { ...drillStragegies, groups: groups.concat(widgetDimension.name), filters: coustomTableFilters.concat(filters), cols: nextWidgetProps.cols, rows: nextWidgetProps.rows, widgetProps: nextWidgetProps } }, [DrillCharts.DIMETIONAXISCOL]: defaultStrategies, [DrillCharts.DIMETIONAXISROW]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { groups, filters, widgetProps } = drillStragegies const nextWidgetProps = WP.overWriteRowsOrCols( widgetProps, WidgetDimensions.ROW, widgetDimension ) const lastGroup = groups[groups.length - 1] return { ...drillStragegies, widgetProps: nextWidgetProps, groups: [widgetDimension.name], filters: mappingFilters(sourceData, lastGroup).concat(filters), cols: nextWidgetProps.cols, rows: nextWidgetProps.rows } }, [DrillCharts.DEFAULT]: defaultStrategies } function defaultStrategies(): IDrillStrategies { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension, currentWidgetProps ) const { groups, filters, widgetProps } = drillStragegies const nextWidgetProps = WP.overWriteRowsOrCols( widgetProps, WidgetDimensions.COL, widgetDimension ) const lastGroup = groups[groups.length - 1] return { ...drillStragegies, groups: [widgetDimension.name], filters: mappingFilters(sourceData, lastGroup).concat(filters), cols: nextWidgetProps.cols, rows: nextWidgetProps.rows, widgetProps: nextWidgetProps } } } export const strategiesOfDrillUpNullDrillHistory = ( WP: OperatingWidget, target: WidgetAbstract ) => ( widgetDimension: RequireAtLeastOne, sourceData? ) => { const initGroups = WP.initGroups() const initNativeFilters = WP.initWidgetNativeFilters() return { [DrillCharts.PIVOT]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension ) const { widgetProps } = drillStragegies const lastGroupOfCols = target.cols && target.cols.length !== 0 ? getLastItemValueOfArray(target.cols, 'name') : null const lastGroupOfRows = target.rows && target.rows.length !== 0 ? getLastItemValueOfArray(target.rows, 'name') : null return { ...drillStragegies, filters: mappingFilters( sourceData, lastGroupOfCols || lastGroupOfRows ).concat(initNativeFilters) } }, [DrillCharts.COUSTOMTABLE]: (): IDrillStrategies => { const drillStragegies: IDrillStrategies = common.call( null, widgetDimension ) const coustomTableFilters = compose( combineFilters, collectKeyValue, setDefaultEmptyArray )(sourceData) return { ...drillStragegies, filters: coustomTableFilters.concat(initNativeFilters) } } } function common(): IDrillStrategies { const widgetProps = WP.deleteWithSthRowsOrCols( WP.deleteWithSthRowsOrCols(target, WidgetDimensions.ROW, widgetDimension), WidgetDimensions.COL, widgetDimension ) return { widgetProps, type: DrillType.UP, groups: initGroups.filter((group) => group !== widgetDimension.name), currentGroup: widgetDimension.name, filters: initNativeFilters, cols: widgetProps.cols, rows: widgetProps.rows } } } export const strategiesOfDrillDownNullDrillHistory = ( WP: OperatingWidget, target: WidgetAbstract ) => ( widgetDimension: RequireAtLeastOne, sourceData, sourceDataGroup ) => { const initGroups = WP.initGroups() const initNativeFilters = WP.initWidgetNativeFilters() const getCols = WP.getRowsOrCols(WidgetDimensions.COL) const getRows = WP.getRowsOrCols(WidgetDimensions.ROW) const cursor: Pick = coustomTableCursor( sourceData, sourceDataGroup ) return { [DrillCharts.PIVOTCOL]: (): IDrillStrategies => { const widgetProps = WP.insertWithSthRowsOrCols( target, WidgetDimensions.COL, widgetDimension ) const lastGroupOfCols = getCols.length !== 0 ? getLastItemValueOfArray(getCols, 'name') : null const lastGroupOfRows = getRows.length !== 0 ? getLastItemValueOfArray(getRows, 'name') : null return { widgetProps, type: DrillType.DOWN, groups: initGroups.concat(widgetDimension.name), currentGroup: widgetDimension.name, filters: mappingFilters( sourceData, lastGroupOfCols || lastGroupOfRows ).concat(initNativeFilters), cols: widgetProps.cols, rows: widgetProps.rows } }, [DrillCharts.PIVOTROW]: (): IDrillStrategies => { const widgetProps = WP.insertWithSthRowsOrCols( target, WidgetDimensions.ROW, widgetDimension ) const lastGroupOfCols = getCols.length !== 0 ? getLastItemValueOfArray(getCols, 'name') : null const lastGroupOfRows = getRows.length !== 0 ? getLastItemValueOfArray(getRows, 'name') : null return { widgetProps, type: DrillType.DOWN, groups: initGroups.concat(widgetDimension.name), currentGroup: widgetDimension.name, filters: mappingFilters( sourceData, lastGroupOfCols || lastGroupOfRows ).concat(initNativeFilters), cols: widgetProps.cols, rows: widgetProps.rows } }, [DrillCharts.COUSTOMTABLE]: (): IDrillStrategies => { const widgetProps = WP.insertWithSthRowsOrCols( target, WidgetDimensions.COL, widgetDimension, cursor ) const coustomTableFilters = compose( combineFilters, collectKeyValue, setDefaultEmptyArray )(sourceData) return { widgetProps, type: DrillType.DOWN, // groups only determine the result of the data set, the order of the table header is determined by cols groups: initGroups.concat(widgetDimension.name), currentGroup: widgetDimension.name, filters: coustomTableFilters.concat(initNativeFilters), cols: widgetProps.cols, rows: widgetProps.rows } }, [DrillCharts.DIMETIONAXISCOL]: defaultStrategies, [DrillCharts.DIMETIONAXISROW]: (): IDrillStrategies => { const widgetProps = WP.overWriteRowsOrCols( target, WidgetDimensions.ROW, widgetDimension ) const lastGroup = getRows.length !== 0 ? getLastItemValueOfArray(getRows, 'name') : null return { widgetProps, type: DrillType.DOWN, groups: [widgetDimension.name], currentGroup: widgetDimension.name, filters: mappingFilters(sourceData, lastGroup).concat( initNativeFilters ), cols: widgetProps.cols, rows: widgetProps.rows } }, [DrillCharts.DEFAULT]: defaultStrategies } function defaultStrategies(): IDrillStrategies { const widgetProps = WP.overWriteRowsOrCols( target, WidgetDimensions.COL, widgetDimension ) const lastGroup = getCols.length !== 0 ? getLastItemValueOfArray(getCols, 'name') : null return { widgetProps, type: DrillType.DOWN, groups: [widgetDimension.name], currentGroup: widgetDimension.name, filters: mappingFilters(sourceData, lastGroup).concat(initNativeFilters), cols: widgetProps.cols, rows: widgetProps.rows } } } function collectKeyValue(sourceDataFilter) { return sourceDataFilter.reduce((iteratee, target) => { iteratee[target['key']] === undefined ? (iteratee[target['key']] = [target['value']]) : iteratee[target['key']].push(target['value']) return iteratee }, {}) } function mappingFilters(sourceDataFilter, group): IFilter[] { if (group === '指标名称') { return [] } if (!(sourceDataFilter && sourceDataFilter.length)) { return [] } const mappgingSource = sourceDataFilter.map((source) => source && source[group] ? source[group] : '' ) const sqlType = getSqlType(group) return [ { name: group, operator: 'in', type: 'filter', value: mappgingSource.map((val) => getValidColumnValue(val, sqlType)), sqlType } ] } function getSqlType(target: string) { return operationWidgetProps.getTypesOfModelByKeyName( operationWidgetProps.getModel(), 'sqlType' )(target) } function combineFilters(keyValuds): IFilter[] { return Object.keys(keyValuds).reduce((iteratee, target) => { const sqlType = getSqlType(target) return iteratee.concat({ name: target, operator: 'in', type: 'filter', value: keyValuds[target].map((v) => getValidColumnValue(v, sqlType)), sqlType }) }, []) } function coustomTableCursor( sourceDataFilter: ISourceDataFilter[], sourceDataGroup? ) { return { name: sourceDataFilter && sourceDataFilter.length ? getLastItemValueOfArray(sourceDataFilter, 'key') : sourceDataGroup && sourceDataGroup.length ? sourceDataGroup.pop() : '' } }