Разумное оптимизированное масштабирование диаграммы

Вы можете использовать функцию string_split(), например, функцию в SQL Server 2016+ (или версию в Интернете).

Затем вы можете сделать:

select ss.substr
from string_split(@str, ' ') ss(substr)
where substr like '%.%.%.%' ;

Однако SQL не лучше всего подходит для этого типа обработки строк.

32
задан Grant 11 March 2019 в 19:06
поделиться

5 ответов

Это от предыдущего подобного вопроса:

Алгоритм для " nice" интервалы линии сетки на графике

я сделал это со своего рода методом грубой силы. Во-первых, выясните максимальное количество меток, можно вписаться в пространство. Разделите общий диапазон значений количеством галочек; это минимум интервал галочки. Теперь вычислите, этаж логарифма базируются 10, чтобы получить величину галочки и разделиться на это значение. Необходимо закончить с чем-то в диапазоне 1 - 10. Просто выберите круглое число, больше, чем или равный значению, и умножьте его на логарифм, вычисленный ранее. Это - Ваш заключительный интервал галочки.

Пример в Python:

import math

def BestTick(largest, mostticks):
    minimum = largest / mostticks
    magnitude = 10 ** math.floor(math.log(minimum) / math.log(10))
    residual = minimum / magnitude
    if residual > 5:
        tick = 10 * magnitude
    elif residual > 2:
        tick = 5 * magnitude
    elif residual > 1:
        tick = 2 * magnitude
    else:
        tick = magnitude
    return tick
5
ответ дан 27 November 2019 в 21:16
поделиться

Вы могли окружить к двум значащим цифрам. Следующий псевдокод должен работать:

// maxValue is the largest value in your chart
magnitude = floor(log10(maxValue))
base = 10^(magnitude - 1)
chartHeight = ceiling(maxValue / base) * base

, Например, если maxValue 1357, то величина равняется 3 и основе, 100. Деление на 100, окружение и умножение на 100 имеет результат окружения к следующему несколько из 100, т.е. окружения к двум значащим цифрам. В этом случае, результат, если 1400 (1 357 в ‡’ 13,57 в ‡’ 14 в ‡’ 1400).

3
ответ дан 27 November 2019 в 21:16
поделиться

Если Вы хотите 1400 наверху, как насчет того, чтобы корректировать последние два параметра к 1400 вместо 1357:

alt text

1
ответ дан 27 November 2019 в 21:16
поделиться

В прошлом я сделал это в виде выхода грубой силы пути. Вот блок кода C++, который работает хорошо..., но на hardcoded нижние и верхние пределы (0 и 5000):

int PickYUnits()
{
    int MinSize[8] = {20, 20, 20, 20, 20, 20, 20, 20};
    int ItemsPerUnit[8] = {5, 10, 20, 25, 50, 100, 250, 500};
    int ItemLimits[8] = {20, 50, 100, 250, 500, 1000, 2500, 5000};
    int MaxNumUnits = 8;
    double PixelsPerY;
    int PixelsPerAxis;
    int Units;

    //
    // Figure out the max from the dataset
    //  - Min is always 0 for a bar chart
    //
    m_MinY = 0;
    m_MaxY = -9999999;
    m_TotalY = 0;
    for (int j = 0; j < m_DataPoints.GetSize(); j++) {
        if (m_DataPoints[j].m_y > m_MaxY) {
            m_MaxY = m_DataPoints[j].m_y;
        }

        m_TotalY += m_DataPoints[j].m_y;
    }

    //
    // Give some space at the top
    //
    m_MaxY = m_MaxY + 1;


    //
    // Figure out the size of the range
    //
    double yRange = (m_MaxY - m_MinY);

    //
    // Pick the initial size
    //
    Units = MaxNumUnits;
    for (int k = 0; k < MaxNumUnits; k++)
    {
        if (yRange < ItemLimits[k])
        {
            Units = k;
            break;
        }
    }

    //
    // Adjust it upwards based on the space available
    //
    PixelsPerY = m_rcGraph.Height() / yRange;
    PixelsPerAxis = (int)(PixelsPerY * ItemsPerUnit[Units]);

    while (PixelsPerAxis < MinSize[Units]){
        Units += 1;
        PixelsPerAxis = (int)(PixelsPerY * ItemsPerUnit[Units]);
        if (Units == 5)
            break;
    }


    return ItemsPerUnit[Units];
}

Однако что-то в том, что Вы сказали, настроило меня. Выбрать хорошую ось нумерует определение "хорошего числа", помог бы:

  • А "хорошее" число является тем, которое имеет 3 или меньше ненулевых цифр (например, 1230000)
  • А, "хорошее" число имеет то же или немного ненулевых цифр, чем нулевые цифры (например, 1230 не хорош, 1200 хорош)
  • , самые хорошие числа являются с кратными числами 3 нулей (например, "1,000", "1,000,000")
  • , вторые самые хорошие числа являются onces с multples 3 нулей плюс 2 нуля (например, "1,500,000", "1,200")

Не уверенный, если вышеупомянутое определение является "правильным" или на самом деле полезным (но с определением в руке это тогда становится более простой задачей разработать алгоритм).

3
ответ дан 27 November 2019 в 21:16
поделиться

Вы могли использовать отделение и модификацию. Например.

Скажем, Вы хотите, чтобы Ваша диаграмма окружила инкрементами 20 (только для создания его больше более произвольным числом, чем типичное "10" значение).

, Таким образом, я предположил бы, что 1, 11, 18 будет повсюду вокруг максимум 20. Но 21, 33, 38 был бы вокруг к 40.

Для предложения правильного значения делают следующее:

Where divisor = your rounding increment.

divisor = 20
multiple = maxValue / divisor;  // Do an integer divide here. 
if (maxValue modulus divisor > 0)
   multiple++;

graphMax = multiple * maxValue;

Поэтому теперь позволяют нам сменные вещественные числа:

divisor = 20;
multiple = 33 / 20; (integer divide)
so multiple = 1
if (33 modulus 20 > 0)  (it is.. it equals 13) 
   multiple++;

so multiple = 2;
graphMax = multiple (2) * maxValue (20);
graphMax = 40;
0
ответ дан 27 November 2019 в 21:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: