draw-curved-arrows
Version:
Draw a curved arrow from target to target through the canvas
257 lines • 13.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
var React = __importStar(require("react"));
var drawArrow_1 = require("./drawArrow");
var movementSize_1 = require("./movementSize");
var react_1 = require("react");
var DrawCurvedArrows = function (_a) {
var stores = _a.stores, imgUrl = _a.imgUrl;
var maxTotalMovement = Math.max.apply(Math, stores.map(function (store) { return store.total; }).flat());
var maxPersonalMovement = Math.max.apply(Math, stores.map(function (v) { return Object.values(v.movement); }).flat());
var canvasRef = (0, react_1.useRef)(null);
var _b = (0, react_1.useState)({ width: 0, height: 0 }), canvasSize = _b[0], setCanvasSize = _b[1];
var _c = (0, react_1.useState)([]), selectedStores = _c[0], setSelectedStores = _c[1];
var _d = (0, react_1.useState)([]), lines = _d[0], setLines = _d[1];
var _e = (0, react_1.useState)({
startStore: "",
endStore: "",
movement: 0,
x: 0,
y: 0,
}), renderData = _e[0], setRenderData = _e[1];
var _f = (0, react_1.useState)({
total: 0,
x: 0,
y: 0,
}), tooltipData = _f[0], setTooltipData = _f[1];
var _g = (0, react_1.useState)(false), displayMovement = _g[0], setDisplayMovement = _g[1];
var setSelectedStoresHandler = function (e) {
var id = e.currentTarget.id;
var matchStore = stores.find(function (store) { return store.name === id; });
if (!(id && matchStore))
return;
if (selectedStores.find(function (store) { return store.name === matchStore.name; })) {
setSelectedStores(selectedStores.filter(function (store) { return store.name !== matchStore.name; }));
}
else {
setSelectedStores(function (pre) {
return pre.length < 2 ? __spreadArray(__spreadArray([], pre, true), [matchStore], false) : [matchStore];
});
}
};
var selectedStoresResetHandler = function () {
setSelectedStores([]);
};
(0, react_1.useEffect)(function () {
var canvas = canvasRef.current;
if (!canvas)
return;
var ctx = canvas.getContext("2d");
if (!ctx)
return;
var img = new Image();
img.onload = function () {
ctx.clearRect(0, 0, canvasSize.width + 100, canvasSize.height + 300);
var width = img.width, height = img.height;
setCanvasSize({ width: width, height: height });
ctx.drawImage(img, 30, 130);
setLines([]);
if (selectedStores.length === 1) {
stores.forEach(function (store) {
if (store.name === selectedStores[0].name)
return;
var selectedStore = selectedStores[0];
var leave = selectedStore.movement[store.name];
var come = store.movement[selectedStore.name];
var _a = (0, movementSize_1.arrowSize)(leave, maxPersonalMovement), leaveALength = _a.aLength, leaveLineWidth = _a.lineWidth;
var _b = (0, movementSize_1.arrowSize)(come, maxPersonalMovement), comeALength = _b.aLength, comeLineWidth = _b.lineWidth;
var firstHalfStoreSize = (0, movementSize_1.marketSize)(selectedStores[0].total, maxTotalMovement).halfStoreSize;
var secondHalfStoreSize = (0, movementSize_1.marketSize)(store.total, maxTotalMovement).halfStoreSize;
var leavePath = (0, drawArrow_1.drawArrow)(ctx, selectedStores[0].coodinate[0], selectedStores[0].coodinate[1], store.coodinate[0], store.coodinate[1], leaveALength, leaveLineWidth, firstHalfStoreSize, secondHalfStoreSize);
var comePath = (0, drawArrow_1.drawArrow)(ctx, store.coodinate[0], store.coodinate[1], selectedStores[0].coodinate[0], selectedStores[0].coodinate[1], comeALength, comeLineWidth, secondHalfStoreSize, firstHalfStoreSize, true);
setLines(function (pre) { return __spreadArray(__spreadArray([], pre, true), [
{
startStore: selectedStore.name,
endStore: store.name,
movement: leave,
path: leavePath,
},
], false); });
setLines(function (pre) { return __spreadArray(__spreadArray([], pre, true), [
{
startStore: store.name,
endStore: selectedStore.name,
movement: come,
path: comePath,
},
], false); });
});
}
else {
var renderStores_1 = selectedStores.reverse();
renderStores_1.forEach(function (firstStore, i) {
renderStores_1.forEach(function (secondStore, j) {
if (i <= j)
return;
var leave = firstStore.movement[secondStore.name];
var come = secondStore.movement[firstStore.name];
var _a = (0, movementSize_1.arrowSize)(leave, maxPersonalMovement), leaveALength = _a.aLength, leaveLineWidth = _a.lineWidth;
var _b = (0, movementSize_1.arrowSize)(come, maxPersonalMovement), comeALength = _b.aLength, comeLineWidth = _b.lineWidth;
var firstHalfStoreSize = (0, movementSize_1.marketSize)(firstStore.total, maxTotalMovement).halfStoreSize;
var secondHalfStoreSize = (0, movementSize_1.marketSize)(secondStore.total, maxTotalMovement).halfStoreSize;
var leavePath = (0, drawArrow_1.drawArrow)(ctx, firstStore.coodinate[0], firstStore.coodinate[1], secondStore.coodinate[0], secondStore.coodinate[1], leaveALength, leaveLineWidth, firstHalfStoreSize, secondHalfStoreSize);
var comePath = (0, drawArrow_1.drawArrow)(ctx, secondStore.coodinate[0], secondStore.coodinate[1], firstStore.coodinate[0], firstStore.coodinate[1], comeALength, comeLineWidth, secondHalfStoreSize, firstHalfStoreSize, true);
setLines(function (pre) { return __spreadArray(__spreadArray([], pre, true), [
{
startStore: firstStore.name,
endStore: secondStore.name,
movement: leave,
path: leavePath,
},
], false); });
setLines(function (pre) { return __spreadArray(__spreadArray([], pre, true), [
{
startStore: secondStore.name,
endStore: firstStore.name,
movement: come,
path: comePath,
},
], false); });
});
});
}
};
img.src = imgUrl;
}, [selectedStores, stores, canvasSize.height]);
(0, react_1.useEffect)(function () {
var canvas = canvasRef.current;
var ctx = canvas === null || canvas === void 0 ? void 0 : canvas.getContext("2d");
if (!canvas || !ctx)
return;
canvas.onmousemove = function (_a) {
var offsetX = _a.offsetX, offsetY = _a.offsetY;
for (var i = 0; i < lines.length; i++) {
ctx.save();
ctx.lineWidth = lines[i].path.lineWidth;
ctx.translate(lines[i].path.translate[0], lines[i].path.translate[1]);
ctx.rotate(lines[i].path.angle);
if (ctx.isPointInStroke(lines[i].path.path, offsetX, offsetY)) {
var _b = lines[i], startStore = _b.startStore, endStore = _b.endStore, movement = _b.movement;
setRenderData({
startStore: startStore,
endStore: endStore,
movement: movement,
x: offsetX,
y: offsetY,
});
setDisplayMovement(true);
return ctx.restore();
}
else {
setDisplayMovement(false);
}
ctx.restore();
}
};
}, [lines]);
return (React.createElement(React.Fragment, null,
React.createElement("div", { style: { position: "relative" } },
React.createElement("canvas", { id: "canvas", ref: canvasRef, width: canvasSize.width + 100, height: canvasSize.height + 300 }),
React.createElement("button", { onClick: selectedStoresResetHandler, style: {
position: "absolute",
left: "1150px",
top: "100px",
zIndex: 0,
padding: "5px 10px",
} }, "RESET"),
React.createElement("ul", null, stores.map(function (store) {
var _a = (0, movementSize_1.marketSize)(store.total, maxTotalMovement), storeSize = _a.storeSize, halfStoreSize = _a.halfStoreSize;
return (React.createElement("li", { id: store.name, key: store.name, onClick: setSelectedStoresHandler, onMouseMove: function (_a) {
var _b = _a.nativeEvent, offsetX = _b.offsetX, offsetY = _b.offsetY;
setTooltipData({
total: store.total,
x: offsetX + store.coodinate[0] - halfStoreSize,
y: offsetY + store.coodinate[1] - halfStoreSize,
});
}, onMouseLeave: function () {
setTooltipData({ total: 0, x: 0, y: 0 });
}, style: {
left: "".concat(store.coodinate[0] - halfStoreSize, "px"),
top: "".concat(store.coodinate[1] - halfStoreSize, "px"),
width: "".concat(storeSize, "px"),
height: "".concat(storeSize, "px"),
position: "absolute",
borderRadius: "50%",
display: "flex",
justifyContent: "center",
alignItems: "center",
cursor: "pointer",
backgroundColor: selectedStores.find(function (_a) {
var name = _a.name;
return name === store.name;
})
? "#3265e6"
: "#f2effb",
color: selectedStores.find(function (_a) {
var name = _a.name;
return name === store.name;
})
? "#f2effb"
: "black",
} }, store.name));
})),
React.createElement("div", { style: {
position: "absolute",
top: renderData.y + 10 + "px",
left: renderData.x + 10 + "px",
backgroundColor: "black",
color: "white",
display: displayMovement ? "block" : "none",
} }, renderData.startStore +
" -> " +
renderData.endStore +
"/" +
renderData.movement),
React.createElement("div", { style: {
position: "absolute",
top: tooltipData.y + 10 + "px",
left: tooltipData.x + 10 + "px",
backgroundColor: "black",
color: "white",
display: tooltipData.total ? "block" : "none",
} }, tooltipData.total))));
};
exports.default = DrawCurvedArrows;
//# sourceMappingURL=DrawCurvedArrows.js.map