module Webglimpse { export interface TimeseriesCursorPainterOptions { font ? : string ; textColor ? : Color ; buffer_px ? : number ; textDecimals ? : number ; lineColor ? : Color ; crosshairThickness_px ? : number ; boxSize_px ? : number ; boxThickness_px ? : number ; } export function newTimeseriesCursorPainterFactory ( cursorOptions ? ) { return function ( drawable , timeAxis , dataAxis , model , rowModel , ui , options ) : Painter { var textColor = ( hasval ( cursorOptions ) && hasval ( cursorOptions . textColor ) ? cursorOptions . textColor : white ) ; var lineColor = ( hasval ( cursorOptions ) && hasval ( cursorOptions . lineColor ) ? cursorOptions . lineColor : white ) ; var font = ( hasval ( cursorOptions ) && hasval ( cursorOptions . font ) ? cursorOptions . font : options . timelineFont ) ; var buffer_px = ( hasval ( cursorOptions ) && hasval ( cursorOptions . buffer_px ) ? cursorOptions . buffer_px : 4 ) ; var textDecimals = ( hasval ( cursorOptions ) && hasval ( cursorOptions . textDecimals ) ? cursorOptions . textDecimals : 2 ) ; var boxSize_px = ( hasval ( cursorOptions ) && hasval ( cursorOptions . boxSize_px ) ? cursorOptions . boxSize_px : 8 ) ; var crosshairThickness_px = ( hasval ( cursorOptions ) && hasval ( cursorOptions . crosshairThickness_px ) ? cursorOptions . boxSize_px : 2 ) ; var boxThickness_px = ( hasval ( cursorOptions ) && hasval ( cursorOptions . boxThickness_px ) ? cursorOptions . boxSize_px : 2 ) ; var program = new Program ( xyFrac_VERTSHADER , solid_FRAGSHADER ) ; var u_Color = new UniformColor ( program , 'u_Color' ) ; var a_Position = new Attribute ( program , 'a_XyFrac' ) ; var xys = new Float32Array ( 0 ) ; xys = ensureCapacityFloat32 ( xys , 4 ) ; var xysBuffer = newDynamicBuffer ( ) ; var textTextures = newTextTextureCache2 ( font ) ; var textureRenderer = new TextureRenderer ( ) ; return function ( gl , viewport ) { var hoveredRow = ui . selection . hoveredRow . value ; if ( ! hasval ( hoveredRow ) || hoveredRow . rowGuid !== rowModel . rowGuid ) return ; gl . blendFuncSeparate ( GL . SRC_ALPHA , GL . ONE_MINUS_SRC_ALPHA , GL . ONE , GL . ONE_MINUS_SRC_ALPHA ) ; gl . enable ( GL . BLEND ) ; var indexXys = 0 ; textTextures . resetTouches ( ) ; var time = ui . selection . hoveredTime_PMILLIS . value ; var y = ui . selection . hoveredY . value ; if ( ! hasval ( time ) || ! hasval ( y ) ) return ; var wLine = crosshairThickness_px / viewport . w ; var hLine = crosshairThickness_px / viewport . h ; var wBoxLine = boxThickness_px / viewport . w ; var hBoxLine = boxThickness_px / viewport . h ; var wBox = boxSize_px / viewport . w ; var hBox = boxSize_px / viewport . h ; if ( hasval ( time ) ) { var cursorModel = model . cursor ( rowModel . cursorGuid ) ; if ( hasval ( cursorModel ) ) { if ( hasval ( cursorModel . lineColor ) ) { lineColor = cursorModel . lineColor ; } if ( hasval ( cursorModel . textColor ) ) { textColor = cursorModel . textColor ; } textureRenderer . begin ( gl , viewport ) ; var timeseriesCount = cursorModel . labeledTimeseriesGuids . length ; xys = ensureCapacityFloat32 ( xys , 2 * ( 36 + timeseriesCount * 48 ) ) ; for ( var i = 0 ; i < cursorModel . labeledTimeseriesGuids . length ; i ++ ) { var timeseriesGuid = cursorModel . labeledTimeseriesGuids . valueAt ( i ) ; var timeseries = model . timeseries ( timeseriesGuid ) ; if ( ! rowModel . timeseriesGuids . hasValue ( timeseriesGuid ) ) continue ; for ( var j = 0 ; j < timeseries . fragmentGuids . length ; j ++ ) { var fragmentGuid = timeseries . fragmentGuids . valueAt ( j ) ; var fragment = model . timeseriesFragment ( fragmentGuid ) ; if ( fragment . start_PMILLIS < time && fragment . end_PMILLIS > time ) { var value ; if ( timeseries . uiHint == 'bars' ) { var index = indexAtOrBefore ( fragment . times_PMILLIS , time ) ; value = fragment . data [ index ] ; } else { var index0 = indexAtOrBefore ( fragment . times_PMILLIS , time ) ; var index1 = indexAtOrAfter ( fragment . times_PMILLIS , time ) ; var value0 = fragment . data [ index0 ] ; var time0 = fragment . times_PMILLIS [ index0 ] ; var value1 = fragment . data [ index1 ] ; var time1 = fragment . times_PMILLIS [ index1 ] ; var diff = time1 - time0 ; var diff0 = ( time - time0 ) / diff ; var diff1 = 1 - diff0 ; value = value0 * diff1 + value1 * diff0 ; } var textTexture = textTextures . value ( textColor . rgbaString , value . toFixed ( textDecimals ) ) ; var valueFracY = dataAxis . vFrac ( value ) ; var valueFracX = timeAxis . tFrac ( time ) ; var boxLeft = valueFracX - wBox / 2 ; var boxRight = valueFracX + wBox / 2 ; var boxTop = valueFracY + hBox / 2 ; var boxBottom = valueFracY - hBox / 2 ; indexXys = putQuadXys ( xys , indexXys , boxLeft - wBoxLine / 2 , boxLeft + wBoxLine / 2 , boxTop + hBoxLine / 2 , boxBottom - hBoxLine / 2 ) ; indexXys = putQuadXys ( xys , indexXys , boxRight - wBoxLine / 2 , boxRight + wBoxLine / 2 , boxTop + hBoxLine / 2 , boxBottom - hBoxLine / 2 ) ; indexXys = putQuadXys ( xys , indexXys , boxLeft + wBoxLine / 2 , boxRight - wBoxLine / 2 , boxTop - hBoxLine / 2 , boxTop + hBoxLine / 2 ) ; indexXys = putQuadXys ( xys , indexXys , boxLeft + wBoxLine / 2 , boxRight - wBoxLine / 2 , boxBottom - hBoxLine / 2 , boxBottom + hBoxLine / 2 ) ; textureRenderer . draw ( gl , textTexture , boxRight + wBoxLine / 2 + buffer_px / viewport . w , valueFracY , { xAnchor : 0 , yAnchor : .6 } ) ; } } } if ( hasval ( cursorModel . showCursorText ) ? cursorModel . showCursorText : true ) { var textTexture = textTextures . value ( textColor . rgbaString , y . toFixed ( textDecimals ) ) ; textureRenderer . draw ( gl , textTexture , 1 , dataAxis . vFrac ( y ) + buffer_px / viewport . h , { xAnchor : 1 , yAnchor : 0 } ) ; } textureRenderer . end ( gl ) ; textTextures . retainTouched ( ) ; var xLeft = 0 ; var xRight = 1 ; var yMid = dataAxis . vFrac ( y ) ; var xMid = timeAxis . tFrac ( time ) ; if ( hasval ( cursorModel . showHorizontalLine ) ? cursorModel . showHorizontalLine : true ) { indexXys = putQuadXys ( xys , indexXys , xLeft , xRight , yMid - hLine / 2 , yMid + hLine / 2 ) ; } if ( hasval ( cursorModel . showVerticalLine ) ? cursorModel . showVerticalLine : true ) { indexXys = putQuadXys ( xys , indexXys , xMid - wLine / 2 , xMid + wLine / 2 , 0 , yMid - hLine / 2 ) ; indexXys = putQuadXys ( xys , indexXys , xMid - wLine / 2 , xMid + wLine / 2 , yMid + hLine / 2 , 1 ) ; } program . use ( gl ) ; xysBuffer . setData ( xys . subarray ( 0 , indexXys ) ) ; a_Position . setDataAndEnable ( gl , xysBuffer , 2 , GL . FLOAT ) ; u_Color . setData ( gl , lineColor ) ; gl . drawArrays ( GL . TRIANGLES , 0 , Math . floor ( indexXys / 2 ) ) ; a_Position . disable ( gl ) ; program . endUse ( gl ) ; } } } ; } ; } }