Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin #28

Closed
Fooourche opened this issue Jan 27, 2016 · 42 comments
Closed

Plugin #28

Fooourche opened this issue Jan 27, 2016 · 42 comments

Comments

@Fooourche
Copy link

Hi everybody

Great package, simplify a lot of work.
Is there a way to add a highchart plugin : the draggable-points.js to higcharter ? Would be great if it's easy.

Thks for help
Fabien

@jbkunst
Copy link
Owner

jbkunst commented Jan 27, 2016

Hi @Fooourche 😄

Is simple to add but I need to check this plugin dont break other functionalities like maps, etc. Anyway, what situation motivates you to have this plugin ;)?

Regards,

@Fooourche
Copy link
Author

Hi Joshua,

Thanks for the quick reply.

I've been doing a shiny app which graphs via higcharts weather forecast
series from model output and my dream would be that the user can be able to
drag the forecast serie to make "an expertise forecast" and to save his
scenario.
Do you think it's possible ?

Ths a lot
Fabien

2016-01-27 21:38 GMT+01:00 Joshua Kunst notifications@github.com:

Hi @Fooourche https://github.com/Fooourche [image: 😄]

Is simple to add but I need to check this plugin dont break other
functionalities like maps, etc. Anyway, what situation motivates you to
have this plugin ;)?

Regards,


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Jan 30, 2016

Hi,

I think it's possible with a little javascript code.

I added the plugin and it seems all work:

http://jkunst.com/highcharter/#draggable-points
http://rpubs.com/jbkunst/highcharter-draggable

In the next week I'll work in your idea and publish here https://jbkunst.shinyapps.io/highcharter/

Let me know if you use this plugin ;)!

@jbkunst jbkunst closed this as completed Jan 30, 2016
@Fooourche
Copy link
Author

Thanks a lot Joshua !! i'll test tomorow. Let me know if u handle my
problem.

Thks
Fabien

2016-01-31 0:44 GMT+01:00 Joshua Kunst notifications@github.com:

Hi,

I think it's possible with a little javascript code.

I added the plugin and it seems all work:

http://jkunst.com/highcharter/#draggable-points
http://rpubs.com/jbkunst/highcharter-draggable

In the next week I'll work in your idea and publish here
https://jbkunst.shinyapps.io/highcharter/

Let me know if you use this plugin ;)!


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Feb 1, 2016

Hey Fabien,

I think I get what you want. It was fun. Check https://jbkunst.shinyapps.io/highcharter/ the time series item.

The key parts were:

  • In highcharts use the drop event (JS code).
  • In the previous code event use the Shiny.onInputChange('manualforecast', data). This tell shiny that manualforecast data has change so you can use in a render function.
  • Then create a renderObject calling input$manualforecast So you can get the updated data and do whatever you want.

Tell me if this help you ;)!

@jbkunst jbkunst added this to the v0.2.0 milestone Feb 3, 2016
@Fooourche
Copy link
Author

Hi Joshua,

I get some time to code and i tried to go back to your application but it's
currently unavailable (https://jbkunst.shinyapps.io/highcharter/)
Are u doing an update, do i have to wait ?

Thanks
Fabien

2016-02-01 17:11 GMT+01:00 Joshua Kunst notifications@github.com:

Hey @Fooourche https://github.com/Fooourche

I think I get wat you want. It was fun. Check
https://jbkunst.shinyapps.io/highcharter/ the time series item.

The key parts were:

  • In highcarts use the drop event.
  • In the previous code event use the Shiny.onInputChange('manualforecast',
    data). This tell shiny that manualforecast data has chage so you can
    use in a render function.
  • Then create a renderObject calling input$manualforecast So you can
    get the updated data and do whatever you want.

Tell me if this help you ;)!


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Feb 9, 2016

Hi Fabien,

I reached the limit in the free plan. Sorry.

Try with:

runGitHub("jbkunst/shiny-apps", subdir = "highcharter")

@Fooourche
Copy link
Author

Thanks,

I'm going to try.
By the way, i'm trying the plotbands option and he doesn t want to do the
job telling me 'Error in FUN(X[[i]], ...) :
'options' must be a fully named list, or have no names (NULL)'

I followed the example, so do u have an idea ?

Thanks

Fabien

2016-02-09 13:50 GMT+01:00 Joshua Kunst notifications@github.com:

I reached the limit in the free plan. Sorry.

Try with:

