R Highcharter: умный способ разделить легенды или несколько графиков с синхронизированным увеличением / всплывающей подсказкой? - PullRequest
0 голосов
/ 26 апреля 2020

Мой вопрос относится к случаю, когда я использую highstock для построения нескольких сложенных осей y, как, например, в последнем примере: http://jkunst.com/highcharter/highstock.html.

Я хотел бы иметь отдельные легенды для каждой из осей Y, но при некотором копании это выглядит так, как будто у старших графиков может быть только одна легенда ( Highcharts множественных легенд ).

Тогда я подумал, что, возможно, я мог бы использовать аннотации, чтобы имитировать c желаемых легенд. Но рисовать цветные отрезки линий было бы грязно, так как они отображались бы как серии (хотя я думаю, что я мог бы просто использовать цветной текст, чтобы указать, какая серия какая).

Есть ли умный способ обойти ограничение в одну легенду при использовании нескольких осей Y в старших картах?

Если нет, то, если бы мне абсолютно необходимо было иметь разные легенды, я бы, по-видимому, использовать несколько стековых диаграмм. В этом случае мне нужно будет синхронизировать масштаб и всплывающую подсказку на нескольких графиках. Существует много информации о том, как это сделать с помощью javascript (с которой у меня ограниченный опыт), но, похоже, периодически возникают проблемы с синхронизацией как зума, так и всплывающей подсказки.

Мне было интересно, есть ли какие-нибудь примеры того, как синхронизировать масштабирование и всплывающую подсказку между несколькими диаграммами в верхнем чартере R (я искал все выше и ниже и не смог их найти)?

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

library(highcharter)
library(gplots)

dates   <- seq(as.Date('2015-04-24'),as.Date('2020-04-24'),1)
nDates  <- NROW(dates)
x11     <- xts(100 * cumprod(1 + 0.0010 * (1 + 0.0002 * rnorm(nDates))), dates)
x12     <- xts(100 * cumprod(1 + 0.0012 * (1 + 0.0001 * rnorm(nDates))), dates)
x2      <- xts(100 * runif(nDates), dates)
x31     <- xts(-1 + 2 * runif(nDates), dates)
x32     <- xts( 1 - 2 * runif(nDates), dates)

glc     <- col2hex('gray65') #gridLineColor)

