- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在制作一个交互式图形,为 2 个定量变量(A 和 B)绘制黑点。用户可以选择阈值。执行此操作后,仅绘制高于阈值幅度的点,并且还绘制表示未通过阈值的区域的灰色矩形。这一切似乎运行良好。
但是,我现在想要实现的是允许用户选择某些点。执行此操作时,所选点应从黑色变为红色。当用户选择新的点子集时,先前选择的点从红色返回到黑色。换句话说,图中唯一显示红色的点应该是最后选择的点。
不幸的是,这部分似乎不起作用。目前的问题是:
1) 选定的点永久保持红色。2) 如果选择了已经是红色的点,有时未选择的黑点会变成红色。您可以在帖子底部看到此错误的示例(在图片中)。
我相信这种情况正在发生,因为我只是绘制了与所选 x 和 y 值相对应的全新红点轨迹(这在下面的代码中注释为“//以红色添加用户选择的点”)。因此,红点成为它们自己的实体。
我的问题是:解决这个问题的有效方法是什么(以便选定的点变成红色,直到选择另一个子集?)我使用术语“高效”,因为我正在处理大型数据集(100-1,000 个点) ,所以我正在寻找节省计算速度的方法。简单地将选定的黑点修改为红色而不是完全重绘叠加的红点可能更有效?但是,我不确定如何使用 Plotly 跟踪语法来实现这一点。
任何帮助将不胜感激。
下面是我的脚本的简化版本。
library(plotly)
library(GGally)
library(htmlwidgets)
ui <- shinyUI(fluidPage(
sliderInput("thresh", "Threshold:", min = 0, max = 3, value=1, step=1),
plotlyOutput("myPlot"),
textOutput("selectedValues")
))
server <- shinyServer(function(input, output) {
thresh <- reactive(input$thresh)
set.seed(1)
dat <- data.frame(Row = paste0("Row",sample(c(1:20),20)), A=4*rnorm(20), B=4*rnorm(20))
dat$Row <- as.character(dat$Row)
minVal = min(dat[,-1])
maxVal = max(dat[,-1])
gg <- ggplot(data = dat, aes(x=A, y=B)) + coord_cartesian(xlim = c(minVal, maxVal), ylim = c(minVal, maxVal))
ggY <- ggplotly(gg)
output$myPlot <- renderPlotly(ggY %>% onRender("
function(el, x, data) {
var Points = [];
var Traces = [];
var selRows = [];
data.dat.forEach(function(row){
if(Math.abs(row['B']) > data.thresh) selRows.push(row);});
var xArr = [];
var yArr = [];
var keepIndex = [];
for (a=0; a<selRows.length; a++){
xArr.push(selRows[a]['A'])
yArr.push(selRows[a]['B'])
keepIndex.push(selRows[a]['Row'])
}
Points.push(keepIndex);
// Add points above the threshold in black
var tracePoints = {
x: xArr,
y: yArr,
hoverinfo: 'none',
mode: 'markers',
marker: {
color: 'black',
size: 4
}
};
// Add upper horizontal line of gray box
var hiLine = {
x: [-15,15],
y: [data.thresh,data.thresh],
mode: 'lines',
line: {
color: 'gray',
width: 1
},
opacity: 0.25,
hoverinfo: 'none'
};
// Add lower horizontal line of gray box
var lowLine = {
x: [-15,15],
y: [-1*data.thresh,-1*data.thresh],
mode: 'lines',
fill: 'tonexty',
line: {
color: 'gray',
width: 1
},
opacity: 0.25,
hoverinfo: 'none'
};
Traces.push(tracePoints);
Traces.push(hiLine);
Traces.push(lowLine);
Plotly.addTraces(el.id, Traces);
var idRows = []
for (a=0; a<data.dat.length; a++){
idRows.push(data.dat[a]['Row'])
}
el.on('plotly_selected', function(e) {
numSel = e.points.length
cN = e.points[0].curveNumber;
var pointNumbers = [];
var selData = [];
for (a=0; a<numSel; a++){
pointNumbers.push(e.points[a].pointNumber)
selData.push(data.dat[idRows.indexOf(Points[0][pointNumbers[a]])])
}
Shiny.onInputChange('selData', selData);
var Traces = [];
var xArr = [];
var yArr = [];
for (a=0; a<selData.length; a++){
xArr.push(selData[a]['A'])
yArr.push(selData[a]['B'])
}
// Add user-selected points in red
var traceRed = {
x: xArr,
y: yArr,
mode: 'markers',
marker: {
color: 'red',
size: 4
},
hoverinfo: 'none'
};
Traces.push(traceRed);
Plotly.addTraces(el.id, Traces);
})
}", data = list(dat=dat, thresh=thresh())))
selData <- reactive(input$selData)
output$selectedValues <- renderPrint({selData()})
})
shinyApp(ui, server)
以下是错误示例:
比如说,我使用所有默认设置打开应用程序,然后简单地通过绘图选择最右边的四个点。结果看起来不错,因为只有这四个点被涂成红色,如下所示:
现在,假设我重新选择前四点。结果看起来不再很好,因为即使这四个点被涂成红色,另外两个点也被错误地涂成红色:
最佳答案
处理此问题的最简单方法是简单地跟踪您是否选择了某些内容,并删除包含先前选择的点的先前轨迹。为了实现这一目标,进行了以下更改:
nseltrace
来跟踪我们选择事物的频率Plotly.deleteTraces
语句来删除最后一条跟踪(可以使用索引 -1 指定。if (nseltrace>0)
语句保护。verbatumTextOutput
来打印它们,因为它是一种更清晰的格式。curveNumber
1 的点,即原始数据,而不是随后选定的迹线。这导致已选择的点在新选择的列表中输入两次。至于这是否是最有效的方法,显然取决于情况。您正在将选定的点绘制在之前未选定的表示上,最坏的情况将是两倍,但点绘制速度非常快,并且一小部分点的典型减速可能甚至无法测量。我不会对此进行优化,除非后来证明它是一个问题,然后我会使用最新的plotly,因为plotly代码库中当前正在进行大量优化(和错误删除)。
这是代码:
library(plotly)
library(GGally)
library(htmlwidgets)
library(shiny)
ui <- shinyUI(fluidPage(
sliderInput("thresh", "Threshold:", min = 0, max = 3, value=1, step=1),
plotlyOutput("myPlot"),
verbatimTextOutput("selectedValues")
))
server <- shinyServer(function(input, output) {
thresh <- reactive(input$thresh)
set.seed(1)
dat <- data.frame(Row = paste0("Row",sample(c(1:20),20)), A=4*rnorm(20), B=4*rnorm(20))
dat$Row <- as.character(dat$Row)
minVal = min(dat[,-1])
maxVal = max(dat[,-1])
gg <- ggplot(data = dat, aes(x=A, y=B)) + coord_cartesian(xlim = c(minVal, maxVal), ylim = c(minVal, maxVal))
ggY <- ggplotly(gg)
output$myPlot <- renderPlotly(ggY %>% onRender("
function(el, x, data) {
var Points = [];
var Traces = [];
var selRows = [];
data.dat.forEach(function(row){
if(Math.abs(row['B']) > data.thresh) selRows.push(row);});
var xArr = [];
var yArr = [];
var keepIndex = [];
for (a=0; a<selRows.length; a++){
xArr.push(selRows[a]['A'])
yArr.push(selRows[a]['B'])
keepIndex.push(selRows[a]['Row'])
}
Points.push(keepIndex);
// Add points above the threshold in black
var tracePoints = {
x: xArr,
y: yArr,
hoverinfo: 'none',
mode: 'markers',
marker: {
color: 'black',
size: 4
}
};
// Add upper horizontal line of gray box
var hiLine = {
x: [-15,15],
y: [data.thresh,data.thresh],
mode: 'lines',
line: {
color: 'gray',
width: 1
},
opacity: 0.25,
hoverinfo: 'none'
};
// Add lower horizontal line of gray box
var lowLine = {
x: [-15,15],
y: [-1*data.thresh,-1*data.thresh],
mode: 'lines',
fill: 'tonexty',
line: {
color: 'gray',
width: 1
},
opacity: 0.25,
hoverinfo: 'none'
};
Traces.push(tracePoints);
Traces.push(hiLine);
Traces.push(lowLine);
Plotly.addTraces(el.id, Traces);
var idRows = []
for (a=0; a<data.dat.length; a++){
idRows.push(data.dat[a]['Row'])
}
var nseltrace = 0;
el.on('plotly_selected', function(e) {
console.log(e.points)
numSel = e.points.length
var pointNumbers = [];
var selData = [];
for (a=0; a<numSel; a++){
if (e.points[a].curveNumber==1){ // restrict to points in the original curve
pointNumbers.push(e.points[a].pointNumber)
selData.push(data.dat[idRows.indexOf(Points[0][pointNumbers[a]])])
}
}
Shiny.onInputChange('selData', selData);
var Traces = [];
var xArr = [];
var yArr = [];
for (a=0; a<selData.length; a++){
xArr.push(selData[a]['A'])
yArr.push(selData[a]['B'])
}
// Add user-selected points in red
var traceRed = {
x: xArr,
y: yArr,
mode: 'markers',
marker: {
color: 'red',
size: 4
},
hoverinfo: 'none'
};
if (nseltrace>0){
Plotly.deleteTraces(el.id,-1)
}
Traces.push(traceRed);
nseltrace = nseltrace+1
Plotly.addTraces(el.id, Traces);
})
}", data = list(dat=dat, thresh=thresh())))
selData <- reactive({
req(input$selData)
rawc <- input$selData
df <- data.frame(t(matrix(rawc,nrow=3)))
names(df) <- names(rawc)[1:3]
df
})
output$selectedValues <- renderPrint({selData()})
})
shinyApp(ui, server)
这是一个屏幕截图:
关于javascript - 在 htmlWidgets 的 onRender() 中修改选定点的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43443218/
我有以下代码来截取“目标”部门的屏幕截图。我在一个网站上找到了这个。但我不知道“onrendered:function() ”是如何工作的。我想问一下“onrendered”是如何使用的?如果我不添加
经过几个小时的实验和阅读,我仍然不明白为什么myTemplate.onRendered(function() {...})只调用一次。 根据您阅读的位置,您会获得不同的信息,但显然每次内部 HTML
我有一个自定义控件,用于执行动态数据呈现。此控件包含一组 DataPoint 对象,每个 DataPoint 都根据其位置 在控件中呈现(这些点在 OnRender 方法)。 自定义控件包含许多影响呈
截至最近, meteor 的所有文档都指出 onRendered是一种在模板完成渲染时获取回调的新方法。和 rendered只是为了向后兼容。 但是,这似乎对我不起作用。 onRendered永远不会
我有一个自定义面板,它实现了其子项的良好自定义布局。我想向面板添加一些额外的图形,因此覆盖 OnRender 以添加额外的矩形等。它工作得很好,除了 OnRender 似乎只添加到背景。有没有办法让
我想使用 OnRender 方法在文本框中绘制下划线,但该线绘制在文本框后面。文本框是不透明的,因此看不到下划线。如何在文本框上方绘制内容? protected override void OnRen
这是我的代码, var pdf = function() { console.log(12); var form = $('.container');
我有一个自定义控件 MyControl,它继承自 Canvas,并且在 OnRender-Method 中有自己的逻辑。它应该将一些矩形和文本绘制到绘图上下文中。 public class MyCon
我想在 twitter-bootstrap 的日期时间选择器中禁用过去的日期。例如,用户不能选择当前日期之前的日期。我编写代码 $(function() { var now = new Da
我有一个 iron-router 路由: Router.route('/profiel/bewerken', { subscriptions: function () {
我正在使用 ionic 框架包,并且我有一个侧边栏类。有一个名为 ionSideMenu.snapper 的类,查看源代码,该类是在呈现 ionSideMenuContainer 模板时定义的,因此我
在 Meteor 模板中使用 JQuery 插件时遇到问题。我试过this插件。 // A bunch of items var options = {
我将 PhaserJS 与 MeteorJS 结合起来,我担心 onRendered 回调中会包含大量代码。 为了简单和组织,我想将许多函数拆分到几个不同的文件中。 但是,我需要避免失去范围。如何将一
我想动态地绘制一些东西。以下代码显示了我的 OnRender。我在程序中需要它的地方设置 DrawItem。但是,当我调用 DrawItem =5; 时,我必须调用什么,以便调用 OnRender?
我在 .NET 3.5 中使用 Adorner,我可以通过覆盖 OnRender 进行绘制,但我需要能够重绘装饰器以更改其外观。 本质上,我正在寻找一种方法来清除绘图上下文并再次调用 OnRender
我有一个用于更新特定项目数据的 Iron-router 路由: Router.route('/project/:key/update', { ... }); 每次用户导航到“编辑项目页面”时,我都
父模板onRendered函数在子模板之前调用。如何在子模板渲染后执行父模板函数。 {{#each object}} {{> child}} {{/each}} 现在我需要执行一些
我正在尝试在我的meteor应用程序中使用chartist.js。我将其代码放在 Template.reportPage.onRendered() 中,以便在插入模板 DOM 后生成条形图。我尝试添加
我画了一些椭圆并将它们添加到网格中。 然后我想为每个 Ellipse 添加一些 FormattedText。我可以通过获取椭圆的 RectangleBounds 来做到这一点。 但是下面这个例子: h
我有一个自定义的 TextBox,它覆盖了 OnRender 方法。不幸的是,当我向网格添加超过 143-145 个文本框时,OnRender 无法正常工作。 这是带有 160 个文本框的窗口在 wp
我是一名优秀的程序员,十分优秀!