runGitHub("jbkunst/shiny-apps", subdir = "highcharter")


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Feb 9, 2016

Always is good send the code you try tu run ;)! It's easy for me to replicate the error. I'm not sure what example your'e trying to do. Can you paste it?

@Fooourche
Copy link
Author

Sorry,

Here are the datas in the rda files and here is the code i try to run :

highchart() %>%
hc_title(text = paste("Hypso :")) %>%
hc_add_series(name = "Hypso", data =rev(hypso.bv.unit.to.plot$alti))
%>%
hc_xAxis(categories = round(hypso.bv.unit.to.plot$pourcentage,0)) %>%
hc_yAxis(title = list(text = "Altitude en Metres"),
opposite = FALSE,
minorTickInterval = "auto",
minorGridLineDashStyle = "LongDashDotDot",
showFirstLabel = FALSE,
showLastLabel = FALSE,
plotBands = list(
list(from = 0, 1500, color = "rgba(68, 170, 213,
0.1)",label = list(text = "Pluie")),
list(from = 1500, to = JS("Infinity"), color = "rgba(0, 0,
0, 0.1)",label = list(text = "Neige"))
))

2016-02-09 14:57 GMT+01:00 Joshua Kunst notifications@github.com:

Always is good send the code you try tu run ;)! It's easy for me to
replicate the error. I'm not sure what example your'e trying to do. Can you
paste it?


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Feb 9, 2016

