Как нарисовать фигуру(многоугольник, линию) поверх изображения d3.js

Вот в чем вопрос: как нарисовать изображение (картинку) (1.png) или (1.jpg), а поверх неё многоугольник?(прямую).Вот мой код:

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <style>
html,body{
  overflow-y:hidden;
}
</style>
</head>
<body>
<script>
  var R1=360.0;
  var R2=300.0;
  var R3=220.0;
  
  var delta=400.0;
  
  var p=(2*Math.PI)/366; 
  var x1 = [366+1];
  var y1 = [366+1];
  var x2 = [366+1];
  var y2 = [366+1];
  var x3 = [366+1];
  var y3 = [366+1];
  
  
  for(var i=0;i<=367;i++){
  y1[i]=R1*(Math.sin(i*p))+delta;
  x1[i]=R1*(Math.cos(i*p))+delta;
  y2[i]=R2*(Math.sin(i*p))+delta;
  x2[i]=R2*(Math.cos(i*p))+delta;
  y3[i]=R3*(Math.sin(i*p))+delta;
  x3[i]=R3*(Math.cos(i*p))+delta;
  }

var a="111";
var b="12";
var c="131";
var d="23";
var e="33";
var f="48";

var W1="";
var canvas = d3.select("body")
   .append("svg")
   .attr("height", 1366)
   .attr("width", 800);
for (var i =0;i<=365;i++){

var W=[8];
W[0]=(x1[i]).toString();
W[1]=(y1[i]).toString();
W[2]=(x1[i+1]).toString();
W[3]=(y1[i+1]).toString();
W[4]=(x2[i+1]).toString();
W[5]=(y2[i+1]).toString();
W[6]=(x2[i]).toString();
W[7]=(y2[i]).toString();
var 
//W1="55,55 100,100 300,555 777,888"; Такой формат должен быть везде.
W1=(W[0]+","+W[1]+" "+W[2]+"," +W[3]+" "+W[4]+","+W[5]+" "+W[6]+","+W[7]);//Здесь уже все работает

canvas.append("polygon")
   .attr("points", W1)
   .style("fill", "yellow")
   .style("stroke", "black")
   .style("strokeWidth", "5px");  

}
var polygon=canvas.append("polygon")
   .attr("points", [a,b,c,d,e,f])
   .style("fill", "blue")
   .style("stroke", "black")
   .style("strokeWidth", "10px")
  // while(true){
   //
  
   
   
window.addEventListener("wheel", function(ev) {
  var dir = Math.sign(ev.deltaY);
	if(dir==1){
	a+=dir;
	b+=dir;
	c+=dir;
	e+=dir;
	f+=dir;
    
	
	
	
	
	}
	
	else if(dir==-1){
	a=a-1;
	b=b-1;
	c=c-1;
	e=e-1;
	f=f-1;
	
	
	
	}
	
	
  polygon.attr("points", [a,b,c,d,e,f]);
});
</script>
</body>


Ответы (3 шт):

Автор решения: Stranger in the Q

Вот, наверное как-то так:

let points = [];
let transform = {};
let dragged = null;
let selected = points[points.length-1];

let line = d3.line().curve(d3.curveLinear);
let svg = d3.select("svg");
let img = d3.select("svg image");
let canvas = svg.append('g');
let path = canvas.append("path")
    .datum(points);

svg.on("mousedown", mousedown)
    .on("mousemove", mousemove)

d3.select(window)
    .on("mouseup", mouseup)
    .on("resize", adjustSize);

window.oncontextmenu = () => false;
svg.call(createZoom());
adjustSize();
redraw();

function toggleElement(selector, isVisible) {
    return d3.select(selector)
        .node()
        .classList
        .toggle('hidden', isVisible)
}

function applyTransform() {
    transform = d3.event.transform;
    canvas.attr("transform", transform);
}

function createZoom() {
    return d3.zoom()
        .filter(() => d3.event.button === 2)
        .scaleExtent([1, 1])
        .on("zoom", applyTransform);
}

function adjustSize() {
    let w = window.innerWidth;
    let h = window.innerHeight;
    svg.attr("viewBox", `0 0 ${w} ${h}`);
}

function redraw() {

    canvas.select("path").attr("d", line);

    var circle = canvas.selectAll("circle.knob")
        .data(points, d => d);

    circle.exit().remove();

    let newNodes = circle.enter()
        .append("circle")
        .classed('knob', true)
        .attr("r", 1e-6)
        .on("mousedown", d => {
            selected = dragged = d;
            redraw();
        })
        .on("dblclick", deletePoint)
        .transition()
        .duration(250)
        .attr("r", 6.5);

    circle.merge(newNodes)
        .classed("selected", d => d === selected)
        .attr("cx", d => d[0])
        .attr("cy", d => d[1]);

    if (d3.event) {
        d3.event.preventDefault();
        d3.event.stopPropagation();
    }
}

function mousedown() {
    if (d3.event.button !== 0)
        return;
    points.push(selected = dragged = 
                d3.mouse(canvas.node()));
    redraw();
}

function mousemove() {
    if (!dragged)
        return;
    let m = d3.mouse(canvas.node());
    dragged[0] = m[0];
    dragged[1] = m[1];
    redraw();
}

function mouseup() {
    if (!dragged)
        return;
    mousemove();
    dragged = null;
}

function deletePoint(d) {
    if (!selected)
        return;
    let i = points.indexOf(selected);
    points.splice(i, 1);
    selected = points.length ? 
        points[i > 0 ? i - 1 : 0] : null;
    redraw();
}
body,svg{
    position: absolute;
    margin: 0;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
}
path {
    fill: none;
    stroke-width: 3.2;
    stroke: red;
}
circle {
    pointer-events: all;
    stroke: red;
    stroke-width: 1.5px;
    fill: #fff;
    fill-opacity: .2;
    cursor: pointer;
}
.selected {
    fill: #ff7f0e;
    stroke: #ff7f0e;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg>
<image xlink:href="https://picsum.photos/800/800" width=800 height=800 />
</svg>

→ Ссылка
Автор решения: Stranger in the Q

Вы про это?

<svg width=400 height=400 >
  <image xlink:href="https://picsum.photos/id/58/400/400" width=400 height=400 />
  <rect x=100 y=50 width=200 height=200 fill=none stroke=red></rect>
</svg>

→ Ссылка
Автор решения: Arthur Alunts

Нашел ура, спасибо. добаление картинки 1.svg, которая лежит рядом с js файлом.

<!DOCTYPE html>
<meta charset="utf-8">
<title>My_Calendar_Project_v_1.0.0.0 </title>
<html>
<script src="https://d3js.org/d3.v5.min.js"></script>
<body>
<script>
var canvas = d3.select("body")
   .append("svg")
   .attr("height", 1024)// размеры 
   .attr("width", 768)// размеры 
var image1=canvas.append("svg:image")
 // .attr("xlink:href", "1.svg")
    .attr("xlink:href", "https://picsum.photos/id/58/400/400")
  
   .attr("x",0) //отступ
  .attr("y",0) //отступ
var polygon24=canvas.append("polygon")
for(var i=0;i<=24;i++){
   polygon24=canvas.append("polygon")
   .attr("points", [100,100,200,200,32,102])
   .style("fill", "yellow")
   .style("stroke", "black")
   .style("strokeWidth", "1px")  
   }
</script>
</html>

→ Ссылка