Legend not appearing when using document.createElement('canvas')

▼魔方 西西 提交于 2020-03-03 07:31:08

问题


I followed this Observable post to easily create a legend.

Since the line

DOM.canvas(1, n)

in the ramp works only on Observable, I replaced it with

document.createElement("canvas")

and also modified the SVG so that it's appended to the main div tag. These changed do not cause any errors however the problem is that the legend is not displayed even though the legend SVG is present in the raw HTML.

Here's the link to a JSFiddle. Any guidance would be greatly appreciated.


回答1:


The canvas is being created, that's not the problem. The problem is that, since you are now missing the width and height in...

const canvas = DOM.canvas(n, 1);
//these are w & h --------^--^

... you now need to set those yourself. For instance:

d3.select(canvas).attr("width", n)
  .attr("height", 1);

Here is a simplified version of that JSFiddle, showing that the canvas works:

legend({
  color: d3.scaleSequential([1, 10], d3.interpolateReds),
  title: "Title"
})


function legend({
  color,
  title,
  tickSize = 6,
  width = 320,
  height = 44 + tickSize,
  marginTop = 18,
  marginRight = 0,
  marginBottom = 16 + tickSize,
  marginLeft = 0,
  ticks = width / 64,
  tickFormat,
  tickValues
} = {}) {

  const svg = d3.select(".scatter").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("viewBox", [0, 0, width, height])
    .style("overflow", "visible")
    .style("display", "block");

  svg.append("image")
    .attr("x", marginLeft)
    .attr("y", marginTop)
    .attr("width", width - marginLeft - marginRight)
    .attr("height", height - marginTop - marginBottom)
    .attr("preserveAspectRatio", "none")
    .attr("xlink:href", ramp(color.interpolator()).toDataURL());

}

function ramp(color, n = 256) {
  const canvas = document.createElement('canvas');
  const context = canvas.getContext("2d");
  d3.select(canvas).attr("width", n)
    .attr("height", 1);
  for (let i = 0; i < n; ++i) {
    context.fillStyle = color(i / (n - 1));
    context.fillRect(i, 0, 1, 1);
  }
  return canvas;
}
<script type="text/javascript" src="https://d3js.org/d3.v5.js"></script>
<div class="scatter">
</div>

By the way, there is no such element as <legend-svg>.


PS: This is the second question from you I'm answering on this subject. As you're new to JavaScript and D3, here is an advice: do not try to use that Observable notebook, that's way too complicated for your purposes. Just create the SVG, the canvas and a basic axis yourself, from scratch, it will be way easier.



来源:https://stackoverflow.com/questions/60443356/legend-not-appearing-when-using-document-createelementcanvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!