hc <- highchart(type = 'stock') %>% 
        hc_chart(marginLeft = 75, marginRight = 75) %>% 
        hc_title(text = 'Example', align = 'center', verticalAlign = 'top', style = list(fontWeight = 'bold', fontSize = '20px')) %>%
        hc_rangeSelector(selected = 7) %>%
        hc_navigator(series = list(color = hex_to_rgba('black',1))) %>%
        hc_xAxis(type = 'datetime') %>% 
        hc_yAxis_multiples( 
                            #yAxis = 0, plot x11 and x12 here
                            list(top = "0%",  height = '60%', opposite = FALSE, type = 'logarithmic', showLastLabel = TRUE, allowDecimals = FALSE, 
                                     labels = list(align = 'right', x = -10, format = '{value}%', distance = 0), gridLineDashStyle = 'Dot', gridLineColor = glc, startOnTick = FALSE, endOnTick = TRUE),

                            #yAxis = 1 to duplicate axis labels on opposite side    
                            list(top = "0%",  height = '60%', opposite = TRUE, type = 'logarithmic', showLastLabel = TRUE, allowDecimals = FALSE, linkedTo = 0, opposite = TRUE, 
                                labels = list(align = 'right', x =  50, format = '{value}%', distance = 0), gridLineDashStyle = 'Dot', gridLineColor = glc, startOnTick = FALSE, endOnTick = TRUE),

                            #yAxis = 2, just to separate the charts
                            list(top = '60%', height = '5%'),

                            #yAxis = 3, plot x2 here
                            list(top = '65%', height = '15%', opposite = FALSE, tickPositions = c(0, 33, 67, 100), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
                                    labels = list(align = 'right', x= 35, format = '{value}%', distance = 0)),

                            #yAxis = 4, to duplicate the axis labels on the opposite side
                            list(top = '65%', height = '15%', linkedTo = 3, opposite = TRUE, tickPositions = c(0, 33, 67, 100), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
                                        labels = list(align = 'right', x= 50, format = '{value}%', distance = 0)),

                            #yAxis = 5, to separate the charts
                            list(top = '80%', height = '5%'),

                            #yAxis = 6, plot x31, x32, x33 here
                            list(top = '85%', height = '15%', opposite = FALSE, tickPositions = c(-2, -1, 0, 1, 2), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
                                    labels = list(align = 'right', x = 30, distance = 0, format = '{value:.1f}'), plotLines = list(list(color = "black", width = 2, value = 0))),

                            #yAxis = 7, to duplicate the axis labels on the opposite side
                            list(top = '85%', height = '15%', linkedTo = 6, opposite = TRUE, tickPositions = c(-2, -1, 0, 1, 2), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
                                        labels = list(align = 'right', x = 50, distance = 0, format = '{value:.1f}'))

                          ) %>%


            #Chart 1
            hc_add_series(x11, yAxis = 0, color = 'navy',   name = 'Series 11', tooltip = list(valueDecimals = 1, valueSuffix = '%')) %>%  
            hc_add_series(x12, yAxis = 0, color = 'green',  name = 'Series 12', tooltip = list(valueDecimals = 1, valueSuffix = '%')) %>% 

            #Chart 2
            hc_add_series(x2, yAxis = 3, color = 'black', name = 'Series 2', tooltip = list(valueDecimals = 0, valueSuffix = '%')) %>%

            #Chart 3
            hc_add_series(x31,  yAxis = 6, color = 'blue',  name = 'Series 31', tooltip = list(valueDecimals = 2)) %>%
            hc_add_series(x32,  yAxis = 6, color = 'green', name = 'Series 32', tooltip = list(valueDecimals = 2)) %>%

            #Chart 'titles'
            hc_annotations(list(labels = list(  list(point = list(x = 0, y = 20),                       text = 'Chart 1',   backgroundColor = 'white', borderColor = 'white', color = 'black', style = list(fontWeight = 'bold')), 
                                                list(point = list(yAxis = 3, x = index(x)[1], y = 90),  text = 'Chart 2',   backgroundColor = 'white', borderColor = 'white', color = 'black', style = list(fontWeight = 'bold')), 
                                                list(point = list(yAxis = 7, x = index(x)[1], y = 0.9), text = 'Chart 3',   backgroundColor = 'white', borderColor = 'white', color = 'black', style = list(fontWeight = 'bold')))))

print(hc)

В вышеприведенном примере, в идеале, можно было бы разместить отдельные легенды на диаграмме 1 и диаграмме. 3, где есть несколько серий.

1 Ответ

0 голосов
/ 29 апреля 2020

Самое простое решение - установить legend.layout на proximate, см. Пример:

library(highcharter)
library(gplots)
library(xts)

dates   <- seq(as.Date('2015-04-24'),as.Date('2020-04-24'),1)
nDates  <- NROW(dates)
x11     <- xts(100 * cumprod(1 + 0.0010 * (1 + 0.0002 * rnorm(nDates))), dates)
x12     <- xts(100 * cumprod(1 + 0.0012 * (1 + 0.0001 * rnorm(nDates))), dates)
x2      <- xts(100 * runif(nDates), dates)
x31     <- xts(-1 + 2 * runif(nDates), dates)
x32     <- xts( 1 - 2 * runif(nDates), dates)

glc     <- col2hex('gray65') #gridLineColor)

