🎨 Database rollup supports numeric calculation https://github.com/siyuan-note/siyuan/issues/10796

This commit is contained in:
Daniel 2024-03-30 11:14:08 +08:00
parent 7f9ddedc8b
commit 8590bd1474
No known key found for this signature in database
GPG key ID: 86211BA83DF03017

View file

@ -1628,5 +1628,98 @@ func (table *Table) calcColRollup(col *TableColumn, colIndex int) {
if 0 < len(table.Rows) {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countNotEmpty)/float64(len(table.Rows)), NumberFormatPercent)}
}
case CalcOperatorSum:
sum := 0.0
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
sum += val
}
}
}
col.Calc.Result = &Value{Number: NewFormattedValueNumber(sum, col.NumberFormat)}
case CalcOperatorAverage:
sum := 0.0
count := 0
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
sum += val
count++
}
}
}
if 0 != count {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(sum/float64(count), col.NumberFormat)}
}
case CalcOperatorMedian:
values := []float64{}
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
values = append(values, val)
}
}
}
sort.Float64s(values)
if len(values) > 0 {
if len(values)%2 == 0 {
col.Calc.Result = &Value{Number: NewFormattedValueNumber((values[len(values)/2-1]+values[len(values)/2])/2, col.NumberFormat)}
} else {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(values[len(values)/2], col.NumberFormat)}
}
}
case CalcOperatorMin:
minVal := math.MaxFloat64
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
if val < minVal {
minVal = val
}
}
}
}
if math.MaxFloat64 != minVal {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(minVal, col.NumberFormat)}
}
case CalcOperatorMax:
maxVal := -math.MaxFloat64
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
if val > maxVal {
maxVal = val
}
}
}
}
if -math.MaxFloat64 != maxVal {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(maxVal, col.NumberFormat)}
}
case CalcOperatorRange:
minVal := math.MaxFloat64
maxVal := -math.MaxFloat64
for _, row := range table.Rows {
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Rollup && 0 < len(row.Cells[colIndex].Value.Rollup.Contents) {
for _, content := range row.Cells[colIndex].Value.Rollup.Contents {
val, _ := strconv.ParseFloat(content.String(), 64)
if val < minVal {
minVal = val
}
if val > maxVal {
maxVal = val
}
}
}
}
if math.MaxFloat64 != minVal && -math.MaxFloat64 != maxVal {
col.Calc.Result = &Value{Number: NewFormattedValueNumber(maxVal-minVal, col.NumberFormat)}
}
}
}