尝试在 dygraph 中构建隐藏/显示功能时出现 JavaScript 错误(来自 R markdown)

问题描述 投票:0回答:4

我正在使用这个创建一个 dygraph:

 library(dygraphs)
    library(htmlwidgets)
    library(rgl)
    knitr::opts_chunk$set(echo = TRUE)
    knitr::knit_hooks$set(webgl = hook_webgl)
    includeScript('C://Desktop//Javascripts/dygraph.js')
    includeScript('C://Desktop//Javascripts/jquery-3.6.0.js')
    
    df<-data.frame(date = seq(as.Date("1980-03-01), length.out = 100, by="day), Long = rnorm(100,50,10), Medium = rnorm(100,30, 5), Short = rnorm(100,10,2), Very.Short = rnorm(100,5,1))
        
    dygraph(df, elementId="the_plot") %>% dyAxis("y", label= "Value ($s)") %>% dyOptions(labelsUTC = TRUE) %>% dyCrosshair(direction = "vertical") %>% dyHighlight(highlightCircleSize = 5, highlightSeriesBackgroundAlpha = 0.2, hideOnMouseOut = FALSE) %>% dyCallbacks(drawCallback = JS('
  function(dygraph, is_initial) {
    if (!is_initial) return;

    var data = this.dataHandler_.data_;
    var labels = dygraph.getLabels();
    var num_cols = labels.length - 1; // exclude x-axis
    var checkboxes_html = "";

    // generate checkbox HTML for each series
    for (var i = 1; i <= num_cols; i++) {
      var label = labels[i];
      var id = "checkbox" + i;
      checkboxes_html += "<label><input type=\\"checkbox\\" id=\\"" + id + "\\" checked> " + label + "</label><br>";
    }

    // add checkboxes to the page
    $("#checkboxes").html(checkboxes_html);

    // add change event listeners to checkboxes
    $("#checkboxes").find("input[type=checkbox]").change(function() {
      var series = this.id.replace("checkbox", "");
      var show = this.checked;
      dygraph.setVisibility(parseInt(series), show);
    });
  }'))

我正在尝试添加一些复选框,以允许 knitted markdown html 的用户在该 dygraph 上显示和隐藏各个系列。虽然我可以将它编织成 html,但我无法呈现复选框。

我该如何解决这个问题?

javascript jquery r r-markdown dygraphs
4个回答
0
投票

这个有用吗?

library(dygraphs)
library(htmlwidgets)
library(rgl)
knitr::opts_chunk$set(echo = TRUE)
knitr::knit_hooks$set(webgl = hook_webgl)
includeScript('C://Desktop//Javascripts/dygraph.js')
includeScript('C://Desktop//Javascripts/jquery-3.6.0.js')

df <- data.frame(date = seq(as.Date("1980-03-01"), length.out = 100, by="day"), 
                 Long = rnorm(100,50,10), 
                 Medium = rnorm(100,30, 5), 
                 Short = rnorm(100,10,2), 
                 Very.Short = rnorm(100,5,1))

dygraph(df, elementId="the_plot") %>% 
  dyAxis("y", label= "Value ($s)") %>% 
  dyOptions(labelsUTC = TRUE) %>% 
  dyCrosshair(direction = "vertical") %>% 
 dyHighlight(highlightCircleSize = 5, 
highlightSeriesBackgroundAlpha = 0.2, 
hideOnMouseOut = FALSE) %>%
dyCallbacks(drawCallback = JS('
  function(dygraph, is_initial) {
    if (!is_initial) return;

    var data = dygraph.rawData();
    var labels = dygraph.getLabels();
    var num_cols = labels.length - 1; // exclude x-axis
    var checkboxes_html = "";

    // generate checkbox HTML for each series
    for (var i = 1; i <= num_cols; i++) {
      var label = labels[i];
      var id = "checkbox" + i;
      checkboxes_html += "<label><input type=\\"checkbox\\" id=\\"" + id + "\\" checked> " + label + "</label><br>";
    }

    // add checkboxes to the page
    $("#checkboxes").html(checkboxes_html);

    // add change event listeners to checkboxes
    $("#checkboxes").find("input[type=checkbox]").change(function() {
      var series = this.id.replace("checkbox", "");
      var show = this.checked;
      dygraph.setVisibility(parseInt(series), show);
    });
  }
'))

0
投票

如果这不起作用,您可以尝试为它创建一个插件,如下所示:https://rstudio.github.io/dygraphs/gallery-plugins.html

import * as utils from './dygraph-utils';
import DygraphInteraction from './dygraph-interaction-model';
import IFrameTarp from './iframe-tarp';

const SeriesToggle = (function() {

  "use strict";

  /**
   * @constructor
   */
  const SeriesToggle = function() {
    this.checkboxContainer_ = null;
    this.dygraph_ = null;
    this.labels_ = null;
  };

  SeriesToggle.prototype.toString = function() {
    return 'SeriesToggle Plugin';
  };

  SeriesToggle.prototype.activate = function(dygraph) {
    this.dygraph_ = dygraph;
    this.labels_ = dygraph.getLabels();
    return {
      layout: this.layout
    };
  };

  SeriesToggle.prototype.layout = function(e) {
    if (this.checkboxContainer_ === null) {
      this.createCheckboxes_();
    }
    this.positionCheckboxes_();
  };

  SeriesToggle.prototype.createCheckboxes_ = function() {
    const containerDiv = document.createElement('div');
    containerDiv.style.cssText = 'position:absolute;top:0px;right:0px;';
    this.checkboxContainer_ = containerDiv;

    const labels = this.labels_;
    for (let i = 1; i < labels.length; i++) {
      const label = labels[i];
      const input = document.createElement('input');
      input.type = 'checkbox';
      input.checked = true;
      input.onclick = this.checkboxClickHandler_(label);
      containerDiv.appendChild(input);

      const span = document.createElement('span');
      span.innerHTML = label;
      containerDiv.appendChild(span);
    }
    this.dygraph_.graphDiv.appendChild(containerDiv);
  };

  SeriesToggle.prototype.positionCheckboxes_ = function() {
    const area = this.dygraph_.getArea();
    const containerDiv = this.checkboxContainer_;
    containerDiv.style.left = area.x + 'px';
    containerDiv.style.width = area.w + 'px';
  };

  SeriesToggle.prototype.checkboxClickHandler_ = function(label) {
    const self = this;
    return function(e) {
      self.dygraph_.setVisibility(label, e.target.checked);
    };
  };

  return SeriesToggle;

})();

Dygraph.Plugins.SeriesToggle = SeriesToggle;

0
投票

问题似乎出在生成复选框并将其添加到页面的 JavaScript 代码中。该代码在也用双引号括起来的字符串中使用双引号,这会导致语法错误。

要解决此问题,您可以将内部双引号替换为单引号,或者您可以使用反斜杠 (") 转义内部双引号。

这里是应该工作的修改后的 JavaScript 代码:

dygraph(df, elementId="the_plot") %>% dyAxis("y", label= "Value ($s)") %>% dyOptions(labelsUTC = TRUE) %>% dyCrosshair(direction = "vertical") %>% dyHighlight(highlightCircleSize = 5, highlightSeriesBackgroundAlpha = 0.2, hideOnMouseOut = FALSE) %>% dyCallbacks(drawCallback = JS('
  function(dygraph, is_initial) {
    if (!is_initial) return;

    var data = this.dataHandler_.data_;
    var labels = dygraph.getLabels();
    var num_cols = labels.length - 1; // exclude x-axis
    var checkboxes_html = "";

    // generate checkbox HTML for each series
    for (var i = 1; i <= num_cols; i++) {
      var label = labels[i];
      var id = "checkbox" + i;
      checkboxes_html += "<label><input type=\'checkbox\' id=\'" + id + "\' checked> " + label + "</label><br>";
    }

    // add checkboxes to the page
    $("#checkboxes").html(checkboxes_html);

    // add change event listeners to checkboxes
    $("#checkboxes").find("input[type=checkbox]").change(function() {
      var series = this.id.replace("checkbox", "");
      var show = this.checked;
      dygraph.setVisibility(parseInt(series), show);
    });
  }'))

请注意,HTML 字符串中的内部双引号已替换为单引号,外部单引号已使用反斜杠 (') 进行转义。


0
投票

一个可能的解决方案是用具有

div
属性的 HTML
id
元素包装您的复选框 HTML 代码。这个
id
属性可用于定位
div
并用复选框填充它。

这是一个更新的代码片段,它添加了一个

id
checkboxes
的 div,并用您的 JavaScript 代码生成的复选框填充它:

library(dygraphs)
library(htmlwidgets)
library(rgl)
knitr::opts_chunk$set(echo = TRUE)
knitr::knit_hooks$set(webgl = hook_webgl)
includeScript('C://Desktop//Javascripts/dygraph.js')
includeScript('C://Desktop//Javascripts/jquery-3.6.0.js')

df <- data.frame(date = seq(as.Date("1980-03-01"), length.out = 100, by = "day"),
                 Long = rnorm(100, 50, 10),
                 Medium = rnorm(100, 30, 5),
                 Short = rnorm(100, 10, 2),
                 Very.Short = rnorm(100, 5, 1))

dygraph(df, elementId = "the_plot") %>% 
  dyAxis("y", label = "Value ($s)") %>% 
  dyOptions(labelsUTC = TRUE) %>% 
  dyCrosshair(direction = "vertical") %>% 
  dyHighlight(highlightCircleSize = 5, highlightSeriesBackgroundAlpha = 0.2, hideOnMouseOut = FALSE) %>% 
  dyCallbacks(drawCallback = JS('
    function(dygraph, is_initial) {
      if (!is_initial) return;

      var data = this.dataHandler_.data_;
      var labels = dygraph.getLabels();
      var num_cols = labels.length - 1; // exclude x-axis
      var checkboxes_html = "";

      // generate checkbox HTML for each series
      for (var i = 1; i <= num_cols; i++) {
        var label = labels[i];
        var id = "checkbox" + i;
        checkboxes_html += "<label><input type=\\"checkbox\\" id=\\"" + id + "\\" checked> " + label + "</label><br>";
      }

      // add checkboxes to the page
      $("#checkboxes").html(checkboxes_html);

      // add change event listeners to checkboxes
      $("#checkboxes").find("input[type=checkbox]").change(function() {
        var series = this.id.replace("checkbox", "");
        var show = this.checked;
        dygraph.setVisibility(parseInt(series), show);
      });
    }')) %>%
  htmltools::onRender("$('#the_plot').append('<div id=\"checkboxes\"></div>');")

在此更新的代码片段中,我添加了一个

onRender
挂钩,以将具有
div
id
元素附加到
checkboxes
元素。
dygraph
函数然后使用复选框 HTML 填充此 div。
希望对您有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.