func (b *ValueBuffer) TrimExcess() {
	threshold := float64(len(b.array)) * 0.9
	if b.size < int(threshold) {
		b.SetCapacity(b.size)
	}
}
TrimExcess resizes the capacity of the buffer to better fit the contents.
package chart
import (
	"fmt"
	"strings"
)
const (
	bufferMinimumGrow     = 4
	bufferShrinkThreshold = 32
	bufferGrowFactor      = 200
	bufferDefaultCapacity = 4
)
func NewValueBuffer(values ...float64) *ValueBuffer {
	var tail int
	array := make([]float64, MaxInt(len(values), bufferDefaultCapacity))
	if len(values) > 0 {
		copy(array, values)
		tail = len(values)
	}
	return &ValueBuffer{
		array: array,
		head:  0,
		tail:  tail,
		size:  len(values),
	}
}
func NewValueBufferWithCapacity(capacity int) *ValueBuffer {
	return &ValueBuffer{
		array: make([]float64, capacity),
		head:  0,
		tail:  0,
		size:  0,
	}
}
type ValueBuffer struct {
	array []float64
	head  int
	tail  int
	size  int
}
func (b *ValueBuffer) Len() int {
	return b.size
}
func (b *ValueBuffer) GetValue(index int) float64 {
	effectiveIndex := (b.head + index) % len(b.array)
	return b.array[effectiveIndex]
}
func (b *ValueBuffer) Capacity() int {
	return len(b.array)
}
func (b *ValueBuffer) SetCapacity(capacity int) {
	newArray := make([]float64, capacity)
	if b.size > 0 {
		if b.head < b.tail {
			arrayCopy(b.array, b.head, newArray, 0, b.size)
		} else {
			arrayCopy(b.array, b.head, newArray, 0, len(b.array)-b.head)
			arrayCopy(b.array, 0, newArray, len(b.array)-b.head, b.tail)
		}
	}
	b.array = newArray
	b.head = 0
	if b.size == capacity {
		b.tail = 0
	} else {
		b.tail = b.size
	}
}
func (b *ValueBuffer) Clear() {
	b.array = make([]float64, bufferDefaultCapacity)
	b.head = 0
	b.tail = 0
	b.size = 0
}
func (b *ValueBuffer) Enqueue(value float64) {
	if b.size == len(b.array) {
		newCapacity := int(len(b.array) * int(bufferGrowFactor/100))
		if newCapacity < (len(b.array) + bufferMinimumGrow) {
			newCapacity = len(b.array) + bufferMinimumGrow
		}
		b.SetCapacity(newCapacity)
	}
	b.array[b.tail] = value
	b.tail = (b.tail + 1) % len(b.array)
	b.size++
}
func (b *ValueBuffer) Dequeue() float64 {
	if b.size == 0 {
		return 0
	}
	removed := b.array[b.head]
	b.head = (b.head + 1) % len(b.array)
	b.size--
	return removed
}
func (b *ValueBuffer) Peek() float64 {
	if b.size == 0 {
		return 0
	}
	return b.array[b.head]
}
func (b *ValueBuffer) PeekBack() float64 {
	if b.size == 0 {
		return 0
	}
	if b.tail == 0 {
		return b.array[len(b.array)-1]
	}
	return b.array[b.tail-1]
}