added legend values calculation
This commit is contained in:
parent
88a935d6d3
commit
1b7f851174
|
@ -20,7 +20,7 @@ runcharts:
|
||||||
beep: true
|
beep: true
|
||||||
legend:
|
legend:
|
||||||
enabled: true
|
enabled: true
|
||||||
details: false
|
details: true
|
||||||
position:
|
position:
|
||||||
x: 0
|
x: 0
|
||||||
y: 0
|
y: 0
|
||||||
|
@ -47,7 +47,7 @@ runcharts:
|
||||||
beep: true
|
beep: true
|
||||||
legend:
|
legend:
|
||||||
enabled: true
|
enabled: true
|
||||||
details: true
|
details: false
|
||||||
position:
|
position:
|
||||||
x: 0
|
x: 0
|
||||||
y: 15
|
y: 15
|
||||||
|
|
|
@ -13,6 +13,8 @@ const (
|
||||||
heightOnDefault = 2
|
heightOnDefault = 2
|
||||||
heightOnPinpoint = 4
|
heightOnPinpoint = 4
|
||||||
heightOnDetails = 6
|
heightOnDetails = 6
|
||||||
|
|
||||||
|
timeFormat = "15:04:05.000"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Legend struct {
|
type Legend struct {
|
||||||
|
@ -36,7 +38,7 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
|
|
||||||
rowCount := (c.Dx() - yAxisLegendIndent) / (height + yAxisLegendIndent)
|
rowCount := (c.Dx() - yAxisLegendIndent) / (height + yAxisLegendIndent)
|
||||||
columnCount := int(math.Ceil(float64(len(c.lines)) / float64(rowCount)))
|
columnCount := int(math.Ceil(float64(len(c.lines)) / float64(rowCount)))
|
||||||
columnWidth := getColumnWidth(c.lines, c.precision)
|
columnWidth := getColumnWidth(c.mode, c.lines, c.precision)
|
||||||
|
|
||||||
for col := 0; col < columnCount; col++ {
|
for col := 0; col < columnCount; col++ {
|
||||||
for row := 0; row < rowCount; row++ {
|
for row := 0; row < rowCount; row++ {
|
||||||
|
@ -47,7 +49,6 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
line := c.lines[row+rowCount*col]
|
line := c.lines[row+rowCount*col]
|
||||||
extrema := getLineValueExtrema(line.points)
|
|
||||||
|
|
||||||
x := c.Inner.Max.X - (columnWidth+xAxisLegendIndent)*(col+1)
|
x := c.Inner.Max.X - (columnWidth+xAxisLegendIndent)*(col+1)
|
||||||
y := c.Inner.Min.Y + yAxisLegendIndent + row*height
|
y := c.Inner.Min.Y + yAxisLegendIndent + row*height
|
||||||
|
@ -59,6 +60,8 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
buffer.SetString(line.label, titleStyle, image.Pt(x, y))
|
buffer.SetString(line.label, titleStyle, image.Pt(x, y))
|
||||||
|
|
||||||
if c.mode == ModePinpoint {
|
if c.mode == ModePinpoint {
|
||||||
|
buffer.SetString(fmt.Sprintf("time %s", line.selectionPoint.time.Format("15:04:05.000")), detailsStyle, image.Pt(x, y+1))
|
||||||
|
buffer.SetString(fmt.Sprintf("value %s", formatValue(line.selectionPoint.value, c.precision)), detailsStyle, image.Pt(x, y+2))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,10 +70,10 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
details := [4]string{
|
details := [4]string{
|
||||||
fmt.Sprintf("cur %s", formatValue(line.points[len(line.points)-1].value, c.precision)),
|
fmt.Sprintf("cur %s", formatValue(getCurrentValue(line), c.precision)),
|
||||||
fmt.Sprintf("max %s", formatValue(extrema.max, c.precision)),
|
fmt.Sprintf("max %s", formatValue(line.extrema.max, c.precision)),
|
||||||
fmt.Sprintf("min %s", formatValue(extrema.min, c.precision)),
|
fmt.Sprintf("min %s", formatValue(line.extrema.min, c.precision)),
|
||||||
fmt.Sprintf("dif %s", formatValue(1, c.precision)),
|
fmt.Sprintf("dif %s", formatValue(getDiffWithPreviousValue(line), c.precision)),
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, detail := range details {
|
for i, detail := range details {
|
||||||
|
@ -80,7 +83,12 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getColumnWidth(lines []TimeLine, precision int) int {
|
func getColumnWidth(mode Mode, lines []TimeLine, precision int) int {
|
||||||
|
|
||||||
|
if mode == ModePinpoint {
|
||||||
|
return len(timeFormat)
|
||||||
|
}
|
||||||
|
|
||||||
width := len(formatValue(0, precision))
|
width := len(formatValue(0, precision))
|
||||||
for _, line := range lines {
|
for _, line := range lines {
|
||||||
if len(line.label) > width {
|
if len(line.label) > width {
|
||||||
|
@ -90,23 +98,14 @@ func getColumnWidth(lines []TimeLine, precision int) int {
|
||||||
return width
|
return width
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove and use the one from line
|
func getDiffWithPreviousValue(line TimeLine) float64 {
|
||||||
func getLineValueExtrema(points []TimePoint) ValueExtrema {
|
if len(line.points) < 2 {
|
||||||
|
return 0
|
||||||
if len(points) == 0 {
|
} else {
|
||||||
return ValueExtrema{0, 0}
|
return math.Abs(line.points[len(line.points)-1].value - line.points[len(line.points)-2].value)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
var max, min = -math.MaxFloat64, math.MaxFloat64
|
|
||||||
|
func getCurrentValue(line TimeLine) float64 {
|
||||||
for _, point := range points {
|
return line.points[len(line.points)-1].value
|
||||||
if point.value > max {
|
|
||||||
max = point.value
|
|
||||||
}
|
|
||||||
if point.value < min {
|
|
||||||
min = point.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ValueExtrema{max: max, min: min}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,11 +53,12 @@ type TimePoint struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeLine struct {
|
type TimeLine struct {
|
||||||
points []TimePoint
|
points []TimePoint
|
||||||
extrema ValueExtrema
|
extrema ValueExtrema
|
||||||
color ui.Color
|
color ui.Color
|
||||||
label string
|
label string
|
||||||
selection int
|
selectionCoordinate int
|
||||||
|
selectionPoint TimePoint
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeRange struct {
|
type TimeRange struct {
|
||||||
|
@ -130,15 +131,25 @@ func (c *RunChart) ConsumeSample(sample data.Sample) {
|
||||||
|
|
||||||
if lineIndex == -1 {
|
if lineIndex == -1 {
|
||||||
line := &TimeLine{
|
line := &TimeLine{
|
||||||
points: []TimePoint{},
|
points: []TimePoint{},
|
||||||
color: sample.Color,
|
color: sample.Color,
|
||||||
label: sample.Label,
|
label: sample.Label,
|
||||||
|
extrema: ValueExtrema{max: float, min: float},
|
||||||
}
|
}
|
||||||
c.lines = append(c.lines, *line)
|
c.lines = append(c.lines, *line)
|
||||||
lineIndex = len(c.lines) - 1
|
lineIndex = len(c.lines) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
line := c.lines[lineIndex]
|
line := c.lines[lineIndex]
|
||||||
|
|
||||||
|
if float < line.extrema.min {
|
||||||
|
line.extrema.min = float
|
||||||
|
}
|
||||||
|
|
||||||
|
if float > line.extrema.max {
|
||||||
|
line.extrema.max = float
|
||||||
|
}
|
||||||
|
|
||||||
timePoint := c.newTimePoint(float)
|
timePoint := c.newTimePoint(float)
|
||||||
line.points = append(line.points, timePoint)
|
line.points = append(line.points, timePoint)
|
||||||
c.lines[lineIndex] = line
|
c.lines[lineIndex] = line
|
||||||
|
@ -167,9 +178,10 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) {
|
||||||
xPoint := make(map[int]image.Point)
|
xPoint := make(map[int]image.Point)
|
||||||
xOrder := make([]int, 0)
|
xOrder := make([]int, 0)
|
||||||
|
|
||||||
if line.selection != 0 {
|
// move selection on a delta, if it was instantiated after cursor move
|
||||||
line.selection -= delta
|
if line.selectionCoordinate != 0 {
|
||||||
c.lines[i].selection = line.selection
|
line.selectionCoordinate -= delta
|
||||||
|
c.lines[i].selectionCoordinate = line.selectionCoordinate
|
||||||
}
|
}
|
||||||
|
|
||||||
for j, timePoint := range line.points {
|
for j, timePoint := range line.points {
|
||||||
|
@ -195,14 +207,14 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if line.selection == 0 {
|
if line.selectionCoordinate == 0 {
|
||||||
|
// instantiate selection coordinate as the closest point to the cursor time
|
||||||
if len(line.points) > j+1 && ui.AbsInt(timePoint.coordinate-selectionCoordinate) > ui.AbsInt(line.points[j+1].coordinate-selectionCoordinate) {
|
if len(line.points) > j+1 && ui.AbsInt(timePoint.coordinate-selectionCoordinate) > ui.AbsInt(line.points[j+1].coordinate-selectionCoordinate) {
|
||||||
selectionPoints[i] = point
|
selectionPoints[i] = point
|
||||||
|
c.lines[i].selectionPoint = timePoint
|
||||||
}
|
}
|
||||||
} else {
|
} else if timePoint.coordinate == line.selectionCoordinate {
|
||||||
if timePoint.coordinate == line.selection {
|
selectionPoints[i] = point
|
||||||
selectionPoints[i] = point
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
xPoint[point.X] = point
|
xPoint[point.X] = point
|
||||||
|
@ -233,8 +245,8 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) {
|
||||||
if c.mode == ModePinpoint {
|
if c.mode == ModePinpoint {
|
||||||
for lineIndex, point := range selectionPoints {
|
for lineIndex, point := range selectionPoints {
|
||||||
buffer.SetCell(ui.NewCell(console.SymbolSelection, ui.NewStyle(c.lines[lineIndex].color)), point)
|
buffer.SetCell(ui.NewCell(console.SymbolSelection, ui.NewStyle(c.lines[lineIndex].color)), point)
|
||||||
if c.lines[lineIndex].selection == 0 {
|
if c.lines[lineIndex].selectionCoordinate == 0 {
|
||||||
c.lines[lineIndex].selection = point.X
|
c.lines[lineIndex].selectionCoordinate = point.X
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -299,7 +311,7 @@ func (c *RunChart) MoveSelection(shift int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range c.lines {
|
for i := range c.lines {
|
||||||
c.lines[i].selection = 0
|
c.lines[i].selectionCoordinate = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue