Changeset 5657


Ignore:
Timestamp:
Jan 6, 2008 1:44:13 PM (9 years ago)
Author:
tschaub
Message:

scalebar update

Location:
sandbox/tschaub/scalebar
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • sandbox/tschaub/scalebar/examples/scalebar.html

    r5651 r5657  
    55    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
    66    <style type="text/css">
     7        body {
     8            font-family: sans-serif;
     9            font-size: 0.9em;
     10        }
    711        #map {
    812            width: 512px;
     
    1014            border: 1px solid gray;
    1115        }
     16        #docs {
     17            width: 512px;
     18            margin: 1em 0;
    1219    </style>
    1320    <script src="../lib/OpenLayers.js"></script>
     
    1825        function init(){
    1926
    20             map = new OpenLayers.Map('map', {theme: null});
     27            map = new OpenLayers.Map('map');
    2128
    2229            var layer = new OpenLayers.Layer.WMS(
     
    3441            map.zoomToMaxExtent();
    3542        }
    36         // -->
     43
     44
     45        function updateProperties() {
     46            var displaySystem = document.getElementById("displaySystem").value;
     47            scalebar.displaySystem = displaySystem;
     48            var divEl = document.getElementById("divisions");
     49            var divisions = parseInt(divEl.value);
     50            divisions = Math.max(1, Math.min(isNaN(divisions) ? 0 : divisions, 4));
     51            divEl.value = divisions;
     52            scalebar.divisions = divisions;
     53            var subEl = document.getElementById("subdivisions");
     54            var subdivisions = parseInt(subEl.value);
     55            subdivisions = Math.max(1, Math.min(isNaN(subdivisions) ? 0 : subdivisions, 4));
     56            subEl.value = subdivisions;
     57            scalebar.subdivisions = subdivisions;
     58            scalebar.showMinorMeasures = document.getElementById("showMinorMeasures").checked;
     59            scalebar.singleLine = document.getElementById("singleLine").checked;
     60            scalebar.abbreviateLabel = document.getElementById("abbreviateLabel").checked;
     61            scalebar.update();
     62        }
    3763    </script>
    3864  </head>
     
    4874    <div id="map"></div>
    4975
    50     <div id="docs"></div>
     76    <div id="docs">
     77        Set properties for the scale bar with the options argument for the
     78        constructor.  Scale bar style (including bar color/graphics) is
     79        controlled with CSS.  See the default style.css for scale bar related
     80        selectors.  To use CSS with the scale bar, add your stylesheet
     81        explicitly to your page with a link tag (as with this page).
     82    </div>
     83   
     84    <div>
     85        <p>Update the scale bar with the form elements below.  (In IE, click
     86        away from these form elements to see the scale bar updated.)</p>
     87        <select name="displaySystem" id="displaySystem"
     88                onchange="updateProperties();">
     89            <option value="metric" selected="selected">metric</option>
     90            <option value="english">english</option>
     91        </select>
     92        display system
     93        <br />
     94        <input type="text" id="divisions" maxlength="2" size="2"
     95               onchange="updateProperties();" value="2" />
     96        <label for="divisions">major divisions</label>
     97        <br />
     98        <input type="text" id="subdivisions" maxlength="2" size="2"
     99               onchange="updateProperties();" value="2" />
     100        <label for="divisions">subdivisions per major division</label>
     101        <br />
     102        <input type="checkbox" id="abbreviateLabel"
     103               onchange="updateProperties();" />
     104        <label for="abbreviateLabel">abbreviated label</label>
     105        <br />
     106        <input type="checkbox" id="showMinorMeasures"
     107               onchange="updateProperties();" />
     108        <label for="showMinorMeasures">show subdivision measures (use CSS to reduce font size)</label>
     109        <br />
     110        <input type="checkbox" id="singleLine"
     111               onchange="updateProperties();" />
     112        <label for="singleLine">single line display (best with abbreviated label)</label>
     113        <br />
     114    </div>
    51115  </body>
    52116</html>
  • sandbox/tschaub/scalebar/lib/OpenLayers/Control/ScaleBar.js

    r5656 r5657  
    2323   
    2424    /**
    25      * Property: scaleDenominator
     25     * Property: scale
    2626     * {Float} Scale denominator (1 / X) - set on update
    2727     */   
    28     scaleDenominator: 1,
     28    scale: 1,
    2929
    3030    /**
     
    8383     * left, center, or right supported
    8484     */
    85     align: 'center',
     85    align: 'left',
    8686
    8787    /**
     
    187187        this.element = document.createElement('div');
    188188        this.element.style.position = 'relative';
    189         this.element.style.overflow = 'hidden';
    190189        this.element.className = this.displayClass + 'Wrapper';
    191190        this.labelContainer = document.createElement('div');
     
    201200        this.element.appendChild(this.labelContainer);
    202201        this.element.appendChild(this.numbersContainer);
     202    },
     203   
     204    /**
     205     * APIMethod: destroy
     206     * Destroy the control.
     207     */
     208    destroy: function() {
     209        this.map.events.unregister('moveend', this, this.onMoveend);
     210        this.div.innerHTML = "";
     211        OpenLayers.Control.prototype.destroy.apply(this);
    203212    },
    204213
     
    224233        if(this.singleLine) {
    225234            classNames.push('LabelBoxSingleLine');
    226         }
    227         else {
     235        } else {
    228236            classNames.push('NumbersBox', 'LabelBox');
    229237        }
     
    239247       
    240248        this.div.appendChild(this.element);
    241         this.map.events.register('moveend', this, this.update);
     249        this.map.events.register('moveend', this, this.onMoveend);
    242250        this.update();
    243251        return this.div;
    244252    },
     253   
     254    /**
     255     * Method: onMoveend
     256     * Registered as a listener for "moveend".
     257     */
     258    onMoveend: function() {
     259        this.update();
     260    },
    245261   
    246262    /**
    247263     * APIMethod: update
    248264     * Update the scale bar after modifying properties.
    249      */
    250     update: function() {
     265     *
     266     * Parameters:
     267     * scale - {Float} Optional scale denominator.  If not specified, the
     268     *     map scale will be used.
     269     */
     270    update: function(scale) {
    251271        if(this.map.baseLayer == null || !this.map.getResolution()) {
    252272            return;
    253273        }
    254         this.scaleDenominator = this.map.getScale();
     274        this.scale = (scale != undefined) ? scale : this.map.getScale();
    255275        // update the element title and width
    256         this.element.title = 'scale 1:' + this.formatNumber(this.scaleDenominator);
     276        this.element.title = 'scale 1:' + this.formatNumber(this.scale);
    257277        this.element.style.width = this.maxWidth + 'px';
    258278        // check each measurement unit in the display system
    259         var comparisonArray = new Array();
    260         for(var unitIndex = 0; unitIndex < this.measurementProperties[this.displaySystem].units.length; ++unitIndex) {
    261             comparisonArray[unitIndex] = new Object();
     279        var system = this.measurementProperties[this.displaySystem];
     280        var numUnits = system.units.length;
     281        var comp = new Array(numUnits);
     282        var numDiv = this.divisions * this.subdivisions;
     283        for(var unitIndex = 0; unitIndex < numUnits; ++unitIndex) {
     284            comp[unitIndex] = {};
    262285            var pixelsPerDisplayUnit = OpenLayers.DOTS_PER_INCH *
    263                                        this.measurementProperties[this.displaySystem].inches[unitIndex] /
    264                                        this.scaleDenominator;
     286                                       system.inches[unitIndex] /
     287                                       this.scale;
    265288            var minSDDisplayLength = ((this.minWidth - this.xOffsetNumbersBox) /
    266289                                       pixelsPerDisplayUnit) /
    267                                       (this.divisions * this.subdivisions);
     290                                      (numDiv);
    268291            var maxSDDisplayLength = ((this.maxWidth - this.xOffsetNumbersBox) /
    269292                                       pixelsPerDisplayUnit) /
    270                                       (this.divisions * this.subdivisions);
     293                                      (numDiv);
    271294            // add up scores for each marker (even if numbers aren't displayed)
    272             for(var valueIndex = 0; valueIndex < (this.divisions * this.subdivisions); ++valueIndex) {
     295            for(var valueIndex = 0; valueIndex < (numDiv); ++valueIndex) {
    273296                var minNumber = minSDDisplayLength * (valueIndex + 1);
    274297                var maxNumber = maxSDDisplayLength * (valueIndex + 1);
    275                 var niceNumber = this.getHandsomeNumber(minNumber, maxNumber);
    276                 comparisonArray[unitIndex][valueIndex] = {
    277                     value: (niceNumber.value / (valueIndex + 1)),
     298                var num = this.getHandsomeNumber(minNumber, maxNumber);
     299                comp[unitIndex][valueIndex] = {
     300                    value: (num.value / (valueIndex + 1)),
    278301                    score: 0,
    279302                    tieBreaker: 0,
     
    282305                };
    283306                // now tally up scores for all values given this subdivision length
    284                 for(var valueIndex2 = 0; valueIndex2 < (this.divisions * this.subdivisions); ++valueIndex2) {
    285                     var displayedValuePosition = niceNumber.value *
    286                                              (valueIndex2 + 1) / (valueIndex + 1);
    287                     var niceNumber2 = this.getHandsomeNumber(displayedValuePosition, displayedValuePosition);
    288                     var isMajorMeasurement = ((valueIndex2 + 1) % this.subdivisions == 0);
    289                     var isLastMeasurement = ((valueIndex2 + 1) == (this.divisions *
    290                                                                    this.subdivisions));
    291                     if((this.singleLine && isLastMeasurement) ||
    292                        (!this.singleLine && (isMajorMeasurement || this.showMinorMeasures))) {
     307                for(var valueIndex2 = 0; valueIndex2 < numDiv; ++valueIndex2) {
     308                    var displayedValuePosition = num.value * (valueIndex2 + 1) / (valueIndex + 1);
     309                    var num2 = this.getHandsomeNumber(displayedValuePosition, displayedValuePosition);
     310                    var major = ((valueIndex2 + 1) % this.subdivisions == 0);
     311                    var last = ((valueIndex2 + 1) == numDiv);
     312                    if((this.singleLine && last) ||
     313                       (!this.singleLine && (major || this.showMinorMeasures))) {
    293314                        // count scores for displayed marker measurements
    294                         comparisonArray[unitIndex][valueIndex].score += niceNumber2.score;
    295                         comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker;
    296                         comparisonArray[unitIndex][valueIndex].numDec = Math.max(comparisonArray[unitIndex][valueIndex].numDec, niceNumber2.numDec);
    297                         comparisonArray[unitIndex][valueIndex].displayed += 1;
    298                     }
    299                     else {
     315                        comp[unitIndex][valueIndex].score += num2.score;
     316                        comp[unitIndex][valueIndex].tieBreaker += num2.tieBreaker;
     317                        comp[unitIndex][valueIndex].numDec = Math.max(comp[unitIndex][valueIndex].numDec, num2.numDec);
     318                        comp[unitIndex][valueIndex].displayed += 1;
     319                    } else {
    300320                        // count scores for non-displayed marker measurements
    301                         comparisonArray[unitIndex][valueIndex].score += niceNumber2.score / this.subdivisions;
    302                         comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker / this.subdivisions;
     321                        comp[unitIndex][valueIndex].score += num2.score / this.subdivisions;
     322                        comp[unitIndex][valueIndex].tieBreaker += num2.tieBreaker / this.subdivisions;
    303323                    }
    304324                }
    305325                // adjust scores so numbers closer to 1 are preferred for display
    306326                var scoreAdjustment = (unitIndex + 1) *
    307                                       comparisonArray[unitIndex][valueIndex].tieBreaker /
    308                                       comparisonArray[unitIndex][valueIndex].displayed;
    309                 comparisonArray[unitIndex][valueIndex].score *= scoreAdjustment;
     327                                      comp[unitIndex][valueIndex].tieBreaker /
     328                                      comp[unitIndex][valueIndex].displayed;
     329                comp[unitIndex][valueIndex].score *= scoreAdjustment;
    310330            }
    311331        }
     
    318338        var bestTieBreaker = Number.POSITIVE_INFINITY;
    319339        var numDec = 0;
    320         for(var unitIndex = 0; unitIndex < comparisonArray.length; ++unitIndex) {
    321             for(valueIndex in comparisonArray[unitIndex]) {
    322                 if((comparisonArray[unitIndex][valueIndex].score < bestScore) ||
    323                    ((comparisonArray[unitIndex][valueIndex].score == bestScore) &&
    324                     (comparisonArray[unitIndex][valueIndex].tieBreaker < bestTieBreaker))) {
    325                     bestScore = comparisonArray[unitIndex][valueIndex].score;
    326                     bestTieBreaker = comparisonArray[unitIndex][valueIndex].tieBreaker;
    327                     subdivisionDisplayLength = comparisonArray[unitIndex][valueIndex].value;
    328                     numDec = comparisonArray[unitIndex][valueIndex].numDec;
    329                     displayUnits = this.measurementProperties[this.displaySystem].units[unitIndex];
    330                     displayUnitsAbbr = this.measurementProperties[this.displaySystem].abbr[unitIndex];
     340        for(var unitIndex = 0; unitIndex < comp.length; ++unitIndex) {
     341            for(valueIndex in comp[unitIndex]) {
     342                if((comp[unitIndex][valueIndex].score < bestScore) ||
     343                   ((comp[unitIndex][valueIndex].score == bestScore) &&
     344                    (comp[unitIndex][valueIndex].tieBreaker < bestTieBreaker))) {
     345                    bestScore = comp[unitIndex][valueIndex].score;
     346                    bestTieBreaker = comp[unitIndex][valueIndex].tieBreaker;
     347                    subdivisionDisplayLength = comp[unitIndex][valueIndex].value;
     348                    numDec = comp[unitIndex][valueIndex].numDec;
     349                    displayUnits = system.units[unitIndex];
     350                    displayUnitsAbbr = system.abbr[unitIndex];
    331351                    pixelsPerDisplayUnit = OpenLayers.DOTS_PER_INCH *
    332                                            this.measurementProperties[this.displaySystem].inches[unitIndex] /
    333                                            this.scaleDenominator;
     352                                           system.inches[unitIndex] /
     353                                           this.scale;
    334354                    subdivisionPixelLength = pixelsPerDisplayUnit * subdivisionDisplayLength; // round before use in style
    335355                }
     
    341361        this.numbersContainer.innerHTML = "";
    342362        // create all divisions
    343         var aMarker, aBarPiece, numbersBox, xOffset;
     363        var marker, bar, numbersBox, xOffset;
    344364        var alignmentOffset = {
    345365            left: 0 + (this.singleLine ? 0 : this.xOffsetNumbersBox),
    346             center: (this.maxWidth / 2) - (this.divisions * this.subdivisions *
     366            center: (this.maxWidth / 2) - (numDiv *
    347367                                           subdivisionPixelLength / 2) -
    348368                                          (this.singleLine ? this.xOffsetSingleLine / 2 : 0),
    349             right: this.maxWidth - (this.divisions * this.subdivisions *
     369            right: this.maxWidth - (numDiv *
    350370                                    subdivisionPixelLength) -
    351371                                   (this.singleLine ? this.xOffsetSingleLine : this.xOffsetNumbersBox)
     
    361381                                 subdivisionDisplayLength).toFixed(numDec);
    362382            // add major marker
    363             aMarker = document.createElement('div');
    364             aMarker.className = this.displayClass + 'MarkerMajor';
    365             aMarker.style.position = 'absolute';
    366             aMarker.style.overflow = 'hidden';
    367             aMarker.style.left = Math.round(xPosition - this.xOffsetMarkerMajor) + 'px';
    368             aMarker.appendChild(document.createTextNode(' '));
    369             this.graphicsContainer.appendChild(aMarker);
     383            marker = document.createElement('div');
     384            marker.className = this.displayClass + 'MarkerMajor';
     385            marker.style.position = 'absolute';
     386            marker.style.overflow = 'hidden';
     387            marker.style.left = Math.round(xPosition - this.xOffsetMarkerMajor) + 'px';
     388            marker.appendChild(document.createTextNode(' '));
     389            this.graphicsContainer.appendChild(marker);
    370390            // add major measure
    371391            if(!this.singleLine) {
     
    377397                if(this.showMinorMeasures) {
    378398                    numbersBox.style.left = Math.round(xPosition - this.xOffsetNumbersBox) + 'px';
    379                 }
    380                 else {
     399                } else {
    381400                    numbersBox.style.left = Math.round(xPosition - this.xOffsetNumbersBox) + 'px';
    382401                }
     
    386405            // create all subdivisions
    387406            for(var subdivisionIndex = 0; subdivisionIndex < this.subdivisions; ++subdivisionIndex) {
    388                 aBarPiece = document.createElement('div');
    389                 aBarPiece.style.position = 'absolute';
    390                 aBarPiece.style.overflow = 'hidden';
    391                 aBarPiece.style.width = Math.round(subdivisionPixelLength) + 'px';
     407                bar = document.createElement('div');
     408                bar.style.position = 'absolute';
     409                bar.style.overflow = 'hidden';
     410                bar.style.width = Math.round(subdivisionPixelLength) + 'px';
    392411                if((subdivisionIndex % 2) == 0) {
    393                     aBarPiece.className = this.displayClass + 'Bar';
    394                     aBarPiece.style.left = Math.round(xPosition - this.xOffsetBar) + 'px';
     412                    bar.className = this.displayClass + 'Bar';
     413                    bar.style.left = Math.round(xPosition - this.xOffsetBar) + 'px';
     414                } else {
     415                    bar.className = this.displayClass + 'BarAlt';
     416                    bar.style.left = Math.round(xPosition - this.xOffsetBarAlt) + 'px';
    395417                }
    396                 else {
    397                     aBarPiece.className = this.displayClass + 'BarAlt';
    398                     aBarPiece.style.left = Math.round(xPosition - this.xOffsetBarAlt) + 'px';
    399                 }
    400                 aBarPiece.appendChild(document.createTextNode(' '));
    401                 this.graphicsContainer.appendChild(aBarPiece);
     418                bar.appendChild(document.createTextNode(' '));
     419                this.graphicsContainer.appendChild(bar);
    402420                // add minor marker if not the last subdivision
    403421                if(subdivisionIndex < (this.subdivisions - 1)) {
     
    408426                    markerMeasure = (divisionIndex * this.subdivisions +
    409427                                     subdivisionIndex + 1) * subdivisionDisplayLength;
    410                     aMarker = document.createElement('div');
    411                     aMarker.className = this.displayClass + 'MarkerMinor';
    412                     aMarker.style.position = 'absolute';
    413                     aMarker.style.overflow = 'hidden';
    414                     aMarker.style.left = Math.round(xPosition - this.xOffsetMarkerMinor) + 'px';
    415                     aMarker.appendChild(document.createTextNode(' '));
    416                     this.graphicsContainer.appendChild(aMarker);
     428                    marker = document.createElement('div');
     429                    marker.className = this.displayClass + 'MarkerMinor';
     430                    marker.style.position = 'absolute';
     431                    marker.style.overflow = 'hidden';
     432                    marker.style.left = Math.round(xPosition - this.xOffsetMarkerMinor) + 'px';
     433                    marker.appendChild(document.createTextNode(' '));
     434                    this.graphicsContainer.appendChild(marker);
    417435                    if(this.showMinorMeasures && !this.singleLine) {
    418436                        // add corresponding measure
     
    430448        }
    431449        // set xPosition and markerMeasure to end of divisions
    432         xPosition = (this.divisions * this.subdivisions) * subdivisionPixelLength;
     450        xPosition = (numDiv) * subdivisionPixelLength;
    433451        xPosition += alignmentOffset[this.align];
    434         markerMeasure = ((this.divisions * this.subdivisions) *
     452        markerMeasure = ((numDiv) *
    435453                         subdivisionDisplayLength).toFixed(numDec);
    436454        // add the final major marker
    437         aMarker = document.createElement('div');
    438         aMarker.className = this.displayClass + 'MarkerMajor';
    439         aMarker.style.position = 'absolute';
    440         aMarker.style.overflow = 'hidden';
    441         aMarker.style.left = Math.round(xPosition - this.xOffsetMarkerMajor) + 'px';
    442         aMarker.appendChild(document.createTextNode(' '));
    443         this.graphicsContainer.appendChild(aMarker);
     455        marker = document.createElement('div');
     456        marker.className = this.displayClass + 'MarkerMajor';
     457        marker.style.position = 'absolute';
     458        marker.style.overflow = 'hidden';
     459        marker.style.left = Math.round(xPosition - this.xOffsetMarkerMajor) + 'px';
     460        marker.appendChild(document.createTextNode(' '));
     461        this.graphicsContainer.appendChild(marker);
    444462        // add final measure
    445463        if(!this.singleLine) {
     
    452470                numbersBox.style.left = Math.round(xPosition -
    453471                                                   this.xOffsetNumbersBox) + 'px';
    454             }
    455             else {
     472            } else {
    456473                numbersBox.style.left = Math.round(xPosition -
    457474                                                   this.xOffsetNumbersBox) + 'px';
     
    467484            labelText = markerMeasure;
    468485            labelBox.className = this.displayClass + 'LabelBoxSingleLine';
    469             labelBox.style.left = (xPosition +
     486            labelBox.style.left = Math.round(xPosition +
    470487                                   this.styleValue('LabelBoxSingleLine', 'left')) + 'px';
    471         }
    472         else {
     488        } else {
    473489            labelText = '';
    474490            labelBox.className = this.displayClass + 'LabelBox';
    475491            labelBox.style.textAlign = 'center';
    476             labelBox.style.width = Math.round(this.divisions * this.subdivisions *
     492            labelBox.style.width = Math.round(numDiv *
    477493                                              subdivisionPixelLength) + 'px'
    478494            labelBox.style.left = Math.round(alignmentOffset[this.align]) + 'px';
     
    481497        if(this.abbreviateLabel) {
    482498            labelText += ' ' + displayUnitsAbbr;
    483         }
    484         else {
     499        } else {
    485500            labelText += ' ' + displayUnits;
    486501        }
     
    513528                                // can't get rules, assume zero
    514529                                break;
    515                             }
    516                             else {
     530                            } else {
    517531                                allRules = sheet.rules;
    518532                            }
    519                         }
    520                         else {
     533                        } else {
    521534                            allRules = sheet.cssRules;
    522535                        }
     
    541554   
    542555    /**
    543      * @type String
    544      * @param {Float} aNumber
    545      * @param {Int} numDecimals
    546      * @private
    547      */
    548     formatNumber: function(aNumber, numDecimals) {
    549         numDecimals = (numDecimals) ? numDecimals : 0;
    550         var formattedInteger = '' + Math.round(aNumber);
    551         var thousandsPattern = /(-?[0-9]+)([0-9]{3})/;
    552         while(thousandsPattern.test(formattedInteger)) {
    553             formattedInteger = formattedInteger.replace(thousandsPattern, '$1,$2');
    554         }
    555         if(numDecimals > 0) {
    556             var formattedDecimal = Math.floor(Math.pow(10, numDecimals) * (aNumber - Math.round(aNumber)));
    557             if(formattedDecimal == 0) {
    558                 return formattedInteger;
    559             }
    560             else {
    561                 return formattedInteger + '.' + formattedDecimal;
    562             }
    563         }
    564         else {
    565             return formattedInteger;
    566         }
     556     * Method: formatNumber
     557     * Returns a string formatted number with thousands separators truncated
     558     *     to the given number of decimal places.
     559     *
     560     * Parameters:
     561     * num - {Float} Input number
     562     * dec - {Integer} Optional number of decimals.  Default is 0.
     563     * tsep - {String} Thousands separator.  Default is ",".
     564     * dsep - {String} Decimal separator.  Default is ".".
     565     *
     566     * Returns:
     567     * {String} A formatted number string.
     568     */
     569    formatNumber: function(num, dec, tsep, dsep) {
     570        dec = (dec != undefined) ? dec : 0;
     571        tsep = (tsep != undefined) ? tsep : ",";
     572        dsep = (dsep != undefined) ? dsep : ".";
     573        var str;
     574        var integer = Math.round(num).toString();
     575        var thousands = /(-?[0-9]+)([0-9]{3})/;
     576        while(thousands.test(integer)) {
     577            integer = integer.replace(thousands, "$1" + tsep + "$2");
     578        }
     579        if(dec > 0) {
     580            var rem = Math.floor(Math.pow(10, dec) * (num - Math.round(num)));
     581            if(rem == 0) {
     582                str = integer;
     583            } else {
     584                str = integer + dcep + rem;
     585            }
     586        } else {
     587            str = integer;
     588        }
     589        return str;
    567590    },
    568591
    569592    /**
    570593     * Method: getHandsomeNumber
    571      * Attempts to generate a nice looking number.
     594     * Attempts to generate a nice looking number between two other numbers.
    572595     *
    573596     * Parameters:
    574597     * small - {Float}
    575598     * big - {Float}
    576      * sigFigs - {Integer}
     599     * sigFigs - {Integer}
     600     *
     601     * Returns:
     602     * {Object} Object representing a nice looking number.
    577603     */
    578604    getHandsomeNumber: function(small, big, sigFigs) {
    579605        sigFigs = (sigFigs == null) ? 10 : sigFigs;
    580         var bestScore = Number.POSITIVE_INFINITY;
    581         var bestTieBreaker = Number.POSITIVE_INFINITY;
    582606        // if all else fails, return a small ugly number
    583         var handsomeValue = small;
    584         var handsomeNumDec = 3;
     607        var num = {
     608            value: small,
     609            score: Number.POSITIVE_INFINITY,
     610            tieBreaker: Number.POSITIVE_INFINITY,
     611            numDec: 3
     612        };
    585613        // try the first three comely multiplicands (in order of comliness)
     614        var cmult, max, numDec, tmult, multiplier, score, tieBreaker;
    586615        for(var halvingExp = 0; halvingExp < 3; ++halvingExp) {
    587             var cmult = Math.pow(2, (-1 * halvingExp));
    588             var maxTensExp = Math.floor(Math.log(big / cmult) / Math.LN10);
    589             for(var texp = maxTensExp; texp > (maxTensExp - sigFigs + 1); --texp) {
    590                 var numDec = Math.max(halvingExp - texp, 0);
    591                 var tmult = cmult * Math.pow(10, texp);
     616            cmult = Math.pow(2, (-1 * halvingExp));
     617            max = Math.floor(Math.log(big / cmult) / Math.LN10);
     618            for(var texp = max; texp > (max - sigFigs + 1); --texp) {
     619                numDec = Math.max(halvingExp - texp, 0);
     620                tmult = cmult * Math.pow(10, texp);
    592621                // check if there is an integer multiple of tmult
    593622                // between small and big
    594                 if((tmult * Math.floor(big /
    595                     tmult)) >= small) {
     623                if((tmult * Math.floor(big / tmult)) >= small) {
    596624                    // check if small is an integer multiple of tmult
    597625                    if(small % tmult == 0) {
    598                         var testMultiplier = small / tmult;
    599                     }
    600                     // otherwise go for the smallest integer multiple between small and big
    601                     else {
    602                         var testMultiplier = Math.floor(small /
    603                                                         tmult) + 1;
     626                        multiplier = small / tmult;
     627                    } else {
     628                        // smallest integer multiple between small and big
     629                        multiplier = Math.floor(small / tmult) + 1;
    604630                    }
    605631                    // test against the best (lower == better)
    606                     var testScore = testMultiplier + (2 * halvingExp);
    607                     var testTieBreaker = (texp < 0) ?
    608                                           (Math.abs(texp) + 1) : texp;
    609                     if((testScore < bestScore) || ((testScore == bestScore) &&
    610                        (testTieBreaker < bestTieBreaker))) {
    611                         bestScore = testScore;
    612                         bestTieBreaker = testTieBreaker;
    613                         handsomeValue = (tmult *
    614                                          testMultiplier).toFixed(numDec);
    615                         handsomeNumDec = numDec;
     632                    score = multiplier + (2 * halvingExp);
     633                    tieBreaker = (texp < 0) ? (Math.abs(texp) + 1) : texp;
     634                    if((score < num.score) || ((score == num.score) &&
     635                       (tieBreaker < num.tieBreaker))) {
     636                        num.value = (tmult * multiplier).toFixed(numDec);
     637                        num.score = score;
     638                        num.tieBreaker = tieBreaker;
     639                        num.numDec = numDec;
    616640                    }
    617641                }
    618642            }
    619643        }
    620         return {
    621             value: handsomeValue,
    622             score: bestScore,
    623             tieBreaker: bestTieBreaker,
    624             numDec: handsomeNumDec
    625         }
     644        return num;
    626645    },
    627646   
  • sandbox/tschaub/scalebar/theme/default/style.css

    r5656 r5657  
    174174.olControlScaleBar {
    175175    bottom: 10px;
     176    left: 15px;
    176177    font-family: sans-serif;
    177178    color: #00008B;
Note: See TracChangeset for help on using the changeset viewer.