Choropleth Pretty Breaks - PullRequest
       25

Choropleth Pretty Breaks

0 голосов
/ 10 октября 2019

Я пытаюсь разработать функцию довольно разрывов в javascript, но я нахожу только примеры в r.

Знаете ли вы, где найти информацию для javascript?

Моя проблема в том, что я не понимаю, как генерировать разрывы. Я понимаю, как сделать круглые перерывы, но как рассчитать диапазоны перерывов при выборе 4 перерывов?

Я использую файл geojson , работающий с плотностью.

Спасибо за помощь PS: Я прошу прощения за мой английский, я не являюсь носителем языка.

1 Ответ

0 голосов
/ 14 октября 2019

Я решил использовать это шагов .

Я надеюсь, что это служит кому-то еще.

Большое спасибо: D

function prettyBreaks(minimum, maximum, classes) {

    let breaks = [];

    if ( classes < 1 ) {
        breaks.push( maximum );
        return breaks;
    }

    let minimumCount = parseInt(classes / 3 );
    let shrink = 0.75;
    let highBias = 1.5;
    let adjustBias = 0.5 + 1.5 * highBias;
    let divisions = parseInt( classes );
    let h = highBias;
    let cell;
    let small = false;
    let dx = maximum - minimum;

    if (NearTo( dx, 0.0 ) && NearTo( maximum, 0.0 )) {
        cell = 1.0;
        small = true;
    } else {
        let U = 1;
        cell = (Math.abs(maximum) >= Math.abs(minimum)) ? Math.abs(maximum) : Math.abs(minimum);
        if ( adjustBias >= 1.5 * h + 0.5) {
            U = parseInt( 1 + (1.0 / (1 + h)) );
        } else {
            U = parseInt( 1 + ( 1.5 / ( 1 + adjustBias ) ) );
        }
        let maxBetweenDivisions = (1 >= divisions) ? 1 : divisions;
        small = dx < ( cell * U * maxBetweenDivisions * 1e-07 * 3.0 );
    }

    if (small) {
        if (cell > 10) {
            cell = 9 + cell / 10;
            cell = cell * shrink;
        }
        if (minimumCount > 1) {
            cell = cell / minimumCount;
        }
    } else {
        cell = dx;
        if (divisions > 1) {
            cell = cell / divisions;
        }
    }

    if (cell < 20 * 1e-07) {
        cell = 20 * 1e-07;
    }

    let base = Math.pow(10.0, Math.floor( Math.log10( cell )));
    let unit = base;

    if ( ( 2 * base ) - cell < h * ( cell - unit ) ) {
        unit = 2.0 * base;
        if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
        {
          unit = 5.0 * base;
          if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
          {
            unit = 10.0 * base;
          }
        }
    }

    let start = parseInt( Math.floor( minimum / unit + 1e-07 ) );
    let end = parseInt( Math.ceil( maximum / unit - 1e-07 ) );

    // Extend the range out beyond the data. Does this ever happen??
    while ( start * unit > minimum + ( 1e-07 * unit ) ) {
        start = start - 1;
    }
    while ( end * unit < maximum - ( 1e-07 * unit ) ) {
        end = end + 1;
    }

    let k = parseInt( Math.floor( 0.5 + end - start ) );
    if ( k < minimumCount ) {
        k = minimumCount - k;
        if ( start >= 0 ) {
            end = end + k / 2;
            start = start - k / 2 + k % 2;
        }
        else {
            start = start - k / 2;
            end = end + k / 2 + k % 2;
        }
    }
    let minimumBreak = start * unit;
    let count = parseInt( end - start );

    breaks = [];
    for ( let i = 1; i < count + 1; i++ ) {
        breaks.push( minimumBreak + i * unit );
    }

    if ( breaks.length === 0 ) return breaks;

    if ( breaks[0] < minimum ) {
        breaks.splice(0, 1, minimum);
    }
    if ( breaks[breaks.length-1] > maximum ) {
        breaks.splice(breaks.length-1, 1, maximum);
    }

    if ( minimum < 0.0 && maximum > 0.0 ) { //then there should be a zero somewhere 
        let breaksMinusZero = []; // compute difference "each break - 0"
        for ( let i = 0; i <= breaks.length; i++ ) {
            breaksMinusZero.push( breaks[i] - 0.0 );
        }
        let posOfMin = 0;
        for ( let i = 1; i <= breaks.length; i++ ) { // find position of minimal difference
            if ( Math.abs( breaksMinusZero[i] ) < Math.abs( breaksMinusZero[i - 1] ) )
            posOfMin = i;
        }
        breaks[posOfMin] = 0.0;
    }

    return breaks;
};



/** Check if value1 is nearest to value2 */
function NearTo(value1, value2) {
    if (value1 > 1 || value2 > 1) return false;
    else if ((value1 >= 0 && value1 < 1 ) && (value2 >= 0 && value2 < 1 )) return true;
    else return false;
};
...