在 Plotly.js 图表中的图例(或键)下方添加按钮

Add button beneath legend (or key) in Plotly.js chart

我有一张 Plotly.js 图表。如何在图例(或键)下方放置按钮?

这是我正在使用的示例:https://codepen.io/synaptik/pen/YLmRMM

<div id="myDiv"></div>
<div id="inset" style="margin-left:80px;">
    <button style="background:grey;">Target<br/>Info</button
</div>

一个复杂但稳健的解决方案是,使用 javascript 并获取图中图例的位置(使用函数 getBoundingClientRect),然后将该定位设置为按钮,JQuery 我正在使用库来执行此操作,但也可以通过 javascript 进行一些调整。

运行 绘图渲染后的函数:

定位按钮的javascript函数应该运行只有在plotly graph完成渲染后,所以基于这个,我在之后调用定位按钮的函数剧情已经完全渲染。

参考文献:

  1. getBoundingClientRect

var data_x = ['2018-05-01', '2018-05-02', '2018-05-03', '2018-05-04', '2018-05-05', '2018-05-06', '2018-05-07', '2018-05-08', '2018-05-09'];

// data
var Data = {
  type: 'scatter',
  x: data_x,
  y: [4, 2, -1, 4, -5, -7, 0, 3, 8],
  mode: 'lines+markers',
  name: 'Data',
  showlegend: true,
  hoverinfo: 'all',
  line: {
    color: 'blue',
    width: 2
  },
  marker: {
    color: 'blue',
    size: 8,
    symbol: 'circle'
  }
}

// violations
var Viol = {
  type: 'scatter',
  x: ['2018-05-06', '2018-05-09'],
  y: [-7, 8],
  mode: 'markers',
  name: 'Violation',
  showlegend: true,
  marker: {
    color: 'rgb(255,65,54)',
    line: {
      width: 6
    },
    opacity: 0.5,
    size: 14,
    symbol: 'circle-open'
  }
}
// control limits
var CL = {
  type: 'scatter',
  x: data_x.concat([null]).concat(data_x),
  y: [5, 5, 5, 5, 6, 6, 7, 7, 7, null, -5, -5, -5, -5, -6, -6, -7, -7, -7],
  mode: 'lines',
  name: 'LCL/UCL',
  showlegend: true,
  line: {
    color: 'green',
    width: 2,
    dash: 'dash'
  }
}

// centre
var Centre = {
  type: 'scatter',
  x: data_x,
  y: [3, 1, 2, 2, 2, -2, 2, 2, 2],
  mode: 'lines',
  name: 'EWMA',
  showlegend: true,
  line: {
    color: 'grey',
    width: 2
  }
}

// all traces
var data = [Data, Viol, CL, Centre]

// layout
var layout = {
  title: 'Basic SPC Chart',
  xaxis: {
    zeroline: false
  },
  yaxis: {
    range: [data_x[0], data_x[data_x.length - 1]],
    zeroline: false
  }
}

function positionButton() {
  var offsets = $("g.legend")[0].getBoundingClientRect();
  $("div#inset").css("left", offsets.left);
  var offsetTop = offsets.height + offsets.top;
  $("div#inset").css("top", offsetTop);
}

Plotly.plot('myDiv', data, layout).then(function() {
  window.requestAnimationFrame(function() {
    window.requestAnimationFrame(function() {
      positionButton();
    });
  });
});


$(window).on("resize", function() {
  positionButton();
});
.position-button {
  position: absolute;
}

.style-this {
  background: grey;
}

.wrapper {
  position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<head>
  <!-- Plotly.js -->
  <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
  <!-- Plotly chart will be drawn inside this DIV -->
  <div class="wrapper">
    <div id="myDiv"></div>
    <div id="inset" class="position-button">
      <button class="style-this">Target<br/>Info</button
</div>
   </div>
  <script>
  /* JAVASCRIPT CODE GOES HERE */
  </script>
</body>
</html>

一个简单的方法是,将绘图包装在 div 设置为相对定位,并使 div 包装按钮绝对定位并将其与图例对齐。请参考以下示例。

var data_x = ['2018-05-01' , '2018-05-02' , '2018-05-03' , '2018-05-04' , '2018-05-05' , '2018-05-06' , '2018-05-07' , '2018-05-08' , '2018-05-09' ];

// data
var Data = {
  type: 'scatter',  
  x: data_x, 
  y: [4,2,-1,4,-5,-7,0,3,8], 
  mode: 'lines+markers', 
  name: 'Data', 
  showlegend: true,
  hoverinfo: 'all',
  line: {
    color: 'blue', 
    width: 2
  }, 
  marker: {
    color: 'blue', 
    size: 8, 
    symbol: 'circle'
  }
}

// violations
var Viol = {
  type: 'scatter', 
  x: ['2018-05-06', '2018-05-09'], 
  y: [-7,8], 
  mode: 'markers', 
  name: 'Violation', 
  showlegend: true, 
  marker: {
    color: 'rgb(255,65,54)', 
    line: {width: 6}, 
    opacity: 0.5, 
    size: 14, 
    symbol: 'circle-open'
  }
}
// control limits
var CL = {
  type: 'scatter', 
  x: data_x.concat([null]).concat(data_x), 
  y: [5,5,5,5,6,6,7,7,7, null, -5,-5,-5,-5,-6,-6,-7,-7,-7], 
  mode: 'lines', 
  name: 'LCL/UCL', 
  showlegend: true, 
  line: {
    color: 'green', 
    width: 2,
    dash: 'dash'
  }
}

// centre
var Centre = {
  type: 'scatter',  
  x: data_x, 
  y: [3,1,2,2,2,-2,2,2,2], 
  mode: 'lines', 
  name: 'EWMA', 
  showlegend: true, 
  line: {
    color: 'grey', 
    width: 2
  }
}

// all traces
var data = [Data,Viol,CL,Centre]

// layout
var layout = {
  title: 'Basic SPC Chart',
  xaxis: {
    zeroline: false
  },
  yaxis: {
    range: [data_x[0], data_x[data_x.length-1]],
    zeroline: false
  }
}

Plotly.plot('myDiv', data,layout);
.position-button {
 position: absolute;
 top: 190px;
 left: 89%;
}
.style-this{
 background:grey;
}
.wrapper{
 position:relative;
}
<head>
 <!-- Plotly.js -->
 <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>

<body>
 <!-- Plotly chart will be drawn inside this DIV -->
 <div class="wrapper">
  <div id="myDiv"></div>
  <div id="inset" class="position-button">
   <button class="style-this">Target<br/>Info</button
</div>
   </div>
  <script>
  /* JAVASCRIPT CODE GOES HERE */
  </script>
</body>
</html>