同步两个handsontables的水平滚动
Posted
技术标签:
【中文标题】同步两个handsontables的水平滚动【英文标题】:Synchronize horizontal scrolling of two handsontables 【发布时间】:2017-05-15 00:15:15 【问题描述】:我想在一个闪亮的应用程序中同步两个掌上电脑的滚动。 我根据here 和here 给出的建议尝试了一些尝试。 我也试过jquery.scrollSync library,我的代码如下。 没有任何效果。
library(shiny)
library(rhandsontable)
ui = shinyUI(fluidPage(
tags$head(tags$script(src = "http://trunk.xtf.dk/Project/ScrollSync/jquery.scrollSync.js")),
sidebarLayout(
sidebarPanel(),
mainPanel(
rHandsontableOutput("hot", width = 350),
rHandsontableOutput("hot2", width = 350),
singleton(
tags$script(html('$("#hot").addClass("scrollable");'))
),
singleton(
tags$script(HTML('$("#hot2").addClass("scrollable");'))
),
singleton(
tags$script(HTML('$(".scrollable").scrollSync();'))
)
)
)
))
server = shinyServer(function(input, output, session)
values = reactiveValues()
data = reactive(
if (!is.null(input$hot))
DF = hot_to_r(input$hot)
else
if (is.null(values[["DF"]]))
DF = mtcars[1:3,]
else
DF = values[["DF"]]
values[["DF"]] = DF
DF
)
output$hot <- renderRHandsontable(
DF = data()
if (!is.null(DF))
rhandsontable(DF, stretchH = "all")
)
output$hot2 <- renderRHandsontable(
rhandsontable(mtcars[1:3,], stretchH = "all")
)
)
runApp(list(ui=ui, server=server))
编辑
以下是使用scrollViewportTo
的不成功尝试。
library(shiny)
library(rhandsontable)
jscode <- "
$('#scroll').on('click', function ()
$('#hot').scrollViewportTo(1,5);
);
"
ui = shinyUI(fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("scroll", "Scroll")
),
mainPanel(
rHandsontableOutput("hot", width = 350),
singleton(
tags$script(HTML(jscode))
)
)
)
))
server = shinyServer(function(input, output, session)
values = reactiveValues()
data = reactive(
if (!is.null(input$hot))
DF = hot_to_r(input$hot)
else
if (is.null(values[["DF"]]))
DF = mtcars[1:3,]
else
DF = values[["DF"]]
values[["DF"]] = DF
DF
)
output$hot <- renderRHandsontable(
DF = data()
if (!is.null(DF))
rhandsontable(DF, stretchH = "all")
)
)
runApp(list(ui=ui, server=server))
【问题讨论】:
你可能想看看:docs.handsontable.com/0.29.2/Core.html#scrollViewportTo 和 docs.handsontable.com/0.29.2/… 谢谢@HubertL,我会试试的。 @HubertL 我试过scrollViewportTo
,但没有成功。我已将我的尝试包含在我的 OP 中。可能选择器方式$("#hot").scrollViewportTo
不是用的方式。
【参考方案1】:
解决方案。我的情况很具体:第二个表只有一行,列数与第一个表相同,用户只滚动第一个表。
也可以让两个表的列宽相同,但是下面的代码没有这样做。
如果滚动不是连续的,如果是逐行跳转就更好了。 已解决: 见最后编辑。
library(shiny)
library(rhandsontable)
js_getViewport <- "
$(document).ready(setTimeout(function()
var hot_instance = HTMLWidgets.getInstance(hot).hot
hot_instance.updateSettings(width: hot_instance.getSettings('width').width + Handsontable.Dom.getScrollbarWidth(hot))
var colPlugin = hot_instance.getPlugin('autoColumnSize');
hot_instance.addHook('afterScrollHorizontally', function()changeViewport2(colPlugin));
, 2000)
)
"
js_setViewport <- "
function changeViewport2 (colPlugin)
var colStart = colPlugin.getFirstVisibleColumn();
var hot2_instance = HTMLWidgets.getInstance(hot2).hot;
hot2_instance.scrollViewportTo(0, colStart, false, false);
;
"
ui = shinyUI(fluidPage(
tags$head(tags$script(HTML(js_getViewport)),
tags$script(HTML(js_setViewport))),
sidebarLayout(
sidebarPanel(
),
mainPanel(
rHandsontableOutput("hot", height=200),
br(),
rHandsontableOutput("hot2", height=100)
)
)
))
server = shinyServer(function(input, output, session)
values = reactiveValues()
data = reactive(
if (!is.null(input$hot))
DF = hot_to_r(input$hot)
else
if (is.null(values[["DF"]]))
DF = mtcars[,]
else
DF = values[["DF"]]
values[["DF"]] = DF
DF
)
rowHeaderWidth <- reactive(
max(100,floor(max(nchar(rownames(values[["DF"]])))*8))
)
output$hot <- renderRHandsontable(
DF = data()
if (!is.null(DF))
rhandsontable(DF, stretchH = "none", useTypes=TRUE,
width = 500,
rowHeaderWidth = rowHeaderWidth())
)
output$hot2 <- renderRHandsontable(
rhandsontable(mtcars[1,], stretchH = "none", useTypes=TRUE,
width = 500,
rowHeaderWidth = rowHeaderWidth())
)
)
runApp(list(ui=ui, server=server))
编辑:
为了更好的对齐,使用:
js_setViewport <- "
function changeViewport2 (colPlugin)
var colStart = colPlugin.getFirstVisibleColumn();
var hot2_instance = HTMLWidgets.getInstance(hot2).hot;
hot2_instance.scrollViewportTo(0, colStart, false, false);
//
var hot_instance = HTMLWidgets.getInstance(hot).hot;
var rowStart = hot_instance.getPlugin('autoRowSize').getFirstVisibleRow();
hot_instance.scrollViewportTo(rowStart, colStart, false, false);
;
【讨论】:
以上是关于同步两个handsontables的水平滚动的主要内容,如果未能解决你的问题,请参考以下文章
Handsontable:jquery 合并标题,水平滚动错误