change

  list(from = 0, 1500, color

to

  list(from = 0, to = 1500, color

@Fooourche
Copy link
Author

waw what a stupid error, sorry for the wast of time

Fabien
++

2016-02-09 16:30 GMT+01:00 Joshua Kunst notifications@github.com:

change

list(from = 0, 1500, color

to

list(from = 0, to = 1500, color


Reply to this email directly or view it on GitHub
#28 (comment).

@jbkunst
Copy link
Owner

jbkunst commented Feb 9, 2016

No problem ;)

@tbenschop
Copy link

Hi Joshua @jbkunst,

If you have two draggable lines, how should you cope with that?

Tim

@jbkunst
Copy link
Owner

jbkunst commented Feb 15, 2016

Hi Tim @tbenschop

You can know/detect the series name with/using this.series.name. Check http://jkunst.com/highcharter/plugins.html#draggable-points. I guess you can do somethig like:

Shiny.onInputChange('inputname', this.series.name)

And:

whichseries <- input$inputname

@tbenschop
Copy link

Thanks for the quick reply @jbkunst. Maybe my question was not clear enough. I want to give the user the flexibility to change 2 lines in a chart and show the data points for both lines in a table.

@jbkunst
Copy link
Owner

jbkunst commented Feb 15, 2016

Maybe something like:

JS():

data = _.map(this.series.data, function(e) { return e.y })
if(this.series.name == 'line1) {
  Shiny.onInputChange('line1', data)
} else {
  Shiny.onInputChange('line2', data)
}

And:

output$table <- tableOutput({
  data.frame(input$line1, input$line2)
})

Something like that.

@tbenschop
Copy link

Thanks @jbkunst

@tbenschop
Copy link

Hi Joshua,@jbkunst
What if you would like the if(this.series.name== 'line1' to be dynamic based on a user input like input$nameoftheline
Obviously, if(this.series.name== input$nameoftheline won't work.

@jbkunst
Copy link
Owner

jbkunst commented Feb 23, 2016

@tbenschop
Copy link

@jbkunst Thanks. I tried both options form (javascript and jquery) and it doesn't work. The document.getElementById('name').value==this.series.name seems to be always true.. and the example you provided also doesn't work the way I implentend. I have it as an example in my repo: https://github.com/tbenschop/Highcharter if you have time. Otherwise I just try more myself. Nevertheless, thanks a lot Joshua.

@tbenschop
Copy link

@jbkunst Joshua, Would you have time to have a quick look at this? I also created a SO Question
I just can't get it working and I really need it, please let me know if you can help, otherwise I'll try to find another specialist. I understand it if you don't want to help everyone with their private issues. BR Tim

@jbkunst
Copy link
Owner

jbkunst commented Mar 1, 2016

@tbenschop

Add to the javascript event the next code and see the messages to check if the values are the same what you expect

console.log(this.series.name)
are_equal = this.series.name == document.getElementById('name').value
console.log('series name : ' + this.series.name +  ' input name : ' + document.getElementById('name').value + ' are equal ' + are_equal)

window.data = _.map(this.series.data, function(e) { return e.y })

if(this.series.name==document.getElementById('name').value){
  console.log('sending data to line1 value')
  Shiny.onInputChange('line1', data)
 } else {  
  console.log('sending data to line2 value')
    Shiny.onInputChange('line2', data)
}

If NOT what you expect maybe you need tofix the code. If IS what you expect, tell me again what you try to do because I lost the point ;).

Finally, it's much better to put a lot of console.log to know what is going on :D in the development process.

gl

@tbenschop
Copy link

@jbkunst Thanks, this works. Let me explain what I try to do:
We have a graph with 6 different time series from which the user has to select two. These 2 lines appear in the graph and the user can alter the data points with the dragging option. We need to capture these new points in a table. So if the user selects time series "A" and "C", we want that the columns "A" and "C" from the data.frame are altered. But if "A" and "D" are selected, "A" and "D" need to change in the data.frame. Therefore I needed the this.series.name to be flexible based on a user-defined time series.

@jbkunst
Copy link
Owner

jbkunst commented Mar 2, 2016

@tbenschop I see a little clearer now. Did you have succes now?

@tbenschop
Copy link

@jbkunst Yes it works, thanks a lot. I hate it to ask that many questions as my javascript knowledge is that little... Is it also possible to refresh the table not only with the Shiny.onInputChange() but also when the input parameter is changed from i.e. "A" to "C" (or First to Second in my example). Currently the JS is only triggered when the line is dragged.

@tbenschop
Copy link

@jbkunst Seems that this does not work when the selectInput filter is a renderUI filter. JS doesn't seem to find the value then as described here: daattali/shinyjs#33
edit: This is also reported in another JS package and fixed (search for renderui)

@jbkunst
Copy link
Owner

jbkunst commented Mar 2, 2016

@tbenschop

Did you generate the selectInput via a renderUI, right? Is this really necessary?

@tbenschop
Copy link

@jbkunst

Yes unfortunately I need it.... I've spend the entire day with this workaround: https://gist.github.com/jcheng5/8441665 and have not succeeded yet but I'm getting close.

@jbkunst
Copy link
Owner

jbkunst commented Mar 2, 2016

@tbenschop

Maybe you can re-chart the highchart when you remake the ui.

gl

@tbenschop
Copy link

@jbkunst Thanks for the suggestion but I fixed it with JS and some logic:

new ui's to identify which filter it is:

  output$name1<-renderUI({      selectInput("name1",label = "name1",choices =    c("A"="1A","B"="1B","C"="1C"),selected = "1A")})
  output$name2<-renderUI({      selectInput("name2",label = "name2",choices = c("A"="2A","B"="2B","C"="2C"),selected = "2A")}) 

JS in graph:

  hc_plotOptions(
    series = list(
      events=list(
        afterAnimate = JS("function(){

$(document).on('change', 'input.shiny-bound-input, select.shiny-bound-input', function(e){
     $target = $(e.target)

                          console.log($target.val());
         if($target.val().substring(0,1)=='1'){ 
Shiny.onInputChange('dropdown_change1', $target.val())
         }
         if($target.val().substring(0,1)=='2'){ 
Shiny.onInputChange('dropdown_change2', $target.val())
         }
})
console.log($target.val().substring(0,1)+'substring')
        }
        ")
      ),
      #stickyTracking = FALSE,
      point = list(
        events = list(
          drop = JS("
function(){
window.data = _.map(this.series.data, function(e) { return e.y })

         if(this.series.name.substring(0,1)=='2'){ 
Shiny.onInputChange('timeseries2', data)
}

         if(this.series.name.substring(0,1)=='1'){ 
Shiny.onInputChange('timeseries1', data)
}
         if(this.series.name.substring(0,1)=='1'){ 
Shiny.onInputChange('changed_series_drag1', this.series.name)
}
         if(this.series.name.substring(0,1)=='2'){ 
Shiny.onInputChange('changed_series_drag2', this.series.name)
  }
}


"
                    )

update table:

x<-FALSE
y<-FALSE
if(!is.null(input$dropdown_change1)) x<-(input$dropdown_change1!=input$changed_series_drag1)   
if(!is.null(input$dropdown_change2)) y<-(input$dropdown_change2!=input$changed_series_drag2)

if(is.null(input$timeseries1)|x)var1<-c(7.0, 6.9, 9.5, 14.5, 18.2) else var1<-input$timeseries1
if(is.null(input$timeseries2)|y)var2<-c(24.5, 18.2, 21.5, 25.2, 26.5)else var2<-input$timeseries2

If you are interested in the total code you can check it out on my github
Many thanks for the hard work on this package Joshua.

@tbenschop
Copy link

@jbkunst Do you know if there is already a solution for the renderui issue? My filters are becoming more complex and the logic is getting overly complex...

@jbkunst
Copy link
Owner

jbkunst commented Mar 15, 2016

Hi @tbenschop

If your think the app is getting too comlpex maybe you should rethink about how you are developing the app, may be separate funcionalities in litter ones, etc. I dont know your app but remeber shiny is dashboard oriented and not for ultracomplex sites (exagerating) . If you think the way your doing is THE ONLY way, then assume it and do it: The app's complexity is proportional to the code complexity.

@tbenschop
Copy link

@jbkunst I think you are right......

@tbenschop
Copy link

Hi @jbkunst

I think there has something changed wrt the dragging function in the latest version of highcharter. My sample app (on GitHub) does not work with the latest version, it does work with 0.2.0.

@jbkunst
Copy link
Owner

jbkunst commented Mar 29, 2016

Thanks. I'll check.

jbkunst added a commit that referenced this issue Mar 29, 2016
@jbkunst
Copy link
Owner

jbkunst commented Mar 29, 2016

@tbenschop

I made a mistake, I removed underscore (_.map). I add that script again and your shiny sample works.

I recommend use animate=FALSE to remove the redraw effect every time you drag a point.

Thanks for report the issue!

@tbenschop
Copy link

@jbkunst Thanks for the fix!

@tbenschop
Copy link

@jbkunst Is it also possible to create a waterfall like this? I tried it but didn't get it to work. I guess you have to do something different with the data call as the 'funnel' example from your site.

@jbkunst
Copy link
Owner

jbkunst commented Apr 11, 2016

@tbenschop

Can you share your code? Let's start from that ;).

I don't see any tricky part in the example so I almost sure we can plot waterfalls.

@tbenschop
Copy link

@jbkunst Thanks for the quick reply. It now worked, I forgot to let the hc_series to start with a list.

Everything works except the Highcharts.numberformat under the dataLabels.

library(highcharter)
cbbPalette <- c("#000000", "#00B0F0", "#AEE934", "#5E36F2", "#fefe00", "#FF5B51", 
                "#173F17", "#c8021c", "#090F6B", "#FF399D", "#59879b", "#fe9ba2",
                "#FF9C51")


highchart() %>% 
  hc_chart(type = "waterfall") %>% 
  hc_title(text = "Higcharts Waterfall") %>% 
  hc_xAxis(type = 'Category') %>% 
  hc_yAxis(title=list(text='USD')) %>% 
  hc_legend(enabled=FALSE)%>%
  hc_tooltip(pointFormat="<b>${point.y:,.2f}</b> USD")%>%
  hc_series(list(upColor=cbbPalette[1],
            color=cbbPalette[2],
            data=
    list(
      list(
      name = "Start",
      y = 120000
    ),
    list(
      name = "Product Reveneu",
      y= 569000
      ),
    list(
      name="Service Revenue",
      y=231000),
    list(
      name='Positive Balance',
      isIntermediateSum=TRUE,
      color=cbbPalette[3]
    ),
    list(
      name="Fixed Costs",
      y=-342000
    ),
    list(
      name='Variable Costs',
      y=-233000
      ),
    list(
      name='Balance',
      isSum=TRUE,
      color=cbbPalette[3]
    ))
    ,
    dataLabels=list(
      enabled=TRUE,
      #formatter=function(){
      #  return Highcharts.numberFormat(this.y / 1000, 0, ',') + 'k';
      #},
      style=list(
        color="#FFFFFF",
        fontWeight="bold",
        textShadow="0px 0px 3px black"
      )
    ),
    pointPadding=0
    ))

Great that this also works! Thanks.

@jbkunst
Copy link
Owner

jbkunst commented Apr 11, 2016

@tbenschop

Please remember, in the highcharts exampels, all the functions arguments you need to apply the JS() function. So:

formatter= JS("function(){ return Highcharts.numberFormat(this.y / 1000, 0, ',') + 'k';}"),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants