mirror of
https://github.com/siyuan-note/siyuan.git
synced 2026-03-09 06:02:33 +01:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
6ddcd12117
3 changed files with 199 additions and 52 deletions
|
|
@ -362,6 +362,8 @@ func (table *Table) CalcCols() {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch col.Type {
|
switch col.Type {
|
||||||
|
case KeyTypeBlock:
|
||||||
|
table.calcColBlock(col, i)
|
||||||
case KeyTypeText:
|
case KeyTypeText:
|
||||||
table.calcColText(col, i)
|
table.calcColText(col, i)
|
||||||
case KeyTypeNumber:
|
case KeyTypeNumber:
|
||||||
|
|
@ -379,7 +381,7 @@ func (table *Table) CalcCols() {
|
||||||
func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
switch col.Calc.Operator {
|
switch col.Calc.Operator {
|
||||||
case CalcOperatorCountAll:
|
case CalcOperatorCountAll:
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountValues:
|
case CalcOperatorCountValues:
|
||||||
countValues := 0
|
countValues := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -387,7 +389,7 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
countValues += len(row.Cells[colIndex].Value.MSelect)
|
countValues += len(row.Cells[colIndex].Value.MSelect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountUniqueValues:
|
case CalcOperatorCountUniqueValues:
|
||||||
countUniqueValues := 0
|
countUniqueValues := 0
|
||||||
uniqueValues := map[string]bool{}
|
uniqueValues := map[string]bool{}
|
||||||
|
|
@ -401,7 +403,7 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountEmpty:
|
case CalcOperatorCountEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -409,7 +411,7 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountNotEmpty:
|
case CalcOperatorCountNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -417,7 +419,7 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorPercentEmpty:
|
case CalcOperatorPercentEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -425,7 +427,10 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorPercentNotEmpty:
|
case CalcOperatorPercentNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -433,14 +438,17 @@ func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
switch col.Calc.Operator {
|
switch col.Calc.Operator {
|
||||||
case CalcOperatorCountAll:
|
case CalcOperatorCountAll:
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountValues:
|
case CalcOperatorCountValues:
|
||||||
countValues := 0
|
countValues := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -448,7 +456,7 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countValues++
|
countValues++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountUniqueValues:
|
case CalcOperatorCountUniqueValues:
|
||||||
countUniqueValues := 0
|
countUniqueValues := 0
|
||||||
uniqueValues := map[string]bool{}
|
uniqueValues := map[string]bool{}
|
||||||
|
|
@ -458,7 +466,7 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countUniqueValues++
|
countUniqueValues++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountEmpty:
|
case CalcOperatorCountEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -466,7 +474,7 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountNotEmpty:
|
case CalcOperatorCountNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -474,7 +482,7 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorPercentEmpty:
|
case CalcOperatorPercentEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -482,7 +490,10 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: false}}
|
||||||
|
}
|
||||||
case CalcOperatorPercentNotEmpty:
|
case CalcOperatorPercentNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -490,14 +501,17 @@ func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
switch col.Calc.Operator {
|
switch col.Calc.Operator {
|
||||||
case CalcOperatorCountAll:
|
case CalcOperatorCountAll:
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountValues:
|
case CalcOperatorCountValues:
|
||||||
countValues := 0
|
countValues := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -505,7 +519,7 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
countValues++
|
countValues++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountUniqueValues:
|
case CalcOperatorCountUniqueValues:
|
||||||
countUniqueValues := 0
|
countUniqueValues := 0
|
||||||
uniqueValues := map[int64]bool{}
|
uniqueValues := map[int64]bool{}
|
||||||
|
|
@ -517,7 +531,7 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountEmpty:
|
case CalcOperatorCountEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -525,7 +539,7 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountNotEmpty:
|
case CalcOperatorCountNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -533,7 +547,7 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorPercentEmpty:
|
case CalcOperatorPercentEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -541,7 +555,10 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorPercentNotEmpty:
|
case CalcOperatorPercentNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -549,7 +566,10 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorEarliest:
|
case CalcOperatorEarliest:
|
||||||
earliest := int64(0)
|
earliest := int64(0)
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -596,7 +616,7 @@ func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||||
func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
switch col.Calc.Operator {
|
switch col.Calc.Operator {
|
||||||
case CalcOperatorCountAll:
|
case CalcOperatorCountAll:
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountValues:
|
case CalcOperatorCountValues:
|
||||||
countValues := 0
|
countValues := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -604,7 +624,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
countValues++
|
countValues++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountUniqueValues:
|
case CalcOperatorCountUniqueValues:
|
||||||
countUniqueValues := 0
|
countUniqueValues := 0
|
||||||
uniqueValues := map[float64]bool{}
|
uniqueValues := map[float64]bool{}
|
||||||
|
|
@ -616,7 +636,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountEmpty:
|
case CalcOperatorCountEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -624,7 +644,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountNotEmpty:
|
case CalcOperatorCountNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -632,7 +652,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorPercentEmpty:
|
case CalcOperatorPercentEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -640,7 +660,10 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorPercentNotEmpty:
|
case CalcOperatorPercentNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -648,7 +671,10 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorSum:
|
case CalcOperatorSum:
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -656,7 +682,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
sum += row.Cells[colIndex].Value.Number.Content
|
sum += row.Cells[colIndex].Value.Number.Content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: sum}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: sum, IsNotEmpty: true}}
|
||||||
case CalcOperatorAverage:
|
case CalcOperatorAverage:
|
||||||
sum := 0.0
|
sum := 0.0
|
||||||
count := 0
|
count := 0
|
||||||
|
|
@ -667,9 +693,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if 0 != count {
|
if 0 != count {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: sum / float64(count)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: sum / float64(count), IsNotEmpty: true}}
|
||||||
} else {
|
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: 0}}
|
|
||||||
}
|
}
|
||||||
case CalcOperatorMedian:
|
case CalcOperatorMedian:
|
||||||
values := []float64{}
|
values := []float64{}
|
||||||
|
|
@ -681,12 +705,10 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
sort.Float64s(values)
|
sort.Float64s(values)
|
||||||
if len(values) > 0 {
|
if len(values) > 0 {
|
||||||
if len(values)%2 == 0 {
|
if len(values)%2 == 0 {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: (values[len(values)/2-1] + values[len(values)/2]) / 2}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: (values[len(values)/2-1] + values[len(values)/2]) / 2, IsNotEmpty: true}}
|
||||||
} else {
|
} else {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: values[len(values)/2]}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: values[len(values)/2], IsNotEmpty: true}}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{IsNotEmpty: false}}
|
|
||||||
}
|
}
|
||||||
case CalcOperatorMin:
|
case CalcOperatorMin:
|
||||||
min := math.MaxFloat64
|
min := math.MaxFloat64
|
||||||
|
|
@ -698,9 +720,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if math.MaxFloat64 != min {
|
if math.MaxFloat64 != min {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: min}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: min, IsNotEmpty: true}}
|
||||||
} else {
|
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{IsNotEmpty: false}}
|
|
||||||
}
|
}
|
||||||
case CalcOperatorMax:
|
case CalcOperatorMax:
|
||||||
max := -math.MaxFloat64
|
max := -math.MaxFloat64
|
||||||
|
|
@ -712,9 +732,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if -math.MaxFloat64 != max {
|
if -math.MaxFloat64 != max {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: max}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: max, IsNotEmpty: true}}
|
||||||
} else {
|
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{IsNotEmpty: false}}
|
|
||||||
}
|
}
|
||||||
case CalcOperatorRange:
|
case CalcOperatorRange:
|
||||||
min := math.MaxFloat64
|
min := math.MaxFloat64
|
||||||
|
|
@ -730,9 +748,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if math.MaxFloat64 != min && -math.MaxFloat64 != max {
|
if math.MaxFloat64 != min && -math.MaxFloat64 != max {
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: max - min}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: max - min, IsNotEmpty: true}}
|
||||||
} else {
|
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{IsNotEmpty: false}}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -740,7 +756,7 @@ func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||||
func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
switch col.Calc.Operator {
|
switch col.Calc.Operator {
|
||||||
case CalcOperatorCountAll:
|
case CalcOperatorCountAll:
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountValues:
|
case CalcOperatorCountValues:
|
||||||
countValues := 0
|
countValues := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -748,7 +764,7 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
countValues++
|
countValues++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountUniqueValues:
|
case CalcOperatorCountUniqueValues:
|
||||||
countUniqueValues := 0
|
countUniqueValues := 0
|
||||||
uniqueValues := map[string]bool{}
|
uniqueValues := map[string]bool{}
|
||||||
|
|
@ -760,7 +776,7 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountEmpty:
|
case CalcOperatorCountEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -768,7 +784,7 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorCountNotEmpty:
|
case CalcOperatorCountNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -776,7 +792,7 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty)}}
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
case CalcOperatorPercentEmpty:
|
case CalcOperatorPercentEmpty:
|
||||||
countEmpty := 0
|
countEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -784,7 +800,10 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
countEmpty++
|
countEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
case CalcOperatorPercentNotEmpty:
|
case CalcOperatorPercentNotEmpty:
|
||||||
countNotEmpty := 0
|
countNotEmpty := 0
|
||||||
for _, row := range table.Rows {
|
for _, row := range table.Rows {
|
||||||
|
|
@ -792,6 +811,89 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||||
countNotEmpty++
|
countNotEmpty++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty) / float64(len(table.Rows))}}
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (table *Table) calcColBlock(col *TableColumn, colIndex int) {
|
||||||
|
switch col.Calc.Operator {
|
||||||
|
case CalcOperatorCountAll:
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows)), IsNotEmpty: true}}
|
||||||
|
case CalcOperatorCountValues:
|
||||||
|
countValues := 0
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Block && "" != row.Cells[colIndex].Value.Block.Content {
|
||||||
|
countValues++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countValues), IsNotEmpty: true}}
|
||||||
|
case CalcOperatorCountUniqueValues:
|
||||||
|
countUniqueValues := 0
|
||||||
|
uniqueValues := map[string]bool{}
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Block && "" != row.Cells[colIndex].Value.Block.Content {
|
||||||
|
if !uniqueValues[row.Cells[colIndex].Value.Block.Content] {
|
||||||
|
uniqueValues[row.Cells[colIndex].Value.Block.Content] = true
|
||||||
|
countUniqueValues++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countUniqueValues), IsNotEmpty: true}}
|
||||||
|
case CalcOperatorCountEmpty:
|
||||||
|
countEmpty := 0
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil == row.Cells[colIndex] || nil == row.Cells[colIndex].Value || nil == row.Cells[colIndex].Value.Block || "" == row.Cells[colIndex].Value.Block.Content {
|
||||||
|
countEmpty++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countEmpty), IsNotEmpty: true}}
|
||||||
|
case CalcOperatorCountNotEmpty:
|
||||||
|
countNotEmpty := 0
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Block && "" != row.Cells[colIndex].Value.Block.Content {
|
||||||
|
countNotEmpty++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(countNotEmpty), IsNotEmpty: true}}
|
||||||
|
case CalcOperatorPercentEmpty:
|
||||||
|
countEmpty := 0
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil == row.Cells[colIndex] || nil == row.Cells[colIndex].Value || nil == row.Cells[colIndex].Value.Block || "" == row.Cells[colIndex].Value.Block.Content {
|
||||||
|
countEmpty++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
|
case CalcOperatorPercentNotEmpty:
|
||||||
|
countNotEmpty := 0
|
||||||
|
for _, row := range table.Rows {
|
||||||
|
if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.Block && "" != row.Cells[colIndex].Value.Block.Content {
|
||||||
|
countNotEmpty++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if 0 < len(table.Rows) {
|
||||||
|
content := RoundUp(float64(countNotEmpty)/float64(len(table.Rows))*100, 2)
|
||||||
|
col.Calc.Result = &Value{Number: &ValueNumber{Content: content, IsNotEmpty: true}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundUp rounds like 12.3416 -> 12.35
|
||||||
|
func RoundUp(val float64, precision int) float64 {
|
||||||
|
return math.Ceil(val*(math.Pow10(precision))) / math.Pow10(precision)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RoundDown rounds like 12.3496 -> 12.34
|
||||||
|
func RoundDown(val float64, precision int) float64 {
|
||||||
|
return math.Floor(val*(math.Pow10(precision))) / math.Pow10(precision)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round rounds to nearest like 12.3456 -> 12.35
|
||||||
|
func Round(val float64, precision int) float64 {
|
||||||
|
return math.Round(val*(math.Pow10(precision))) / math.Pow10(precision)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,16 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
notFound := []string{}
|
||||||
|
for blockID, _ := range rows {
|
||||||
|
if treenode.GetBlockTree(blockID) == nil {
|
||||||
|
notFound = append(notFound, blockID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, blockID := range notFound {
|
||||||
|
delete(rows, blockID)
|
||||||
|
}
|
||||||
|
|
||||||
for rowID, row := range rows {
|
for rowID, row := range rows {
|
||||||
var tableRow av.TableRow
|
var tableRow av.TableRow
|
||||||
for _, col := range ret.Columns {
|
for _, col := range ret.Columns {
|
||||||
|
|
|
||||||
|
|
@ -722,9 +722,44 @@ func (tx *Transaction) doDelete(operation *Operation) (ret *TxErr) {
|
||||||
if err = tx.writeTree(tree); nil != err {
|
if err = tx.writeTree(tree); nil != err {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncDelete2AttributeView(node)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func syncDelete2AttributeView(node *ast.Node) {
|
||||||
|
avs := node.IALAttr(NodeAttrNameAVs)
|
||||||
|
if "" == avs {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
avIDs := strings.Split(avs, ",")
|
||||||
|
for _, avID := range avIDs {
|
||||||
|
attrView, parseErr := av.ParseAttributeView(avID)
|
||||||
|
if nil != parseErr {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
changedAv := false
|
||||||
|
blockValues := attrView.GetBlockKeyValues()
|
||||||
|
if nil == blockValues {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, blockValue := range blockValues.Values {
|
||||||
|
if blockValue.Block.ID == node.ID {
|
||||||
|
blockValues.Values = append(blockValues.Values[:i], blockValues.Values[i+1:]...)
|
||||||
|
changedAv = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if changedAv {
|
||||||
|
av.SaveAttributeView(attrView)
|
||||||
|
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": avID})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
|
func (tx *Transaction) doInsert(operation *Operation) (ret *TxErr) {
|
||||||
var err error
|
var err error
|
||||||
opParentID := operation.ParentID
|
opParentID := operation.ParentID
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue