From 1b7f851174b5c047b68dae040310c489e3b56b30 Mon Sep 17 00:00:00 2001 From: sqshq Date: Fri, 15 Feb 2019 21:52:03 -0500 Subject: [PATCH] added legend values calculation --- config.yml | 4 +-- widgets/runchart/legend.go | 49 +++++++++++++++++------------------ widgets/runchart/runchart.go | 50 ++++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 46 deletions(-) diff --git a/config.yml b/config.yml index 76f6e05..4b82df3 100644 --- a/config.yml +++ b/config.yml @@ -20,7 +20,7 @@ runcharts: beep: true legend: enabled: true - details: false + details: true position: x: 0 y: 0 @@ -47,7 +47,7 @@ runcharts: beep: true legend: enabled: true - details: true + details: false position: x: 0 y: 15 diff --git a/widgets/runchart/legend.go b/widgets/runchart/legend.go index 45e2763..b9b45ba 100644 --- a/widgets/runchart/legend.go +++ b/widgets/runchart/legend.go @@ -13,6 +13,8 @@ const ( heightOnDefault = 2 heightOnPinpoint = 4 heightOnDetails = 6 + + timeFormat = "15:04:05.000" ) type Legend struct { @@ -36,7 +38,7 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) { rowCount := (c.Dx() - yAxisLegendIndent) / (height + yAxisLegendIndent) 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 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] - extrema := getLineValueExtrema(line.points) x := c.Inner.Max.X - (columnWidth+xAxisLegendIndent)*(col+1) 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)) 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 } @@ -67,10 +70,10 @@ func (c *RunChart) renderLegend(buffer *ui.Buffer, rectangle image.Rectangle) { } details := [4]string{ - fmt.Sprintf("cur %s", formatValue(line.points[len(line.points)-1].value, c.precision)), - fmt.Sprintf("max %s", formatValue(extrema.max, c.precision)), - fmt.Sprintf("min %s", formatValue(extrema.min, c.precision)), - fmt.Sprintf("dif %s", formatValue(1, c.precision)), + fmt.Sprintf("cur %s", formatValue(getCurrentValue(line), c.precision)), + fmt.Sprintf("max %s", formatValue(line.extrema.max, c.precision)), + fmt.Sprintf("min %s", formatValue(line.extrema.min, c.precision)), + fmt.Sprintf("dif %s", formatValue(getDiffWithPreviousValue(line), c.precision)), } 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)) for _, line := range lines { if len(line.label) > width { @@ -90,23 +98,14 @@ func getColumnWidth(lines []TimeLine, precision int) int { return width } -// TODO remove and use the one from line -func getLineValueExtrema(points []TimePoint) ValueExtrema { - - if len(points) == 0 { - return ValueExtrema{0, 0} +func getDiffWithPreviousValue(line TimeLine) float64 { + if len(line.points) < 2 { + return 0 + } else { + return math.Abs(line.points[len(line.points)-1].value - line.points[len(line.points)-2].value) } - - var max, min = -math.MaxFloat64, math.MaxFloat64 - - for _, point := range points { - if point.value > max { - max = point.value - } - if point.value < min { - min = point.value - } - } - - return ValueExtrema{max: max, min: min} +} + +func getCurrentValue(line TimeLine) float64 { + return line.points[len(line.points)-1].value } diff --git a/widgets/runchart/runchart.go b/widgets/runchart/runchart.go index 7ab0a19..3dcf00f 100644 --- a/widgets/runchart/runchart.go +++ b/widgets/runchart/runchart.go @@ -53,11 +53,12 @@ type TimePoint struct { } type TimeLine struct { - points []TimePoint - extrema ValueExtrema - color ui.Color - label string - selection int + points []TimePoint + extrema ValueExtrema + color ui.Color + label string + selectionCoordinate int + selectionPoint TimePoint } type TimeRange struct { @@ -130,15 +131,25 @@ func (c *RunChart) ConsumeSample(sample data.Sample) { if lineIndex == -1 { line := &TimeLine{ - points: []TimePoint{}, - color: sample.Color, - label: sample.Label, + points: []TimePoint{}, + color: sample.Color, + label: sample.Label, + extrema: ValueExtrema{max: float, min: float}, } c.lines = append(c.lines, *line) lineIndex = len(c.lines) - 1 } 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) line.points = append(line.points, timePoint) c.lines[lineIndex] = line @@ -167,9 +178,10 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) { xPoint := make(map[int]image.Point) xOrder := make([]int, 0) - if line.selection != 0 { - line.selection -= delta - c.lines[i].selection = line.selection + // move selection on a delta, if it was instantiated after cursor move + if line.selectionCoordinate != 0 { + line.selectionCoordinate -= delta + c.lines[i].selectionCoordinate = line.selectionCoordinate } for j, timePoint := range line.points { @@ -195,14 +207,14 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) { 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) { selectionPoints[i] = point + c.lines[i].selectionPoint = timePoint } - } else { - if timePoint.coordinate == line.selection { - selectionPoints[i] = point - } + } else if timePoint.coordinate == line.selectionCoordinate { + selectionPoints[i] = point } xPoint[point.X] = point @@ -233,8 +245,8 @@ func (c *RunChart) renderLines(buffer *ui.Buffer, drawArea image.Rectangle) { if c.mode == ModePinpoint { for lineIndex, point := range selectionPoints { buffer.SetCell(ui.NewCell(console.SymbolSelection, ui.NewStyle(c.lines[lineIndex].color)), point) - if c.lines[lineIndex].selection == 0 { - c.lines[lineIndex].selection = point.X + if c.lines[lineIndex].selectionCoordinate == 0 { + c.lines[lineIndex].selectionCoordinate = point.X } } } @@ -299,7 +311,7 @@ func (c *RunChart) MoveSelection(shift int) { } for i := range c.lines { - c.lines[i].selection = 0 + c.lines[i].selectionCoordinate = 0 } }