@@ -43,14 +43,30 @@ import {
updateShapeAttr ,
ViewMeta
} from ' @antv / s2 '
import { cloneDeep , filter , find , intersection , keys , merge , repeat } from ' lodash - es '
import { createVNode , render } from ' vue '
import {
cloneDeep ,
filter ,
find ,
intersection ,
keys ,
map ,
maxBy ,
meanBy ,
merge ,
minBy ,
repeat ,
sumBy ,
size ,
sum
} from ' lodash - es '
import { createVNode , render } from ' vue '
import TableTooltip from ' @ / views / chart / components / editor / common / TableTooltip . vue '
import Exceljs from ' exceljs '
import { saveAs } from ' file - saver '
import { ElMessage } from ' element - plus - secondary '
import { useI18n } from ' @ / hooks / web / useI18n '
const { t : i18nt } = useI18n ( )
import { saveAs } from ' file - saver '
import { ElMessage } from ' element - plus - secondary '
import { useI18n } from ' @ / hooks / web / useI18n '
const { t : i18nt } = useI18n ( )
export function getCustomTheme ( chart : Chart ) : S2Theme {
const headerColor = hexColorToRGBA (
@@ -199,7 +215,7 @@ export function getCustomTheme(chart: Chart): S2Theme {
let customAttr : DeepPartial < ChartAttr >
if ( chart . customAttr ) {
customAttr = parseJson ( chart . customAttr )
const { basicStyle , tableHeader , tableCell } = customAttr
const { basicStyle , tableHeader , tableCell } = customAttr
// basic
if ( basicStyle ) {
const tableBorderColor = basicStyle . tableBorderColor
@@ -251,7 +267,7 @@ export function getCustomTheme(chart: Chart): S2Theme {
}
const fontStyle = tableHeader . isItalic ? ' italic ' : ' normal '
const fontWeight = tableHeader . isBolder = = = false ? ' normal ' : ' bold '
const { tableHeaderAlign , tableTitleFontSize } = tableHeader
const { tableHeaderAlign , tableTitleFontSize } = tableHeader
const tmpTheme : S2Theme = {
cornerCell : {
cell : {
@@ -366,7 +382,7 @@ export function getCustomTheme(chart: Chart): S2Theme {
}
const fontStyle = tableCell . isItalic ? ' italic ' : ' normal '
const fontWeight = tableCell . isBolder = = = false ? ' normal ' : ' bold '
const { tableItemAlign , tableItemFontSize , enableTableCrossBG } = tableCell
const { tableItemAlign , tableItemFontSize , enableTableCrossBG } = tableCell
const tmpTheme : S2Theme = {
rowCell : {
cell : {
@@ -476,7 +492,7 @@ export function getStyle(chart: Chart, dataConfig: S2DataConfig): Style {
let customAttr : DeepPartial < ChartAttr >
if ( chart . customAttr ) {
customAttr = parseJson ( chart . customAttr )
const { basicStyle , tableHeader , tableCell } = customAttr
const { basicStyle , tableHeader , tableCell } = customAttr
style . colCfg = {
height : tableHeader . tableTitleHeight
}
@@ -497,7 +513,7 @@ export function getStyle(chart: Chart, dataConfig: S2DataConfig): Style {
} , { } ) | | { }
// 下钻字段使用入口字段的宽度
if ( chart . drill ) {
const { xAxis } = parseJson ( chart )
const { xAxis } = parseJson ( chart )
const curDrillField = chart . drillFields [ chart . drillFilters . length ]
const drillEnterFieldIndex = xAxis . findIndex (
item = > item . id = = = chart . drillFilters [ 0 ] . fieldId
@@ -589,7 +605,7 @@ export function getCurrentField(valueFieldList: Axis[], field: ChartViewField) {
}
export function getConditions ( chart : Chart ) {
const { threshold } = parseJson ( chart . senior )
const { threshold } = parseJson ( chart . senior )
if ( ! threshold . enable ) {
return
}
@@ -601,7 +617,7 @@ export function getConditions(chart: Chart) {
const dimFields = [ . . . chart . xAxis , . . . chart . xAxisExt ] . map ( i = > i . dataeaseName )
if ( conditions ? . length > 0 ) {
const { tableCell , basicStyle , tableHeader } = parseJson ( chart . customAttr )
const { tableCell , basicStyle , tableHeader } = parseJson ( chart . customAttr )
// 合并单元格时斑马纹失效
const enableTableCrossBG = chart . type = = = ' table - info ' ? tableCell . enableTableCrossBG & & ! tableCell . mergeCells : tableCell . enableTableCrossBG
const valueColor = isAlphaColor ( tableCell . tableFontColor )
@@ -610,8 +626,8 @@ export function getConditions(chart: Chart) {
const valueBgColor = enableTableCrossBG
? null
: isAlphaColor ( tableCell . tableItemBgColor )
? tableCell . tableItemBgColor
: hexColorToRGBA ( tableCell . tableItemBgColor , basicStyle . alpha )
? tableCell . tableItemBgColor
: hexColorToRGBA ( tableCell . tableItemBgColor , basicStyle . alpha )
const headerValueColor = tableHeader . tableHeaderFontColor
const headerValueBgColor = isAlphaColor ( tableHeader . tableHeaderBgColor )
? tableHeader . tableHeaderBgColor
@@ -662,7 +678,7 @@ export function getConditions(chart: Chart) {
if ( isTransparent ( fill ) ) {
return null
}
return { fill }
return { fill }
}
} )
}
@@ -876,9 +892,10 @@ export function handleTableEmptyStrategy(chart: Chart) {
}
return newData
}
export class SortTooltip extends BaseTooltip {
show ( showOptions ) {
const { iconName } = showOptions
const { iconName } = showOptions
if ( iconName ) {
this . showSortTooltip ( showOptions )
return
@@ -887,9 +904,9 @@ export class SortTooltip extends BaseTooltip {
}
showSortTooltip ( showOptions ) {
const { position , options , meta , event } = showOptions
const { enterable } = getTooltipDefaultOptions ( options )
const { autoAdjustBoundary , adjustPosition } = this . spreadsheet . options . tooltip | | { }
const { position , options , meta , event } = showOptions
const { enterable } = getTooltipDefaultOptions ( options )
const { autoAdjustBoundary , adjustPosition } = this . spreadsheet . options . tooltip | | { }
this . visible = true
this . options = showOptions
const container = this [ ' getContainer ' ] ( )
@@ -903,14 +920,14 @@ export class SortTooltip extends BaseTooltip {
this . spreadsheet . tooltip . container . appendChild ( childElement )
render ( vNode , childElement )
const { x , y } = getAutoAdjustPosition ( {
const { x , y } = getAutoAdjustPosition ( {
spreadsheet : this . spreadsheet ,
position ,
tooltipContainer : container ,
autoAdjustBoundary
} )
this . position = adjustPosition ? . ( { position : { x , y } , event } ) ? ? {
this . position = adjustPosition ? . ( { position : { x , y } , event } ) ? ? {
x ,
y
}
@@ -930,6 +947,7 @@ export class SortTooltip extends BaseTooltip {
} )
}
}
const SORT_DEFAULT =
' < svg t = " 1711681787276 " class = " icon " viewBox= " 0 0 1024 1024 " version= " 1 . 1 " xmlns= " http : //www.w3.org/2000/svg" p-id="4355" width="200" height="200"><path d="M922.345786 372.183628l-39.393195 38.687114L676.138314 211.079416l0 683.909301-54.713113 0L621.425202 129.010259l53.320393 0L922.345786 372.183628zM349.254406 894.989741 101.654214 651.815349l39.393195-38.687114 206.814276 199.792349L347.861686 129.010259l54.713113 0 0 765.978459L349.254406 894.988718z" fill="{fill}" p-id="4356"></path></svg>'
const SORT_UP =
@@ -942,7 +960,7 @@ function svg2Base64(svg) {
}
export function configHeaderInteraction ( chart : Chart , option : S2Options ) {
const { tableHeaderFontColor , tableHeaderSort } = parseJson ( chart . customAttr ) . tableHeader
const { tableHeaderFontColor , tableHeaderSort } = parseJson ( chart . customAttr ) . tableHeader
if ( ! tableHeaderSort ) {
return
}
@@ -994,7 +1012,7 @@ export function configHeaderInteraction(chart: Chart, option: S2Options) {
return iconName = = = ` customSortDefault$ { randomSuffix } `
} ,
onClick : props = > {
const { meta , event } = props
const { meta , event } = props
meta . spreadsheet . showTooltip ( {
position : {
x : event . clientX ,
@@ -1022,7 +1040,7 @@ export function configHeaderInteraction(chart: Chart, option: S2Options) {
}
export function configTooltip ( chart : Chart , option : S2Options ) {
const { tooltip } = parseJson ( chart . customAttr )
const { tooltip } = parseJson ( chart . customAttr )
const textFontFamily = chart . fontFamily ? chart . fontFamily : FONT_FAMILY
option . tooltip = {
. . . option . tooltip ,
@@ -1037,7 +1055,7 @@ export function configTooltip(chart: Chart, option: S2Options) {
opacity : 0 . 95 ,
position : ' absolute '
} ,
adjustPosition : ( { event } ) = > {
adjustPosition : ( { event } ) = > {
return getTooltipPosition ( event )
}
}
@@ -1052,7 +1070,7 @@ export function copyContent(s2Instance: SpreadSheet, event, fieldMeta) {
let content = ' '
// 多选
if ( selectState . stateName = = = InteractionStateName . SELECTED ) {
const { cells } = selectState
const { cells } = selectState
if ( ! cells ? . length ) {
return
}
@@ -1147,13 +1165,13 @@ export function copyContent(s2Instance: SpreadSheet, event, fieldMeta) {
function getTooltipPosition ( event ) {
const s2Instance = event . s2Instance
const { x , y } = event
const result = { x : x + 15 , y }
const { x , y } = event
const result = { x : x + 15 , y }
if ( ! s2Instance ) {
return result
}
const { height , width } = s2Instance . getCanvasElement ( ) . getBoundingClientRect ( )
const { offsetHeight , offsetWidth } = s2Instance . tooltip . getContainer ( )
const { height , width } = s2Instance . getCanvasElement ( ) . getBoundingClientRect ( )
const { offsetHeight , offsetWidth } = s2Instance . tooltip . getContainer ( )
if ( offsetWidth > width ) {
result . x = 0
}
@@ -1181,8 +1199,8 @@ function getTooltipPosition(event) {
}
export async function exportGridPivot ( instance : PivotSheet , chart : ChartObj ) {
const { layoutResult } = instance . facet
const { meta , fields } = instance . dataCfg
const { layoutResult } = instance . facet
const { meta , fields } = instance . dataCfg
const rowLength = fields ? . rows ? . length | | 0
const colLength = fields ? . columns ? . length | | 0
const colNums = layoutResult . colLeafNodes . length + rowLength + 1
@@ -1202,27 +1220,27 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
fields . columns ? . forEach ( ( column , index ) = > {
const cell = worksheet . getCell ( index + 1 , 1 )
cell . value = metaMap [ column ] ? . name ? ? column
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( rowLength > = 2 ) {
worksheet . mergeCells ( index + 1 , 1 , index + 1 , rowLength )
}
cell . border = {
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
fields ? . rows ? . forEach ( ( row , index ) = > {
const cell = worksheet . getCell ( colLength + 1 , index + 1 )
cell . value = metaMap [ row ] ? . name ? ? row
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . border = {
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
if ( index = = = fields . rows . length - 1 ) {
cell . border . right = { style : ' thick ' , color : { argb : ' 00000000 ' } }
cell . border . right = { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
// 行头
const { rowLeafNodes , rowsHierarchy , rowNodes } = layoutResult
const { rowLeafNodes , rowsHierarchy , rowNodes } = layoutResult
const maxColIndex = rowsHierarchy . maxLevel + 1
const notLeafNodeHeightMap : Record < string , number > = { }
rowLeafNodes . forEach ( node = > {
@@ -1233,17 +1251,17 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
notLeafNodeHeightMap [ curNode . id ] = height + 1
curNode = curNode . parent
}
const { rowIndex } = node
const { rowIndex } = node
const writeRowIndex = rowIndex + 1 + colLength + 1
const writeColIndex = node . level + 1
const cell = worksheet . getCell ( writeRowIndex , writeColIndex )
cell . value = node . label
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( writeColIndex < maxColIndex ) {
worksheet . mergeCells ( writeRowIndex , writeColIndex , writeRowIndex , maxColIndex )
}
cell . border = {
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
@@ -1265,7 +1283,7 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
const value = node . label
const cell = worksheet . getCell ( writeRowIndex , node . level + 1 )
cell . value = value
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( mergeColCount > 1 | | height > 1 ) {
worksheet . mergeCells (
writeRowIndex ,
@@ -1277,7 +1295,7 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
} )
// 列头
const { colLeafNodes , colNodes , colsHierarchy } = layoutResult
const { colLeafNodes , colNodes , colsHierarchy } = layoutResult
const maxColHeight = colsHierarchy . maxLevel + 1
const notLeafNodeWidthMap : Record < string , number > = { }
colLeafNodes . forEach ( node = > {
@@ -1288,7 +1306,7 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
notLeafNodeWidthMap [ curNode . id ] = width + 1
curNode = curNode . parent
}
const { colIndex } = node
const { colIndex } = node
const writeRowIndex = node . level + 1
const writeColIndex = colIndex + 1 + rowLength
const cell = worksheet . getCell ( writeRowIndex , writeColIndex )
@@ -1297,12 +1315,12 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
value = metaMap [ value ] . name
}
cell . value = value
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( writeRowIndex < maxColHeight ) {
worksheet . mergeCells ( writeRowIndex , writeColIndex , maxColHeight , writeColIndex )
}
cell . border = {
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
const getNodeStartColIndex = ( node : Node ) = > {
@@ -1324,7 +1342,7 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
const writeColIndex = colIndex + rowLength
const cell = worksheet . getCell ( writeRowIndex , writeColIndex )
cell . value = value
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( mergeRowCount > 1 | | width > 1 ) {
worksheet . mergeCells (
writeRowIndex ,
@@ -1338,12 +1356,12 @@ export async function exportGridPivot(instance: PivotSheet, chart: ChartObj) {
for ( let rowIndex = 0 ; rowIndex < rowLeafNodes . length ; rowIndex + + ) {
for ( let colIndex = 0 ; colIndex < colLeafNodes . length ; colIndex + + ) {
const dataCellMeta = layoutResult . getCellMeta ( rowIndex , colIndex )
const { fieldValue } = dataCellMeta
const { fieldValue } = dataCellMeta
if ( fieldValue = = = 0 | | fieldValue ) {
const meta = metaMap [ dataCellMeta . valueField ]
const cell = worksheet . getCell ( rowIndex + maxColHeight + 1 , rowLength + colIndex + 1 )
const value = meta ? . formatter ? . ( fieldValue ) | | fieldValue . toString ( )
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . value = value
}
}
@@ -1361,7 +1379,7 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
ElMessage . warning ( i18nt ( ' chart . pivot_export_invalid_col_exceed ' ) )
return
}
const { meta , fields } = instance . dataCfg
const { meta , fields } = instance . dataCfg
const colLength = fields ? . columns ? . length | | 0
const workbook = new Exceljs . Workbook ( )
const worksheet = workbook . addWorksheet ( i18nt ( ' chart . chart_data ' ) )
@@ -1376,33 +1394,33 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
fields . columns ? . forEach ( ( column , index ) = > {
const cell = worksheet . getCell ( index + 1 , 1 )
cell . value = metaMap [ column ] ? . name ? ? column
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . border = {
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
const maxColHeight = layoutResult . colsHierarchy . maxLevel + 1
const rowName = fields ? . rows ? . map ( row = > metaMap [ row ] ? . name ? ? row ) . join ( '/' )
const cell = worksheet . getCell ( colLength + 1 , 1 )
cell . value = rowName
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . border = {
right : { style : ' thick ' , color : { argb : ' 00000000 ' } } ,
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
right : { style : ' thick ' , color : { argb : ' 00000000 ' } } ,
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
//行头
const { rowLeafNodes } = layoutResult
const { rowLeafNodes } = layoutResult
rowLeafNodes . forEach ( ( node , index ) = > {
const cell = worksheet . getCell ( maxColHeight + index + 1 , 1 )
cell . value = repeat ( ' ' , node . level ) + node . label
cell . alignment = { vertical : ' middle ' , horizontal : ' left ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' left ' }
cell . border = {
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
right : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
// 列头
const notLeafNodeWidthMap : Record < string , number > = { }
const { colLeafNodes } = layoutResult
const { colLeafNodes } = layoutResult
colLeafNodes . forEach ( node = > {
let curNode = node . parent
while ( curNode ) {
@@ -1410,7 +1428,7 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
notLeafNodeWidthMap [ curNode . id ] = width + 1
curNode = curNode . parent
}
const { colIndex } = node
const { colIndex } = node
const writeRowIndex = node . level + 1
const writeColIndex = colIndex + 1 + 1
const cell = worksheet . getCell ( writeRowIndex , writeColIndex )
@@ -1419,12 +1437,12 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
value = metaMap [ value ] . name
}
cell . value = value
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( writeRowIndex < maxColHeight ) {
worksheet . mergeCells ( writeRowIndex , writeColIndex , maxColHeight , writeColIndex )
}
cell . border = {
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
bottom : { style : ' thick ' , color : { argb : ' 00000000 ' } }
}
} )
const colNodes = layoutResult . colNodes
@@ -1446,7 +1464,7 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
const writeColIndex = colIndex + 1
const cell = worksheet . getCell ( writeRowIndex , writeColIndex )
cell . value = node . label
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
if ( mergeRowCount > 1 | | width > 1 ) {
worksheet . mergeCells (
writeRowIndex ,
@@ -1460,12 +1478,12 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
for ( let rowIndex = 0 ; rowIndex < rowLeafNodes . length ; rowIndex + + ) {
for ( let colIndex = 0 ; colIndex < colLeafNodes . length ; colIndex + + ) {
const dataCellMeta = layoutResult . getCellMeta ( rowIndex , colIndex )
const { fieldValue } = dataCellMeta
const { fieldValue } = dataCellMeta
if ( fieldValue = = = 0 | | fieldValue ) {
const meta = metaMap [ dataCellMeta . valueField ]
const cell = worksheet . getCell ( rowIndex + maxColHeight + 1 , colIndex + 1 + 1 )
const value = meta ? . formatter ? . ( fieldValue ) | | fieldValue . toString ( )
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . alignment = { vertical : ' middle ' , horizontal : ' center ' }
cell . value = value
}
}
@@ -1476,8 +1494,9 @@ export async function exportTreePivot(instance: PivotSheet, chart: ChartObj) {
} )
saveAs ( dataBlob , ` $ { chart . title ? ? ' 透视表 ' } . xlsx ` )
}
export async function exportPivotExcel ( instance : PivotSheet , chart : ChartObj ) {
const { fields } = instance . dataCfg
const { fields } = instance . dataCfg
const rowLength = fields ? . rows ? . length | | 0
const valueLength = fields ? . values ? . length | | 0
if ( ! ( rowLength & & valueLength ) ) {
@@ -1492,8 +1511,8 @@ export async function exportPivotExcel(instance: PivotSheet, chart: ChartObj) {
}
export function configMergeCells ( chart : Chart , options : S2Options , dataConfig : S2DataConfig ) {
const { mergeCells } = parseJson ( chart . customAttr ) . tableCell
const { showIndex } = parseJson ( chart . customAttr ) . tableHeader
const { mergeCells } = parseJson ( chart . customAttr ) . tableCell
const { showIndex } = parseJson ( chart . customAttr ) . tableHeader
if ( mergeCells ) {
options . frozenColCount = 0
options . frozenRowCount = 0
@@ -1601,7 +1620,7 @@ class CustomMergedCell extends MergedCell {
const allPoints = getPolygonPoints ( this . cells )
// 处理条件样式,这里没有用透明度
// 因为合并的单元格是单独的图层,透明度降低的话会显示底下未合并的单元格,需要单独处理被覆盖的单元格
const { backgroundColor : fill , backgroundColorOpacity : fillOpacity } = this . getBackgroundColor ( )
const { backgroundColor : fill , backgroundColorOpacity : fillOpacity } = this . getBackgroundColor ( )
const cellTheme = this . theme . dataCell . cell
this . backgroundShape = renderPolygon ( this , {
points : allPoints ,
@@ -1610,6 +1629,7 @@ class CustomMergedCell extends MergedCell {
lineHeight : cellTheme . horizontalBorderWidth
} )
}
drawTextShape ( ) : void {
if ( this . meta . deFieldType = = = 7 ) {
drawImage . apply ( this )
@@ -1674,11 +1694,11 @@ const drawTextShape = (cell, isHeader) => {
// 用户配置的最大行数
const maxLines = cell . meta . maxLines ? ? 1
const {
options : { placeholder }
options : { placeholder }
} = cell . spreadsheet
const emptyPlaceholder = getEmptyPlaceholder ( this , placeholder )
// 单元格文本
const { formattedValue } = cell . getFormattedFieldValue ( )
const { formattedValue } = cell . getFormattedFieldValue ( )
// 获取文本样式
const textStyle = cell . getTextStyle ( )
// 宽度能放几个字符,就放几个,放不下就换行
@@ -1758,7 +1778,7 @@ export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, l
if ( tableHeader . showTableHeader = = = false ) return
const ev = layoutResult | | newChart . facet . layoutResult
const maxLines = basicStyle . maxLines ? ? 1
const textStyle = { . . . newChart . theme . cornerCell . text }
const textStyle = { . . . newChart . theme . cornerCell . text }
const sourceText = info . info . meta . value
let maxHeight = getWrapTextHeight (
getWrapText ( sourceText , textStyle , info . info . resizedWidth , ev . spreadsheet ) ,
@@ -1779,10 +1799,10 @@ export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, l
maxLines
)
return wrapTextHeight > maxHeightNode . height
? { height : wrapTextHeight , colIndex : currentNode . colIndex }
? { height : wrapTextHeight , colIndex : currentNode . colIndex }
: maxHeightNode
} ,
{ height : 0 }
{ height : 0 }
)
// 使用最大高度
@@ -1873,30 +1893,71 @@ export const configSummaryRow = (
// 设置汇总行高度和表头一致
const heightByField = { }
heightByField [ newData . length ] = tableHeader . tableTitleHeight
s2Options . style . rowCfg = { heightByField }
s2Options . style . rowCfg = { heightByField }
// 计算汇总加入到数据里,冻结最后一行
s2Options . frozenTrailingRowCount = 1
const yAxis = chart . yAxis
const xAxis = chart . xAxis
const summaryObj = newData . reduce (
( p , n ) = > {
if ( chart . type = = = ' table - info ' ) {
x Axis
. filter ( axis = > [ 2 , 3 , 4 ] . includes ( axis . deType ) )
. forEach ( axis = > {
p [ axis . dataeaseName ] =
( parseFloat ( n [ axis . dataeaseName ] ) | | 0 ) + ( parseFloat ( p [ axis . dataeaseName ] ) | | 0 )
} )
} else {
y Axis. forEach ( axis = > {
p [ axis . dataeaseName ] =
( parseFloat ( n [ axis . dataeaseName ] ) | | 0 ) + ( parseFloat ( p [ axis . dataeaseName ] ) | | 0 )
} )
const axis = chart . type = = = ' table - info '
? filter ( chart . xAxis , axis = > [ 2 , 3 , 4 ] . includes ( axis . deType ) )
: chart . y Axis
const summaryObj = { SUMMARY : true }
for ( let i = 0 ; i < axis . length ; i + + ) {
const a = axis [ i ] . dataeaseName
let savedAxis = find ( basicStyle . seriesSummary , s = > s . field = = = a )
if ( savedAxis ) {
if ( savedAxis . summary = = undefined ) {
saved Axis. summary = ' sum '
}
return p
} ,
{ SUMMARY : true }
)
if ( savedAxis . show = = undefined ) {
savedAxis . show = true
}
} else {
savedAxis = {
field : a ,
summary : ' sum ' ,
show : true
}
}
if ( ! savedAxis . show ) {
continue
}
switch ( savedAxis . summary ) {
case ' sum ' :
summaryObj [ a ] = sumBy ( newData , d = > ( parseFloat ( d [ a ] ) | | 0 ) )
break
case ' avg ' :
summaryObj [ a ] = meanBy ( newData , d = > ( parseFloat ( d [ a ] ) | | 0 ) )
break
case ' max ' :
summaryObj [ a ] = maxBy ( filter ( newData , d = > parseFloat ( d [ a ] ) ! = = undefined ) , d = > parseFloat ( d [ a ] ) ) [ a ]
break
case ' min ' :
summaryObj [ a ] = minBy ( filter ( newData , d = > parseFloat ( d [ a ] ) ! = = undefined ) , d = > parseFloat ( d [ a ] ) ) [ a ]
break
case ' var_pop ' : //方差
if ( newData . length < 2 ) {
continue
} else {
const mean = meanBy ( newData , d = > ( parseFloat ( d [ a ] ) | | 0 ) ) // 计算均值
const squaredDeviations = map ( newData , d = > ( ( parseFloat ( d [ a ] ) | | 0 ) - mean ) * * 2 ) ; // 计算偏差平方
summaryObj [ a ] = sum ( squaredDeviations ) / ( size ( newData ) - 1 ) ; // 样本方差( 分母n-1)
}
break
case ' stddev_pop ' : //标准差
if ( newData . length < 2 ) {
continue
} else {
const mean = meanBy ( newData , d = > ( parseFloat ( d [ a ] ) | | 0 ) ) // 计算均值
const squaredDeviations = map ( newData , d = > ( ( parseFloat ( d [ a ] ) | | 0 ) - mean ) * * 2 ) ; // 计算偏差平方
const sampleVariance = sum ( squaredDeviations ) / ( size ( newData ) - 1 ) ; // 样本方差( 分母n-1)
summaryObj [ a ] = Math . sqrt ( sampleVariance ) ; // 样本标准差
}
break
}
}
newData . push ( summaryObj )
s2Options . dataCell = viewMeta = > {
// 配置文本自动换行参数
@@ -1948,9 +2009,10 @@ export class SummaryCell extends CustomDataCell {
textStyle . textAlign = this . theme . dataCell . text . textAlign
return textStyle
}
getBackgroundColor ( ) {
const { backgroundColor , backgroundColorOpacity } = this . theme . colCell . cell
return { backgroundColor , backgroundColorOpacity }
const { backgroundColor , backgroundColorOpacity } = this . theme . colCell . cell
return { backgroundColor , backgroundColorOpacity }
}
}
@@ -2026,12 +2088,12 @@ export const getColumns = (fields, cols: Array<ColumnNode>) => {
export function drawImage ( ) {
const img = new Image ( )
const { x , y , width , height , fieldValue } = this . meta
const { x , y , width , height , fieldValue } = this . meta
img . src = fieldValue as string
img . setAttribute ( ' crossOrigin ' , ' anonymous ' )
img . onload = ( ) = > {
! this . cfg . children & & ( this . cfg . children = [ ] )
const { width : imgWidth , height : imgHeight } = img
const { width : imgWidth , height : imgHeight } = img
const ratio = Math . max ( imgWidth / width , imgHeight / height )
// 不铺满,部分留白
const imgShowWidth = ( imgWidth / ratio ) * 0 . 8