diff --git a/pkg/keyvisual/matrix/axis.go b/pkg/keyvisual/matrix/axis.go index 8346ac6fab..6a05477441 100644 --- a/pkg/keyvisual/matrix/axis.go +++ b/pkg/keyvisual/matrix/axis.go @@ -236,6 +236,61 @@ func (c *chunk) Focus(strategy Strategy, threshold uint64, ratio int, target int } generateBucket(len(c.Values)) + newChunk := createChunk(newKeys, newValues) + if len(newValues) >= target*2 { + newChunk = newChunk.MergeColdLogicalRange(strategy, threshold, target) + } + return newChunk +} + +func (c *chunk) MergeColdLogicalRange(strategy Strategy, threshold uint64, target int) chunk { + threshold /= 4 // TODO: This var can be adjusted + + newKeys := make([]string, 0, target) + newValues := make([]uint64, 0, target) + newKeys = append(newKeys, c.Keys[0]) + + coldStart := 0 + coldEnd := 0 + var coldRangeSum uint64 = 0 + mergeColdRange := func() { + if coldEnd <= coldStart { + return + } + newKeys = append(newKeys, c.Keys[coldEnd]) + newValues = append(newValues, coldRangeSum) + coldStart = coldEnd + coldRangeSum = 0 + } + generateRange := func(end int) { + if end <= coldEnd { + return + } + var rangeSum uint64 = 0 + for i := coldEnd; i < end; i++ { + rangeSum += c.Values[i] + } + if coldRangeSum > threshold || rangeSum > threshold { + mergeColdRange() + } + if rangeSum > threshold { + newKeys = append(newKeys, c.Keys[coldEnd+1:end+1]...) + newValues = append(newValues, c.Values[coldEnd:end]...) + coldStart = end + } else { + coldRangeSum += rangeSum + } + coldEnd = end + } + + for i := range c.Values { + if strategy.CrossBorder(c.Keys[i], c.Keys[i+1]) { + generateRange(i + 1) + } + } + generateRange(len(c.Values)) + mergeColdRange() + return createChunk(newKeys, newValues) }