【问题标题】:Drawing connective elements between fixed positions on several html elements在几个 html 元素的固定位置之间绘制连接元素
【发布时间】:2020-03-16 06:31:49
【问题描述】:

我对网络编程很陌生,所以如果我遗漏了一些明显的东西,请多多包涵。我正在使用 html、css 和 javascript 来可视化不同的 DNA 序列。每个序列都表示为 html 元素的图形,并具有对应于 DNA 序列长度的固定长度。跨度位于每个图中的固定点以表示某些主题。一个这样的图的代码如下所示(使用 django 作为我的网络框架):

<div class="graph" style='--graph-length: {{sequence_length}}'>
        <hr class="line">
      {% for key, value2 in value.items %}
        {% if value2.start_position %}
            <span class='motif' style="--start: {{ value2.start_position }}; --stop: {{ value2.stop_position }};"></span>
        {% endif %}
      {% endfor %}
      </div>

像这样,我在我的网页上创建了几个序列的表示,一个在另一个之下。现在,这些序列中的一些可能彼此相似。我想以图形方式显示序列与其下方显示的序列相似的区域,如下所示:

在上面的例子中,graph1 和 2 和 graph2 和 3 表示的序列具有相似的区域,但是序列的总长度(以及图上表示的基序的显示大小)不同,导致更宽graph2 和 3 之间的蓝色元素。

所以我对每个图的了解是每个图应该表示的序列长度、相应图上每个主题的开始和结束位置,以及如果两个图(序列) 包含一个相似的区域(图中的绿色)。

所以我的问题是:如何使用 html、css 或 javascript 创建表示两个图形(图中蓝色)之间相似区域的元素? (或者实际上我可以在我已经拥有的东西中实现的任何其他东西)

如果您有更多问题,请告诉我如何解决此问题的任何提示!

编辑:我实际上更喜欢 svg 中的解决方案,因为我认为它更适合集成到我的应用程序中

【问题讨论】:

  • 画布被禁止了吗?
  • 我可以集成到我的 html 代码中的所有内容都被允许 @user753642 !虽然我真的不知道画布上的限制是什么,但看起来它在 html 中使用了很多,所以我想我可以使用它
  • 您可以使用出色的 d3,也称为 data-driver-documents。但它只适用于画布,所以你必须忘记 html。

标签: javascript html css svg visualization


【解决方案1】:

您可以使用 svg 或画布。

这是一种使用画布的极简主义方法。您可能希望依赖一个非常可能提供与您的图表接近的图表的库。

但抓挠永远不会痛。

在下面,每个图表负责正确缩放其轴。

最终,梯形依赖于它们所依赖的图来缩放相应的顶点。

您可能希望更多地显示text,因此请使用 Bar 并可能给它一个布尔值来指示是否应该显示它。

您可以通过使用笔划线的权重来进一步设置画布的样式,但这只是一个演示,向您展示您可以轻松完成它

const canvas = document.querySelector('canvas')
  let ctx = canvas.getContext('2d')
  let bars = [
    [Bar(200, 300), Bar(1800,2300), Bar(2500, 4500), Bar(5000,5200), Bar(8000,8500)],
    [Bar(1100,1300), Bar(3000, 3800), Bar(4000, 4200), Bar(7000, 7500)],
    [Bar(1, 2700)]
  ]
  function Bar(a,b){return [a, b]}
  class Graph{
    constructor ({anchorY, width, min, max}) {
      this.anchorY = anchorY
      this.width = width
      this.dw = width / (max - min )
      this.min = min
      this.max = max
    }

    plot (bars) {
      // plot bars
      // resize bars dimension to fit canvas
      const e = 5
      ctx.fillStyle = 'orange'
      const scaledBars = bars.map(([a, b]) => [ a, b, a * this.dw, b * this.dw ])
      scaledBars.forEach(([_, dum, left, right])=>{
        ctx.fillRect(left, this.anchorY - e, right - left, 2*e)
      })

      // plot line
      ctx.strokeStyle = 'black'
      ctx.beginPath()
      ctx.moveTo(0, this.anchorY)
      ctx.lineTo(this.width, this.anchorY)
      ctx.closePath()
      ctx.stroke()

      ctx.strokeStyle = 'green'
      ctx.font = '10px serif'
      scaledBars.forEach(([origLeft, origRight, left, right]) => {
        ctx.strokeText(origLeft, left, this.anchorY - 10)
        if (right - left > 100 ) {
          ctx.strokeText(origRight, right, this.anchorY - 10)
        }
      })
      
    }

    //x will be shifted automatically
    moveTo (x) {
      ctx.moveTo(x * this.dw, this.anchorY)
    }


    lineTo (x) {
      ctx.lineTo(x * this.dw, this.anchorY)
    }
  }
  const graphs = [
    new Graph({anchorY:100, width: canvas.width, min: 1, max: 10000}),
    new Graph({anchorY:200, width: canvas.width, min: 1, max: 8500}),
    new Graph({anchorY:300, width: canvas.width, min: 1, max: 4000})
  ]
  
  // g first graph, (a,b) left, right anchors in first graph
  // g2 second graph, c right anchor, d left anchor in second graph
  function trapeze(g, a, b, g2, c, d){
    ctx.beginPath()
    g.moveTo(a)
    g.lineTo(b)
    g2.lineTo(c)
    g2.lineTo(d)
    ctx.closePath()
    ctx.fillStyle = 'rgba(84, 147, 158, 0.5)'
    ctx.fill()
  }

  const [g1, g2, g3] = graphs
  const trapezes = [
    [g1, 1800, 4500, g2, 3800, 1100],
    [g1, 8000, 8500, g2, 7500, 7000],
    [g2, 1100, 3800, g3, 2700, 1],
  ]
  trapezes.forEach(t => trapeze(...t))

  graphs.forEach((g, i) => {
    g.plot(bars[i])
  })
canvas{background:#eeeeee;}
&lt;canvas width="400" height="400"&gt;&lt;/canvas&gt;

【讨论】:

  • 感谢您的回答!我将不得不阅读一些有关画布的内容,以了解如何尝试在我的代码中实现您的答案,但我会在完成后立即回复您!
猜你喜欢
  • 2015-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 2017-03-04
  • 2014-05-21
  • 2012-10-12
  • 1970-01-01
相关资源
最近更新 更多