#javascript #r #plotly #flexdashboard #crosstalk
Вопрос:
В настоящее время я работаю над продуктом R-flexdashboard без блеска. Цель состоит в том, чтобы иметь на графике эволюцию цен на различные продукты разных компаний. У меня есть сюжетная линия и 2 перекрестных фильтра вверху, которые позволяют мне фильтровать по компании и/или продукту. Эта часть работает нормально.
Тем не менее, я хочу, чтобы эти линии были прекращены, если у меня нет цен в течение нескольких дней или если продукт не был доступен в то время. Для этого я понял, что мне нужно создать строки в своем наборе данных, где цена равна NA или NaN, а затем установить параметр plotly «connectgaps = FALSE». Это также работает без проблем.
Проблема, с которой я сталкиваюсь, заключается в том, что если у меня есть NA/NaN для данного продукта, этот продукт появится в легенде моего сюжета, хотя этого не должно быть из-за фильтров, и он не исчезнет.
Вот пример, где я выбираю компанию A, и отображаются только 2 ее продукта. Однако продукты B2 и C1 отображаются в легенде…
Вот некоторый код, иллюстрирующий мою проблему.
--- title: "Stack example" output: flexdashboard::flex_dashboard: orientation: columns vertical_layout: fill --- Overview {data-orientation=columns} ======================================================================= column{.tabset} ----------------------------------------------------------------------- ### Example ```{r} library(flexdashboard) library(tidyverse) library(lubridate) library(plotly) library(crosstalk) library(RColorBrewer) my_table = tibble( date = c("10.11.2021", "10.11.2021", "10.11.2021", "10.11.2021", "10.11.2021", "10.11.2021", "11.11.2021", "11.11.2021", "11.11.2021", "11.11.2021", "11.11.2021", "11.11.2021", "12.11.2021", "12.11.2021", "12.11.2021", "12.11.2021", "12.11.2021", "12.11.2021", "13.11.2021", "13.11.2021", "13.11.2021", "13.11.2021", "13.11.2021", "13.11.2021", "14.11.2021", "14.11.2021", "14.11.2021", "14.11.2021", "14.11.2021", "14.11.2021", "15.11.2021", "15.11.2021", "15.11.2021", "15.11.2021", "15.11.2021", "15.11.2021"), company = c("A", "A", "B", "B", "B", "C", "A", "A", "B", "B", "B", "C", "A", "A", "B", "B", "B", "C", "A", "A", "B", "B", "B", "C", "A", "A", "B", "B", "B", "C", "A", "A", "B", "B", "B", "C"), product = c("A1", "A2", "B1", "B2", "B3", "C1", "A1", "A2", "B1", "B2", "B3", "C1", "A1", "A2", "B1", "B2", "B3", "C1", "A1", "A2", "B1", "B2", "B3", "C1", "A1", "A2", "B1", "B2", "B3", "C1", "A1", "A2", "B1", "B2", "B3", "C1"), price = c(5, 10, 15, 20, 25, 45, 25, 10, 15, 20, 25, 45, 15, 15, 20, 25, 30, 50, 15, 15, 20, NaN, 30, NaN, 10, 10, 15, 20, 25, 45, 10, 10, 15, 20, 25, 45) ) %gt;% mutate(date = lubridate::dmy(date)) a_palette = brewer.pal(9, 'Blues')[c(4,6)] b_palette = brewer.pal(9, 'Reds')[c(4,6,8)] c_palette = brewer.pal(9, 'Greens')[5] pal = c(a_palette, b_palette, c_palette) pal = setNames(pal, unique(my_table$product)) my_table = my_table %gt;% arrange(date, product) share = SharedData$new(my_table) # ------------------------------------------------------------------------------------------------- bscols(widths = c(6,6), filter_select(id = 'company', label = 'Company', sharedData = share, group = ~company, multiple = TRUE), filter_select(id = 'product', label = 'Product', sharedData = share, group = ~product, multiple = TRUE)) plot_ly(share, x = ~date, y = ~price, type = 'scatter', mode = 'lines markers', color = ~product, colors = pal, height = 525, connectgaps = FALSE, hoverlabel = list(namelength = - 1)) %gt;% layout(hovermode = 'x', title = list(text = 'Market prices'), xaxis = list(title = 'Date'), yaxis = list(title = 'Price', range = list(0, 60), autorange = FALSE, fixedrange = FALSE))
I have no idea how to fix this as it seems to be a bug to me. I considered trying to add some html/javascript to hide the elements in the legend that shouldn’t be displayed every time one of the 2 filters is used but I have no idea where to start, don’t know if this kind of interactivity is doable on a single .html file, and don’t know any javascript at the moment.
The idea would be to do in pseudocode something like —gt;
When updating the filter values: for (i in legends): if (string(legend.text) exists in company_filter.text) do nothing else set.value of some html/css attribute in order not to display this part of the legend.
Любые советы будут высоко оценены.
Спасибо вам за вашу помощь !