Highcharts внутреннее или PHP-решение, чтобы иметь равное расстояние года по оси x?

У меня проблема с некоторыми из моих (сотни) переменных, в основном с годовыми значениями, имеющими данные только за определенные годы. Итак, вместо 1990,1992,1992,.... у них 1990,2000,2005,2010... или 1990,1995,2000,2005,2008

Полученная диаграмма показывает одинаковое расстояние между всеми годами, хотя в случае 1990, 2000, 2005, 2010 годов расстояние между 1990 и 2000 годами (в два раза) больше, чем между последующими годами. Вот пример.

Теперь я не видел никакого внутреннего решения Highcharts для этого. Было бы неплохо указать такой параметр, как «правильно распределить годы по оси X». Думаю, этого не существует.

Это означает, что мне нужно будет что-то закодировать на PHP. Какая-то «инъекция» в два массива (ось x, ось y), которая заполнит массив оси x пропущенными годами, а массив оси y - значениями NULL.

Спасибо за любые подсказки!


person luftikus143    schedule 30.01.2014    source источник
comment
В случае, когда вы используете категории, вам нужно добавить нулевые элементы, чтобы иметь расстояние между ними, когда вы хотите иметь неправильную галочку, вам нужно использовать тип даты и времени xAxis и установить порядковый номер как false.   -  person Sebastian Bochan    schedule 30.01.2014
comment
Спасибо! Если я правильно понимаю, например, здесь порядковый номер недоступен в Highcarts, но только в Highstocks. Точно так?   -  person luftikus143    schedule 30.01.2014
comment
Точно, вы правы.   -  person Sebastian Bochan    schedule 30.01.2014


Ответы (3)


Вы можете исправить это в PHP, как вы догадались. вот как я это сделал:

while($row = mysql_fetch_assoc($result,1))
{
    $chartData[$row['date']] = $row['value']; 
    $chartDataDates[$row['date']] = 1;
}
$max_date = max( array_keys( $chartDataDates) );
$min_date = min( array_keys( $chartDataDates) );
for($i=$min_date;$i<$max_date;$i++)
{
    $chartDataDates[$i] = 1;
}
foreach($chartDataDates as $date=>$value)
{
    if(!isset($chartData[$date]))
    $chartData[$date] = 0;
}

и в параметрах highcharts:

        xAxis: {categories: ['<?php echo implode("','",array_keys($chartDataDates)); ?>']},
        series: [<?php 
            name: 'my data',
            data: [<?php echo implode(",",$chartData ) ?>]
        }
person Volkan Ulukut    schedule 30.01.2014

Спасибо за подсказки!

В конце концов я выбрал, возможно, немного более сложное решение, сначала проверив необходимость дополнительных вычислений, если произойдет что-то подобное.

// categories = years
$cat = "";

for ($j = 0; $j < count($data_x); $j++)
{
    $cat .= "'" . $data_x[$j] . "',";

    // what happens with data like "1990,2000,2005,2008" (id=2199)
    if (($j >= 1) && ($j < (count($data_x) - 1)))
    {
        if (!(($data_x[($j)] - $data_x[($j - 1)]) == ($data_x[($j + 1)] - $data_x[$j])))
        {
            // what to do here?
            $flag_years = true;
        }
    }
}

$cat = substr($cat, 0, -1);

И если да, то пересчитывая годы:

// if need to display additional years due to "1990,2000,2005,2008"
if ($flag_years)
{
    $data_x_new = array();

    $min_date = min($data_x);
    $max_date = max($data_x);

    for ($i = $min_date; $i <= $max_date; $i++)
    {
        $data_x_new[($i - $min_date)] = $i;
    }

    $cat = "'" . implode("','", $data_x_new) . "'";

    $numYears = count($data_x_new);
}

А затем позаботимся о дополнительных значениях NULL, которые будут вставлены в $data_y:

// loop through countries
for ($i = 0; $i < $numCountries; $i++)
{   
    $val = "[";
    $count = 0;

    // loop through values
    for ($j = 0; $j < $numYears; $j++)
    {
        // if need to display additional years due to "1990,2000,2005,2008"
        if ($flag_years)
        {
            if ($data_x_new[$j] == $data_x[($j - $count)])
            {
                $val .= $data_y[$i][($j - $count)] . ",";
            }
            else
            {
                $val .= "null,";
                $count++;
            }
        }
        // otherwise normal display
        else
        {
            if ($data_y[$i][$j] == "")
            {
                $val .= "null,";
            }
            else
            {
                $val .= $data_y[$i][$j] . ",";
            }
        }
    }

    $val = substr($val, 0, -1) . "]";


    // store all in an array        
    $vals[$i] = $val;
}

Думаю, есть более простое решение, но оно работает!

person luftikus143    schedule 30.01.2014
comment
Я думаю, что это СЛИШКОМ сложное решение проблемы, если я правильно понимаю проблему. Смотрите мой ответ. - person jlbriggs; 31.01.2014

Все, что вам нужно сделать в Highcharts, чтобы «правильно» распределить годы, — это использовать тип оси даты и времени и указать фактическую дату в этом году в качестве значения x.

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

Затем вы просто форматируете свои метки, чтобы отображать дату только как год.

Никаких циклов или вычислений не требуется.

{{РЕДАКТИРОВАТЬ:

updated fiddle example: http://jsfiddle.net/jlbriggs/6H3jL/2/

Кроме того, если вы хотите иметь метки оси x только там, где есть точка данных, вы можете использовать свойство tickPositions и предоставить ему массив тех же значений даты и времени, которые вы отправляете в качестве значений x для ваших данных.

person jlbriggs    schedule 31.01.2014
comment
Спасибо за это. Но я не вижу, как добиться того, что мне нужно, с помощью этих команд. Я разместил здесь скрипку; возможно, вы можете проверить это и исправить соответственно? - person luftikus143; 03.02.2014
comment
1) избавиться от категорий. Категории и оси даты и времени являются взаимоисключающими. 2) избавиться от настройки шага метки. 3) вам нужно отправить значение даты и времени в качестве значения x для каждой точки данных, чтобы диаграмма знала, куда его поместить. См. обновленный пример: jsfiddle.net/jlbriggs/6H3jL/2. - person jlbriggs; 03.02.2014