hc <- highchart(type = 'stock') %>% 
  hc_chart(marginLeft = 150, marginRight = 75) %>% 
  hc_title(text = 'Example', align = 'center', verticalAlign = 'top', style = list(fontWeight = 'bold', fontSize = '20px')) %>%
  hc_rangeSelector(selected = 7) %>%
  hc_navigator(series = list(color = hex_to_rgba('black',1)), top = 580) %>%
  hc_xAxis(type = 'datetime') %>% 
  hc_legend(enabled = TRUE, layout = 'proximate', align = 'left', floating = FALSE) %>%
  hc_yAxis_multiples( 
    #yAxis = 0, plot x11 and x12 here
    list(top = "0%",  height = '60%', opposite = FALSE, type = 'logarithmic', showLastLabel = TRUE, allowDecimals = FALSE, 
         labels = list(align = 'right', x = -10, format = '{value}%', distance = 0), gridLineDashStyle = 'Dot', gridLineColor = glc, startOnTick = FALSE, endOnTick = TRUE),

    #yAxis = 1 to duplicate axis labels on opposite side    
    list(top = "0%",  height = '60%', opposite = TRUE, type = 'logarithmic', showLastLabel = TRUE, allowDecimals = FALSE, linkedTo = 0, opposite = TRUE, 
         labels = list(align = 'right', x =  50, format = '{value}%', distance = 0), gridLineDashStyle = 'Dot', gridLineColor = glc, startOnTick = FALSE, endOnTick = TRUE),

    #yAxis = 2, just to separate the charts
    list(top = '60%', height = '5%'),

    #yAxis = 3, plot x2 here
    list(top = '65%', height = '15%', opposite = FALSE, tickPositions = c(0, 33, 67, 100), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
         labels = list(align = 'right', x= 35, format = '{value}%', distance = 0)),

    #yAxis = 4, to duplicate the axis labels on the opposite side
    list(top = '65%', height = '15%', linkedTo = 3, opposite = TRUE, tickPositions = c(0, 33, 67, 100), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
         labels = list(align = 'right', x= 50, format = '{value}%', distance = 0)),

    #yAxis = 5, to separate the charts
    list(top = '80%', height = '5%'),

    #yAxis = 6, plot x31, x32, x33 here
    list(top = '85%', height = '15%', opposite = FALSE, tickPositions = c(-2, -1, 0, 1, 2), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
         labels = list(align = 'right', x = 30, distance = 0, format = '{value:.1f}'), plotLines = list(list(color = "black", width = 2, value = 0))),

    #yAxis = 7, to duplicate the axis labels on the opposite side
    list(top = '85%', height = '15%', linkedTo = 6, opposite = TRUE, tickPositions = c(-2, -1, 0, 1, 2), gridLineDashStyle = 'Dot', gridLineColor = glc, showLastLabel = TRUE,
         labels = list(align = 'right', x = 50, distance = 0, format = '{value:.1f}'))

  ) %>%


  #Chart 1
  hc_add_series(x11, yAxis = 0, color = 'navy',   name = 'Series 11', tooltip = list(valueDecimals = 1, valueSuffix = '%')) %>%  
  hc_add_series(x12, yAxis = 0, color = 'green',  name = 'Series 12', tooltip = list(valueDecimals = 1, valueSuffix = '%')) %>% 

  #Chart 2
  hc_add_series(x2, yAxis = 3, color = 'black', name = 'Series 2', tooltip = list(valueDecimals = 0, valueSuffix = '%')) %>%

  #Chart 3
  hc_add_series(x31,  yAxis = 6, color = 'blue',  name = 'Series 31', tooltip = list(valueDecimals = 2)) %>%
  hc_add_series(x32,  yAxis = 6, color = 'green', name = 'Series 32', tooltip = list(valueDecimals = 2))


print(hc)

К сожалению, в Highstock есть ошибка с этим макетом. Навигатор расположен неправильно - я сообщил об этой ошибке здесь: https://github.com/highcharts/highcharts/issues/13392

В качестве обходного пути я предлагаю переместить навигатор, используя свойство navigator.top , но это не идеальное решение Мы могли бы изменить основной код и написать логи c, которые бы правильно и автоматически размещали навигатор, но для этого требуется некоторая пользовательская JavaScript кодировка.

Если это решение не соответствует вашим требованиям, вы могли бы всегда визуализируйте свои элементы легенды с помощью инструмента Highcharts SVG Renderer, но для этого также требуется специальное кодирование. Вы можете найти множество примеров пользовательских легенд на официальном форуме Highcharts, StackOverflow, или вы можете увидеть эту статью, которую я написал об использовании Renderer: https://support.highcharts.com/support/solutions/articles/44001706971-how-to-use-highcharts-svg-renderer

...