Sparkline Hover Value

Is there any way to show the value when hovering over a sparkline chart? This would be especially useful for at least the min and max values, which can have special markers.

I imagine that this could easily be done with scripting using the mouseMoved event handler.

Example:
If the data in for the chart is polled at a constant rate, then it would be simple to use the mouse cursor's relative position on the x axis to find the appropriate row in the chart's dataset like this:

# Written for the mouseMoved event handler

# Convert the mouse's location along the x-axis to a percentage
relativeLocation = event.x / float(event.source.width) 

# Use that percentage to get the relative data point from the chart's dataset
row = int(event.source.data.rowCount * relativeLocation)

# Store the retrieved value in the tooltip text
event.source.toolTipText = unicode(event.source.data.getValueAt(row, 'value'))

However, if the polling rate can vary, then the value would need to be obtained using the mouse position along the x axis relative to the date range. It's slightly more complex but still relatively straightforward:

# Written for the mouseMoved event handler

# Convert the mouse's location along the x-axis to a percentage
relativeLocation = event.x / float(event.source.width) 

# Get the date range from the dataset
data = event.source.data
maxRow = data.rowCount - 1
startTime = data.getValueAt(0, 't_stamp')
endTime = data.getValueAt(maxRow, 't_stamp')
dateRange = system.date.millisBetween(startTime, endTime)

# Calculate the approximate date of the pointer location
relativeMillis = int(dateRange * relativeLocation)
datePosition = system.date.addMillis(startTime, relativeMillis)

# Iterate through the dataset values, locate appropriate row, and assign its value to the tooltip text
for row in xrange(data.rowCount):
	nextRow = min(row + 1, maxRow)
	if data.getValueAt(row, 't_stamp') <= datePosition <= data.getValueAt(nextRow, 't_stamp'):
		event.source.toolTipText = unicode(data.getValueAt(row, 'value'))
		break
	elif row == maxRow:
		event.source.toolTipText = unicode(data.getValueAt(row, 'value'))

Result:
image

5 Likes

Thanks! That's exactly what I need. It is static, so the first solution will do

1 Like

I was also hoping to limit it based on the remainder, to limit where the tooltip is set to within like ~10% of the row, but the relative positions don't seem to be that accurate

I'm not sure what this means. If you're talking about pixels above or below the line, this could be done with the chart's minValue and maxValue properties. All you would have to do is write a blank string or a null value to the tool tip text when the cursor is out of range.

I could probably throw it together pretty quick, but I have to get a trailer load of wood stacked before the rain hits this morning.

2 Likes

Not up/down but left/right. So, at row "4.5" the tooltip is nothing. Between rows "4.95" and "5.05" the tooltip is the value for row 5. Basically, limiting the tooltip to only show up close to the value for the row. My attempt to do this is the commented out if statement below. It ends up between the rows, but not a big deal, I just won't use it. (seems like it uses the right side of the cursor for the x position?)

Also, the values being displayed in my case are floats, so I've added some number formatting.

def sparklineValueTooltipStatic(event, decimals = 1):
	'''
		Set the tooltip text for a sparkline who's dataset date range is static.
		
		Args:
			event		(event obj)	:	sparkline's mouseMoved() event handler
			decimals	(int)		:	number of digits to include after the decimal
		
		Returns:
			n/a
			*event.source.toolTipText
	'''
	#get the relative x location
	relativeLocation = event.x / float(event.source.width)
	
	#calculate the equivalent row
	row = event.source.data.rowCount * relativeLocation
	
	#set the tooltip to the row value
	#if ( row % 1 > 0.9 ) or ( row % 1 < 0.1 ):
	formatString = '%.1f'.replace('1',str(decimals))
	text = formatString % float( event.source.data.getValueAt(int(row),'value') )
	
	#else:
		#text = ''
	
	event.source.toolTipText = text
2 Likes

Part of the problem could be that I didn't take into consideration that the rows are zero indexed. Try subtracting 1 from the rowCount property to see if that improves the calibration. Also, I'm pretty sure my test data had a data point for every pixel, so I wouldn't have noticed any precision issues. There's no way to fractionally position on a pixel

No, that's not it because the remainder for relative position would be unchanged and you'd shift a row. I did try it, and my max of 24 was showing 24 before, but now it's showing the point before it, which is 2.

Of course not

1 Like