diff options
author | jaspert <jaspert> | 2019-02-28 15:52:15 (GMT) |
---|---|---|
committer | jaspert <jaspert> | 2019-02-28 15:52:15 (GMT) |
commit | 7883dcdedb3af8454956e7599b139e350dbddfdf (patch) | |
tree | c71b83f34ce0163f89d54bbe2765f589098664a0 /generic/tkScale.c | |
parent | 31b66a6295cd71b19bc085fd8c1b6b660c327ad3 (diff) | |
download | tk-7883dcdedb3af8454956e7599b139e350dbddfdf.zip tk-7883dcdedb3af8454956e7599b139e350dbddfdf.tar.gz tk-7883dcdedb3af8454956e7599b139e350dbddfdf.tar.bz2 |
Added a procedure to increase the number of digits in the tick values until
the maximum rounding error goes below a certain value, currently 0.2x the
tick interval. Also fixed it to work with scales from larger to smaller values.
Diffstat (limited to 'generic/tkScale.c')
-rw-r--r-- | generic/tkScale.c | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/generic/tkScale.c b/generic/tkScale.c index 455c656..95cc399 100644 --- a/generic/tkScale.c +++ b/generic/tkScale.c @@ -759,6 +759,46 @@ ScaleWorldChanged( TkEventuallyRedrawScale(scalePtr, REDRAW_ALL); } + + + /* + *---------------------------------------------------------------------- + * + * MaxTickRoundingError -- + * + * Given the separation between values that can be displayed on ticks, + * this calculates the maximum magnitude of error for the displayed + * value. Tries to be clever by working out the increment in error + * between ticks rather than testing all of them, so may overestimate + * error if it is greater than 0.25 x the value separation. + * + * Results: + * Maximum error magnitude of tick numbers. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static double +MaxTickRoundingError( + TkScale *scalePtr, /* Information about scale widget. */ + double tickResolution) /* Separation between displayable values. */ +{ + double tickPosn, firstTickError, lastTickError, intervalError; + int tickCount; + + tickPosn = scalePtr->fromValue/tickResolution; + firstTickError = tickPosn - round(tickPosn); + tickPosn = scalePtr->tickInterval/tickResolution; + intervalError = tickPosn - round(tickPosn); + tickCount = (int)((scalePtr->toValue-scalePtr->fromValue) / + scalePtr->tickInterval); // not including first + lastTickError = fmin(fabs(firstTickError + tickCount*intervalError), 0.5); + return fmax(fabs(firstTickError),lastTickError)*tickResolution; +} + /* *---------------------------------------------------------------------- @@ -782,7 +822,7 @@ ComputeFormat( TkScale *scalePtr, /* Information about scale widget. */ int forTicks) /* Do for ticks rather than value */ { - double maxValue, x; + double maxValue, x, tickResolution; int mostSigDigit, numDigits, leastSigDigit, afterDecimal; int eDigits, fDigits; @@ -807,8 +847,16 @@ ComputeFormat( * values */ - if (scalePtr->tickInterval > 0) { - numDigits = 1 + mostSigDigit - (int) floor(log10(scalePtr->tickInterval)); + if (scalePtr->tickInterval != 0) { + leastSigDigit = (int) floor(log10(fabs(scalePtr->tickInterval))); + /* + * Now add more digits until max error is less than 0.2 intervals + */ + while (MaxTickRoundingError(scalePtr, pow(10,leastSigDigit)) > + fabs(0.2*scalePtr->tickInterval)) + --leastSigDigit; + + numDigits = 1 + mostSigDigit - leastSigDigit; } else { numDigits = 1; } |