I'm trying to add a responsive connecting line between 3 divs in a React Js project, I was able to add a line between elements, but when I'm using Axios to fetch the data and display it with if/else statement, my React project gives me an error saying "Cannot read property 'left' of undefined -var originX = this.ele1.offset().left + this.ele1.outerWidth() / 2;
This is my code with axios:
import React, { useState, useEffect } from "react";
import "./styles.css";
import $ from "jquery";
import axios from "axios";
export default function App() {
const [solutions, setSolutions] = useState([]);
const getSolutions = async () => {
const response = await axios.get("./data.json");
setSolutions(response.data.home);
};
useEffect(() => {
getSolutions();
}, []);
var Connector = function(params) {
if (typeof params === "undefined") {
return false;
}
var ele1 = params.ele1 || "";
var ele2 = params.ele2 || "";
if (ele1.length === 0 || ele2.length === 0) {
return false;
}
var className = params.class || "Connector";
this.gapX1 = params.gapX1 || 0;
this.gapY1 = params.gapY1 || 0;
this.gapX2 = params.gapX2 || 0;
this.gapY2 = params.gapY2 || 0;
this.gap = params.gap || 0;
if (this.gap > 0) {
this.gapX1 = this.gap;
this.gapY1 = this.gap;
this.gapX2 = this.gap;
this.gapY2 = this.gap;
}
var pos = function() {
this.left = 0;
this.top = 0;
};
this.PseudoGuid = new function() {
this.empty = "00000000-0000-0000-0000-000000000000";
this.GetNew = function() {
var fC = function() {
return (((1 + Math.random()) * 0x10000) | 0)
.toString(16)
.substring(1)
.toUpperCase();
};
return (
fC() +
fC() +
"-" +
fC() +
"-" +
fC() +
"-" +
fC() +
"-" +
fC() +
fC() +
fC()
);
};
}();
this.id = this.PseudoGuid.GetNew();
this.ele1 = $("#" + ele1);
this.ele2 = $("#" + ele2);
this.lineID = "L" + this.id;
$("body").append(
"<div id='" + this.lineID + "' class='" + className + "' style= ></div>"
);
this.line = $("#L" + this.id);
this.line.css({
position: "absolute",
"border-left": this.lineStyle,
"z-index": -100
});
this.offsets = [];
this.offsets[ele1] = new pos();
this.offsets[ele2] = new pos();
this.link(); //
};
Connector.prototype.link = function link() {
var originX = this.ele1.offset().left + this.ele1.outerWidth() / 2;
var originY = this.ele1.offset().top + this.ele1.outerHeight() / 2;
var targetX = this.ele2.offset().left + this.ele2.outerWidth() / 2;
var targetY = this.ele2.offset().top + this.ele2.outerHeight() / 2;
var l = this.hyp(targetX - originX, targetY - originY);
var angle = (180 / 3.1415) * Math.acos((targetY - originY) / l);
if (targetX > originX) {
angle = angle * -1;
}
var adj1 = this.edgeAdjust(
angle,
this.gapX1 + this.ele1.width() / 2,
this.gapY1 + this.ele1.height() / 2
);
var adj2 = this.edgeAdjust(
angle,
this.gapX2 + this.ele2.width() / 2,
this.gapY2 + this.ele2.height() / 2
);
l = l - (adj1.hp + adj2.hp);
this.line
.css({ left: originX, height: l, width: 0, top: originY + adj1.hp })
.css("-webkit-transform", "rotate(" + angle + "deg)")
.css("-moz-transform", "rotate(" + angle + "deg)")
.css("-o-transform", "rotate(" + angle + "deg)")
.css("-ms-transform", "rotate(" + angle + "deg)")
.css("transform", "rotate(" + angle + "deg)")
.css("transform-origin", "0 " + -1 * adj1.hp + "px");
};
Connector.prototype.Round = function(value, places) {
var multiplier = Math.pow(10, places);
return Math.round(value * multiplier) / multiplier;
};
Connector.prototype.edgeAdjust = function(a, w1, h1) {
var w = 0,
h = 0;
var ca = [];
ca[0] = (Math.atan(w1 / h1) * 180) / 3.1415926;
ca[1] = 180 - ca[0];
ca[2] = ca[0] + 180;
ca[3] = ca[1] + 180;
if (this.Round(a, 0) === 0) {
h = h1;
w = 0;
} else if (this.Round(a, 0) === 180) {
h = h1;
w = 0;
} else if ((a > 0 && a <= ca[0]) || (a < 0 && a >= -1 * ca[0])) {
h = h1;
w = -1 * Math.tan(a * (3.1415926 / 180)) * h1;
} else if (a > ca[0] && a <= 90) {
h = Math.tan((90 - a) * (3.1415926 / 180)) * w1;
w = w1;
} else if (a > 90 && a <= ca[1]) {
h = -1 * Math.tan((a - 90) * (3.1415926 / 180)) * w1;
w = w1;
} else if (a > ca[1] && a <= 180) {
h = h1;
w = -1 * Math.tan((180 - a) * (3.1415926 / 180)) * h1;
} else if (a > -180 && a <= -1 * ca[1]) {
h = h1;
w = Math.tan((a - 180) * (3.1415926 / 180)) * h1;
} else if (a > -1 * ca[1] && a <= 0) {
h = Math.tan((a - 90) * (3.1415926 / 180)) * w1;
w = w1;
}
// We now have the width and height offsets - compute the hypotenuse.
var hp = this.hyp(w, h);
return { hp: hp };
};
Connector.prototype.hyp = function hyp(X, Y) {
return Math.abs(Math.sqrt(X * X + Y * Y));
};
Connector.prototype.moved = function moved(e, ele) {
this.link();
};
$(document).ready(function() {
var c1 = new Connector({
ele1: "a",
ele2: "b",
lineStyle: "1px solid #b8c6f2"
});
Setup(c1, "a");
Setup(c1, "b");
var c2 = new Connector({
ele1: "b",
ele2: "c",
lineStyle: "1px solid ##b8c6f2"
});
Setup(c2, "b");
Setup(c2, "c");
function Setup(connector, id) {
var ele = $("#" + id);
ele.on("mousedown.Connector", function(e) {
//#critical: tell the connector about the starting position when the mouse goes down.
connector.offsets[id].left = e.pageX - ele.offset().left;
connector.offsets[id].top = e.pageY - ele.offset().top;
e.preventDefault();
});
}
});
if (solutions.length) {
return (
<div className="App">
<div className="App">
<div className="divs">
{solutions.map(({ id, text, title }) => {
return <h1>{title}</h1>;
})}
<div id="a"> 1 </div>
<div id="b"> 2</div>
<div id="c"> 3</div>
</div>
</div>
</div>
);
} else {
return null;
}
}
This is a link to codesandbox's example with a working line (without Axios) : working
This is a link to the Axios version of this code : not working
If anyone can explain why using if/else statement is blocking code from drawing a line between divs and how to fix it, I'll be very grateful.
P.s. code to draw a line is not mine, I just modified it for my project.
Aucun commentaire:
Enregistrer un commentaire