open div in new window on row click - javascript

I try to open div in new window on row click . i tried this .. div open in new window but the problem is that this is display only 1 div whereas i have 2 divs and second problem is when this is open then there is no demo bar and menu display where as i want to display these with div when div is open in new window
this is what i tried
link js fiddle
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'sumdata',
type: 'pie',
width: 500,
borderWidth: 2,
events: {
load: function(event) {
var total = 0;
for (var i = 0, len = this.series[0].yData.length; i < len; i++) {
total += this.series[0].yData[i];
}
var text = this.renderer.text(
'Total: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add()
}
}
},
title: {
text: 'demo'
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 30,
labelFormat: '{name} ({y})',
navigation: {
activeColor: '#3E576F',
animation: true,
arrowSize: 12,
inactiveColor: '#CCC',
style: {
fontWeight: 'bold',
color: '#333',
fontSize: '12px'
}
}
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.percentage, 2) + '%<br />' + '<b>' + this.point.name + '</b><br />Rs.: ' + Highcharts.numberFormat(this.y, 2);
}
},
series: [{
data: (function() {
var names = 'grapes,lemon,orange,sugar,tea,pine',
arr = [];
Highcharts.each(names.split(','), function(name) {
arr.push({
name: name,
y: Math.round(Math.random() * 100)
});
});
return arr;
}()),
showInLegend: true
}]
});
});
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie',
width: 500,
borderWidth: 2,
events: {
load: function(event) {
var total = 0;
for (var i = 0, len = this.series[0].yData.length; i < len; i++) {
total += this.series[0].yData[i];
}
var text = this.renderer.text(
'Total: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add()
}
}
},
title: {
text: 'demo'
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 30,
labelFormat: '{name} ({y})',
navigation: {
activeColor: '#3E576F',
animation: true,
arrowSize: 12,
inactiveColor: '#CCC',
style: {
fontWeight: 'bold',
color: '#333',
fontSize: '12px'
}
}
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.percentage, 2) + '%<br />' + '<b>' + this.point.name + '</b><br />Rs.: ' + Highcharts.numberFormat(this.y, 2);
}
},
series: [{
data: (function() {
var names = 'Ari,Bjartur,Bogi,Bragi,Dánjal,Dávur,Eli,Emil,Fróði,Hákun,Hanus,Hjalti,Ísakur,' +
'Johan,Jóhan,Julian,Kristian,Leon,Levi,Magnus,Martin,Mattias,Mikkjal,Nóa,Óli,Pauli,Petur,Rói,Sveinur,Teitur',
arr = [];
Highcharts.each(names.split(','), function(name) {
arr.push({
name: name,
y: Math.round(Math.random() * 100)
});
});
return arr;
}()),
showInLegend: true
}]
});
});
function nWin() {
var w = window.open();
var html1 = $("#container").html();
var html2 = $("#sumdata").html();
$(w.document.body).html(html1, html2);
//$(w.document.body).html(htmll);
}
$(function() {
$('#tabledata').on('click', 'tr', (nWin))
// $("a#print").click(nWin);
});
.lefttabs {
background-color: #1E1E1E;
color: White;
position: absolute;
font-weight: bold;
font-size: medium;
margin-top: 12px;
width: 150px;
height: 400px;
z-index: 10;
/
}
.lefttabs li {
list-style: none;
margin-left: -30px;
}
#tabledata {
margin-left: 160px;
}
#cont {
margin-left: 160px;
background-color: blue;
}
#sumdata {
margin-left: 160px;
}
.bar {
background-color: blue;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div class="bar">
demo
</div>
<div class="lefttabs">
<ul>
<li>
<a>DASHBOARD</a>
</li>
<li>
<a>EVENTS</a>
</li>
</ul>
</div>
<table id="tabledata">
<thead>
<tr>
<td>
1
</td>
<td>
2
</td>
<td>
3
</td>
</tr>
</thead>
<tbody>
<tr>
<td>
1data
</td>
<td>
2data
</td>
<td>
3data
</td>
</tr>
<tr>
<td>
data1
</td>
<td>
data2
</td>
<td>
data3
</td>
</tr>
</tbody>
</table>
<div id="container" style="width: 50px; height: 200px;margin-left: 170px;display:none"></div>
<br />
<div id="sumdata" style="width: 50px; height: 200px;margin-left: 170px;display:none"></div>

use append method instead of html method .
i have updated fiddle .
http://jsfiddle.net/8dXvt/1481/

Related

Click on an fabricjs element is not recognized

I am trying to build a simple editor using fabricjs.
I did the following:
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.input-group {
padding: 4px;
}
.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}
.actived {
background: #fff9a8;
}
.list-group {
line-height: 35px;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
.fl {
float: left;
}
.fr {
float: right;
}
.input-group-text {
background-color: #f4f4f4;
}
.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}
.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>
<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<hr>
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: '#000', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: '#000', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
</div>
<hr>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas><canvas class="upper-canvas " width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: manipulation; user-select: none; cursor: default;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
<form class="form-inline pt-4" id="f" onsubmit="return false;" style="display: none;">
<div class="form-floating w-100 mb-4" style="">
<textarea type="text" class="form-control form-control-sm" name="text" oninput="canvas.getActiveObject().set({'text':this.value}); canvas.renderAll();" onmouseover="this.style.height = (this.scrollHeight)+'px';" rows="10" autocomplete="off"></textarea>
<label for="floatingInput" class="lable-sm">Text</label>
</div>
<div class="input-group input-group-sm mb-3 w-100 tour13">
<span class="input-group-text" id="inputGroup-sizing-sm">MaxHeight to Fit Text</span>
<input type="number" class="form-control" name="maxHeight" onkeyup="hide_mh_box(); show_mh_box();" onblur="hide_mh_box();" onfocus="show_mh_box();" autocomplete="off">
</div>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric#5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;
fabric.Text.prototype.set({
_getNonTransformedDimensions() {
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() {
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});
function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);
if (scale > 1) {
scale = 1;
}
canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);
initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);
canvas.renderAll();
console.log("finished!!");
}
(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});
canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}
if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});
}
if ((o.rx || o.ry) && o.type == "image") {
let rx = (o.rx || 0);
let ry = (o.ry || 0);
o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>
<script>
fabric.Object.prototype.objectCaching = false;
function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}
function setCanvasBI(src, o = "1") {
if (!src) {
src = $("#canvasBI").val();
}
if (src.length == 0) {
src = new fabric.Image('');
}
canvas.setBackgroundImage(src, canvas.renderAll.bind(canvas), {
opacity: o
});
}
(function() {
$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});
fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};
$("form#f").hide();
var activeObject;
$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});
canvas.preserveObjectStacking = true;
fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text
});
};
})(fabric.Object.prototype.toObject);
canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});
canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});
canvas.on("after:render", function() {
canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {
if (typeof layer.name !== 'undefined') {
canvas.getItemByAttr(`name`, layer.name).set({
"name": String.fromCharCode(65 + id).toLowerCase()
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}
}
});
document.body.style.cursor = 'default'
});
canvas.on("selection:created", function(obj) {
if ("image" == obj.target.type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
showForm();
});
canvas.on("selection:updated", function(obj) {
if ("image" == obj.target.type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
showForm();
});
canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});
canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});
canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});
function showForm() {
$("form#f").show();
activeObject = canvas.getActiveObject();
var v;
for (i in activeObject) {
v = activeObject[i];
if (typeof v != "undefined") {
$("textarea[name='" + i + "']").val(v).parent().show();
$("input[name='" + i + "']").val(v).parent().show();
$("select[name='" + i + "']").val(v).parent().show();
}
}
}
addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});
canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();
function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}
function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}
var visited = [];
</script>
<script>
function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}
</script>
</body>
</html>
When I click on an element f.ex. the triangle it is added to the canvas. When I click on the added triangle a menu on the right should go up. However, the element does not get selected.
Any suggestions what I am doing wrong?
I appreciate your replies!
you have second canvas element next to your canvas, it prevents from clicking on first canvas element, removing this second canvas solves this issue
<canvas class="upper-canvas " width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: manipulation; user-select: none; cursor: default;"></canvas>
<!DOCTYPE html>
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.input-group {
padding: 4px;
}
.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}
.actived {
background: #fff9a8;
}
.list-group {
line-height: 35px;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
.fl {
float: left;
}
.fr {
float: right;
}
.input-group-text {
background-color: #f4f4f4;
}
.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}
.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>
<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<hr>
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: '#000', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: '#000', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
</div>
<hr>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
<form class="form-inline pt-4" id="f" onsubmit="return false;" style="display: none;">
<div class="form-floating w-100 mb-4" style="">
<textarea type="text" class="form-control form-control-sm" name="text" oninput="canvas.getActiveObject().set({'text':this.value}); canvas.renderAll();" onmouseover="this.style.height = (this.scrollHeight)+'px';" rows="10" autocomplete="off"></textarea>
<label for="floatingInput" class="lable-sm">Text</label>
</div>
<div class="input-group input-group-sm mb-3 w-100 tour13">
<span class="input-group-text" id="inputGroup-sizing-sm">MaxHeight to Fit Text</span>
<input type="number" class="form-control" name="maxHeight" onkeyup="hide_mh_box(); show_mh_box();" onblur="hide_mh_box();" onfocus="show_mh_box();" autocomplete="off">
</div>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric#5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;
fabric.Text.prototype.set({
_getNonTransformedDimensions() {
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() {
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});
function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);
if (scale > 1) {
scale = 1;
}
canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);
initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);
canvas.renderAll();
console.log("finished!!");
}
(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});
canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}
if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});
}
if ((o.rx || o.ry) && o.type == "image") {
let rx = (o.rx || 0);
let ry = (o.ry || 0);
o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>
<script>
fabric.Object.prototype.objectCaching = false;
function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}
function setCanvasBI(src, o = "1") {
if (!src) {
src = $("#canvasBI").val();
}
if (src.length == 0) {
src = new fabric.Image('');
}
canvas.setBackgroundImage(src, canvas.renderAll.bind(canvas), {
opacity: o
});
}
(function() {
$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});
fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};
$("form#f").hide();
var activeObject;
$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});
canvas.preserveObjectStacking = true;
fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text
});
};
})(fabric.Object.prototype.toObject);
canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});
canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});
canvas.on("after:render", function() {
canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {
if (typeof layer.name !== 'undefined') {
canvas.getItemByAttr(`name`, layer.name).set({
"name": String.fromCharCode(65 + id).toLowerCase()
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}
}
});
document.body.style.cursor = 'default'
});
canvas.on("selection:created", function(obj) {
if ("image" == obj.target?.type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
showForm();
});
canvas.on("selection:updated", function(obj) {
if ("image" == obj.target?.type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
showForm();
});
canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});
canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});
canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});
function showForm() {
$("form#f").show();
activeObject = canvas.getActiveObject();
var v;
for (i in activeObject) {
v = activeObject[i];
if (typeof v != "undefined") {
$("textarea[name='" + i + "']").val(v).parent().show();
$("input[name='" + i + "']").val(v).parent().show();
$("select[name='" + i + "']").val(v).parent().show();
}
}
}
addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});
canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();
function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}
function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}
var visited = [];
</script>
<script>
function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}
</script>
</body>
</html>

How can I rename an object and render canvas in FabricJS?

I am using FabricJS 5 and have implemented a simple display for my layers.
When I press the pencil button I open a prompt and rename the layer using the following function:
function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);
let newName = prompt("Rename Layer?", layerObj.name);
while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}
layerObj.name = newName;
canvas.renderAll();
}
function checkIfNameExists(newName) {
count = 0;
canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});
if (count > 0) {
return true;
} else {
return false;
}
}
However, after renaming I get an error.
Find below my example:
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.input-group {
padding: 4px;
}
.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}
.actived {
background: #fff9a8;
}
#sortable {
max-height: 200px;
overflow: scroll;
}
.list-group {
line-height: 35px;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
#bkboxXX {
background: url(transparent.png);
border: 1px solid rgba(0, 0, 0, 0.3);
display: inline-block;
height: 19px;
width: 20px;
}
.bk-btn {
background: url(/transparent.png);
}
.fl {
float: left;
}
.fr {
float: right;
}
.input-group-text {
background-color: #f4f4f4;
}
.input-group-sm>.input-group-text {
/*
padding: .2rem .3rem !important;
*/
}
.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}
.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>
<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: 'green', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: 'red', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="canvas.add(new fabric.Rect({ name: genNextName(), originX:'center', originY:'center', left: 110, top: 110, fill: '#000', width: 50, height: 50 }))" data-bs-original-title="Add Rectangle"><i class="fa fa-square-full"></i> </button>
</div>
<hr>
<div class="w-100 tour7 Xd-none Xd-sm-block">
<h6 class="mb-3">Elements</h6>
<ul class="list-group" id="sortable"></ul>
</div>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
right map
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric#5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
function cn2h(cn) {
if (!cn) {
return 'transparent';
}
d = document.createElement("span");
d.style.display = "none";
d.style.color = cn
document.body.appendChild(d)
return rgba2hex(window.getComputedStyle(d).color);
}
</script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;
fabric.Text.prototype.set({
_getNonTransformedDimensions() { // Object dimensions
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() { // Controls dimensions
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});
function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);
if (scale > 1) {
scale = 1;
}
canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);
initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);
canvas.renderAll();
console.log("finished!!");
}
(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});
canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}
if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});
}
if ((o.rx || o.ry) && o.type == "image") {
let rx = (o.rx || 0);
let ry = (o.ry || 0);
o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>
<script>
fabric.Object.prototype.objectCaching = false;
function setCanvasBG(clr) {
canvas.backgroundColor = clr;
canvas.renderAll();
}
function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}
function setColor(clr, what = 'fill') {
canvas.getActiveObject().set(what, clr);
canvas.renderAll();
}
(function() {
$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});
fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};
$("form#f").hide();
var activeObject;
$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});
canvas.preserveObjectStacking = true;
fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text,
textAlign: this.textAlign,
fontSize: this.fontSize,
charSpacing: this.charSpacing,
lineHeight: this.lineHeight,
fontWeight: this.fontWeight,
fontFamily: this.fontFamily,
fontStyle: this.fontStyle,
textBackgroundColor: this.textBackgroundColor,
originX: this.originX,
originY: this.originY,
maxHeight: this.maxHeight,
height: this.height,
width: this.width,
radius: this.radius,
rx: this.rx,
ry: this.ry,
stroke: this.stroke,
padding: this.padding,
circleFrame: this.circleFrame
});
};
})(fabric.Object.prototype.toObject);
canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});
canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});
canvas.on("after:render", function() {
$("#sortable").empty();
canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {
if (typeof layer.name !== 'undefined') {
//console.log(id,layer.name);
//canvas.getItemByAttr(`name`, layer.name).set({ "name": String.fromCharCode(65 + id).toLowerCase() })
canvas.getItemByAttr(`name`, layer.name).set({
"name": layer.name.replace(/ /g, "_")
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}
$("#sortable").append('<li class="list-group-item ui-sortable-handle clearfix ' + actived + '" onClick="canvas.setActiveObject(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();" id=' + layer.name + '>' + layer.name + ' (' + layer.type + ')' + '<span class="fr button-group"><a class="mx-2" title="Edit" href="#" onClick="RenameLayer(`' + layer.name + '`)"><i class="fa fa-pencil-alt" aria-hidden="true"></i></a><a class="mx-2" title="Delete" href="#" onClick="if(confirm(`Are you sure?`)){canvas.remove(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();}"><i class="fa fa-trash-alt" aria-hidden="true"></i></a><a class="me-2" title="Duplicate this layer" href="#" onClick="Duplicate(`' + layer.name + '`); canvas.renderAll();"><i class="fa fa-clone" aria-hidden="true"></i></a></span></li>');
}
});
document.body.style.cursor = 'default'
});
canvas.on("selection:created", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
});
canvas.on("selection:updated", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
});
canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});
canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});
canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});
addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});
canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();
function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}
function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}
var visited = [];
$(document).ready(function() {
$("input[type=color]").on("input", function() {
$(this).parent().parent().find('input').first().val(this.value);
});
$("textarea, input").attr("autocomplete", "off");
if (window !== window.parent) {
const url = new URL(document.referrer);
$(".isIframe").removeClass('d-none');
$(".notIframe").hide();
}
});
</script>
<script>
function Duplicate(name) {
Copy(name);
}
function Copy(name) {
canvas.getItemByAttr("name", name).clone(function(cloned) {
cloned.set({
"name": genNextName()
})
_clipboard = cloned;
Paste(name);
canvas.renderAll();
});
}
function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);
let newName = prompt("Rename Layer?", layerObj.name);
while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}
layerObj.name = newName;
canvas.renderAll();
}
function checkIfNameExists(newName) {
count = 0;
canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});
if (count > 0) {
return true;
} else {
return false;
}
}
function Paste(name) {
_clipboard.clone(function(clonedObj) {
canvas.discardActiveObject();
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});
if (clonedObj.type === 'activeSelection') {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function(obj) {
canvas.add(obj);
});
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}
_clipboard.top += 10;
_clipboard.left += 10;
canvas.setActiveObject(clonedObj);
canvas.requestRenderAll();
});
}
function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.borderColor = '#5cdce4';
fabric.Object.prototype.cornerColor = 'white';
fabric.Object.prototype.cornerStrokeColor = 'blue';
fabric.Object.prototype.cornerStyle = 'circle';
fabric.Object.prototype.cornerSize = 10;
fabric.Object.prototype.borderScaleFactor = 2;
</script>
</body>
</html>
Any suggestions what I am doing wrong?
I appreciate your replies!
I didn't do deep debugging of the code, but since in many places the layer "name" is used as a key value, you can try renaming the layer (and subsequent updating) in a separate macrotask, using setTimeout.
Instead of this code:
layerObj.name = newName;
canvas.renderAll();
try this code:
setTimeout(() => {
layerObj.name = newName;
canvas.renderAll();
});
Example of your code with setTimeout:
<html lang="en">
<head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.9.0/font/bootstrap-icons.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css">
<style>
html,
body {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
body {
touch-action: none;
background-image: linear-gradient(to bottom left, rgb(214, 240, 201) 10%, rgba(255, 231, 191, 1) 80%);
-webkit-user-select: none;
-moz-user-select: -moz-none;
-ms-user-select: none;
user-select: none;
}
.input-group {
padding: 4px;
}
.canvas-container {
margin: 0 auto;
width: 100%;
overflow: hidden;
background: url(./transparent.png);
background-size: 15px 15px;
box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 1px 3px 1px;
}
.actived {
background: #fff9a8;
}
#sortable {
max-height: 200px;
overflow: scroll;
}
.list-group {
line-height: 35px;
}
.svg-icon {
width: 1em;
height: 1em;
}
.svg-icon path,
.svg-icon polygon,
.svg-icon rect {
fill: #4691f6;
}
.svg-icon circle {
stroke: #4691f6;
stroke-width: 1;
}
#bkboxXX {
background: url(transparent.png);
border: 1px solid rgba(0, 0, 0, 0.3);
display: inline-block;
height: 19px;
width: 20px;
}
.bk-btn {
background: url(/transparent.png);
}
.fl {
float: left;
}
.fr {
float: right;
}
.input-group-text {
background-color: #f4f4f4;
}
.input-group-sm>.input-group-text {
/*
padding: .2rem .3rem !important;
*/
}
.list-group-item {
padding: 2px 10px;
;
cursor: pointer;
}
.list-group {
border-radius: 0;
text-align: left;
}
</style>
</head>
<body>
<div class="container-fluid h-100">
<div class="row h-100">
<div class="col-sm-3 border-end text-center h-100 overflow-scroll bg-light py-3">
<div class="form-floating w-100 mb-3 tour5">
<h6 class="mb-3">Add Element</h6>
<button class="btn btn-outline-primary" onclick="addText();" data-toggle="tooltip" data-placement="top" title="" data-bs-original-title="Add Text" aria-label="Add Text"><i
class="fa fa-font"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Circle({ name: genNextName(), originX:'center', originY:'center', radius: 30, fill: 'green', top: 100, left: 100 }));" data-bs-original-title="Add Circle"
aria-label="Add Circle"><i
class="fa fa-circle"></i></button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick=" canvas.add(new fabric.Triangle({ name: genNextName(), originX:'center', originY:'center', height:100, width:100, fill: 'red', top: 100, left: 100 }));"
data-bs-original-title="Add Triangle">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="triangle" role="img"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" class=""
style="height: 16px;top: 9px;">
<path fill="currentColor"
d="M329.6 24c-18.4-32-64.7-32-83.2 0L6.5 440c-18.4 31.9 4.6 72 41.6 72H528c36.9 0 60-40 41.6-72l-240-416z"
class=""></path>
</svg>
</button>
<button class="btn btn-outline-primary" data-toggle="tooltip" data-placement="top" title="" onclick="canvas.add(new fabric.Rect({ name: genNextName(), originX:'center', originY:'center', left: 110, top: 110, fill: '#000', width: 50, height: 50 }))" data-bs-original-title="Add Rectangle"><i class="fa fa-square-full"></i> </button>
</div>
<hr>
<div class="w-100 tour7 Xd-none Xd-sm-block">
<h6 class="mb-3">Elements</h6>
<ul class="list-group" id="sortable"></ul>
</div>
</div>
<div class="col-sm-6 my-auto py-4 overflow-hidden">
<div class="canvas-container" style="width: 329px; height: 329px; position: relative; user-select: none;"><canvas id="c" class="lower-canvas" width="329" height="329" style="position: absolute; width: 329px; height: 329px; left: 0px; top: 0px; touch-action: none; user-select: none;"></canvas>
</div>
</div>
<div class="col-sm-3 border-start py-3 h-100 overflow-scroll bg-light text-center">
right map
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js"></script>
<script src="https://unpkg.com/fabric#5.2.1/dist/fabric.min.js"></script>
<script src="https://rawcdn.githack.com/lyzerk/fabric-history/8c223cbdc8305307b4a8f8710f97da54d9146ffa/src/index.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/centering_guidelines.js"></script>
<script src="https://rawgit.com/fabricjs/fabric.js/master/lib/aligning_guidelines.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.10/webfont.js"></script>
<script>
const rgba2hex = (rgba) => `#${rgba.match(/^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+\.{0,1}\d*))?\)$/).slice(1).map((n, i) => (i === 3 ? Math.round(parseFloat(n) * 255) : parseFloat(n)).toString(16).padStart(2, '0').replace('NaN', '')).join('')}`
function cn2h(cn) {
if (!cn) {
return 'transparent';
}
d = document.createElement("span");
d.style.display = "none";
d.style.color = cn
document.body.appendChild(d)
return rgba2hex(window.getComputedStyle(d).color);
}
</script>
<script>
var canvas;
var apiUrl;
var startedLoadingFamilies = false;
var to;
var scale;
fabric.Text.prototype.set({
_getNonTransformedDimensions() { // Object dimensions
return new fabric.Point(this.width, this.height).scalarAdd(this.padding);
},
_calculateCurrentDimensions() { // Controls dimensions
return fabric.util.transformPoint(this._getTransformedDimensions(), this.getViewportTransform(), true);
}
});
function fitCanvas(w, h) {
var scaleW = (document.querySelectorAll(".col-sm-6")[0].offsetWidth - 100) / w;
var scaleH = (document.querySelectorAll("body")[0].offsetHeight - 100) / h;
scale = Math.min(scaleH, scaleW);
if (scale > 1) {
scale = 1;
}
canvas.setZoom(scale);
canvas.setWidth(w * scale);
canvas.setHeight(h * scale);
initAligningGuidelines(canvas);
initCenteringGuidelines(canvas);
canvas.renderAll();
console.log("finished!!");
}
(function() {
canvas = new fabric.Canvas('c', {
allowTouchScrolling: true
});
WebFont.load({
google: {
families: ["Inter:200"]
},
active: function() {
canvas.loadFromJSON({
"height": "500",
"width": "500",
"edit": "yes",
"objects": [],
"backgroundImage": {
"crossOrigin": "anonymous"
}
}, function() {
fitCanvas(500, 500);
})
}
});
canvas.on('before:render', function(opt) {
canvas.getObjects().map(function(o, i) {
if (o.type.toLowerCase() == "textbox") {
var maxH = (o.maxHeight) ? (o.maxHeight) : (canvas.height);
o.set({
'maxHeight': maxH
});
if (o.fontSize > 0 && (maxH > o.fontSize)) {
while (o.height > maxH) {
o.set({
'fontSize': o.fontSize - 1
});
}
}
}
if (o.circleFrame) {
o.set({
clipPath: new fabric.Circle({
radius: o.width / 2,
originX: 'center',
originY: 'center'
})
});
}
if ((o.rx || o.ry) && o.type == "image") {
let rx = (o.rx || 0);
let ry = (o.ry || 0);
o.set({
clipPath: new fabric.Rect({
rx: rx,
ry: ry,
height: o.height,
width: o.width,
originX: 'center',
originY: 'center'
})
});
}
});
});
})();
</script>
<script>
fabric.Object.prototype.objectCaching = false;
function setCanvasBG(clr) {
canvas.backgroundColor = clr;
canvas.renderAll();
}
function changeDim() {
fitCanvas($("#widthC").val(), $("#heightC").val());
}
function setColor(clr, what = 'fill') {
canvas.getActiveObject().set(what, clr);
canvas.renderAll();
}
(function() {
$(document).on("mouseenter", "[data-label]", function() {
$("#font-search").val($(this).data("label"));
loadFont($(this).data("label"));
});
fabric.Canvas.prototype.getItemByAttr = function(attr, name) {
var object = null,
objects = this.getObjects();
for (var i = 0, len = this.size(); i < len; i++) {
if (objects[i][attr] && objects[i][attr] == name) {
object = objects[i];
break;
}
}
return object;
};
$("form#f").hide();
var activeObject;
$("#f input, #f select").on("input", function() {
if (["height", "width", "top", "left", "strokeWidth", "charSpacing"].includes(this.name)) {
canvas.getActiveObject().set(this.name, parseFloat(this.value)).setCoords();
} else {
canvas.getActiveObject().set(this.name, this.value).setCoords();
}
canvas.renderAll();
});
canvas.preserveObjectStacking = true;
fabric.Object.prototype.toObject = (function(toObject) {
return function() {
return fabric.util.object.extend(toObject.call(this), {
name: this.name,
text: this.text,
textAlign: this.textAlign,
fontSize: this.fontSize,
charSpacing: this.charSpacing,
lineHeight: this.lineHeight,
fontWeight: this.fontWeight,
fontFamily: this.fontFamily,
fontStyle: this.fontStyle,
textBackgroundColor: this.textBackgroundColor,
originX: this.originX,
originY: this.originY,
maxHeight: this.maxHeight,
height: this.height,
width: this.width,
radius: this.radius,
rx: this.rx,
ry: this.ry,
stroke: this.stroke,
padding: this.padding,
circleFrame: this.circleFrame
});
};
})(fabric.Object.prototype.toObject);
canvas.on('object:scaling', function(e) {
if (e.target.toObject().type != "image" && e.target.toObject().type != "circle") {
e.target.set({
width: e.target.width * e.target.scaleX,
height: e.target.height * e.target.scaleY,
scaleX: 1,
scaleY: 1
})
}
});
canvas.on('object:modified', function(opt) {
document.body.style.cursor = 'progress';
});
canvas.on("after:render", function() {
$("#sortable").empty();
canvas.includeDefaultValues = false;
canvas.toObject().objects.forEach(function(layer, id) {
if (typeof layer.name !== 'undefined') {
//console.log(id,layer.name);
//canvas.getItemByAttr(`name`, layer.name).set({ "name": String.fromCharCode(65 + id).toLowerCase() })
canvas.getItemByAttr(`name`, layer.name).set({
"name": layer.name.replace(/ /g, "_")
})
var actived = '';
if (canvas.getActiveObject()) {
actived = (canvas.getActiveObject().name == layer.name) ? " actived" : "";
}
$("#sortable").append('<li class="list-group-item ui-sortable-handle clearfix ' + actived + '" onClick="canvas.setActiveObject(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();" id=' + layer.name + '>' + layer.name + ' (' + layer.type + ')' + '<span class="fr button-group"><a class="mx-2" title="Edit" href="#" onClick="RenameLayer(`' + layer.name + '`)"><i class="fa fa-pencil-alt" aria-hidden="true"></i></a><a class="mx-2" title="Delete" href="#" onClick="if(confirm(`Are you sure?`)){canvas.remove(canvas.getItemByAttr(`name`,`' + layer.name + '`)); canvas.renderAll();}"><i class="fa fa-trash-alt" aria-hidden="true"></i></a><a class="me-2" title="Duplicate this layer" href="#" onClick="Duplicate(`' + layer.name + '`); canvas.renderAll();"><i class="fa fa-clone" aria-hidden="true"></i></a></span></li>');
}
});
document.body.style.cursor = 'default'
});
canvas.on("selection:created", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
$("form#f input[type!='hidden'], #f select").parent().hide();
$("form#f").hide();
canvas.renderAll();
});
canvas.on("selection:updated", function(obj) {
if ("image" == obj.selected[0].type) {
canvas.getActiveObject().setControlsVisibility({
mb: false,
ml: false,
mt: false,
mr: false
});
}
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'] , #f select, #f textarea").parent().hide();
});
canvas.on("selection:cleared", function() {
canvas.renderAll();
$("form#f").hide();
$("form#f input[type!='hidden'], #f select, #f textarea").parent().hide();
});
canvas.hoverCursor = 'default';
canvas.on('mouse:over', function(e) {
if (e.target) {
e.target._renderControls(canvas.contextTop, {
hasControls: false
})
}
});
canvas.on('mouse:out', function(e) {
canvas.clearContext(canvas.contextTop);
});
canvas.on('mouse:down', function(e) {
canvas.clearContext(canvas.contextTop);
});
addText = function() {
var text = new fabric.Textbox("Edit this Text", {
name: genNextName(),
left: canvas.getWidth() / canvas.getZoom() / 2,
top: canvas.getHeight() / canvas.getZoom() / 2,
width: (canvas.getWidth() / canvas.getZoom()) / 2,
fill: "#000000",
originX: "center",
originY: "center",
fontFamily: "Inter",
fontWeight: 400,
fontSize: 60,
padding: 20
});
text.setControlsVisibility({
mt: false,
mb: false,
ml: true,
mr: true,
tl: true,
tr: true,
bl: true,
br: true
});
canvas.add(text);
canvas.setActiveObject(text);
canvas.renderAll();
};
})();
function hide_mh_box() {
canvas.remove(canvas.getItemByAttr("isBB", true));
}
function show_mh_box() {
var h = parseInt($("[name=maxHeight]").val());
var n = new fabric.Rect({
top: canvas.getActiveObject().get('top'),
left: canvas.getActiveObject().get('left'),
width: canvas.getActiveObject().get('width'),
height: h,
originX: canvas.getActiveObject().get('originX'),
originY: canvas.getActiveObject().get('originY'),
angle: canvas.getActiveObject().get('angle'),
opacity: 1,
strokeWidth: 2,
stroke: "#FF00FF",
fill: "rgba(0,0,0,0)",
evented: !1,
isBB: true
});
canvas.add(n);
canvas.renderAll();
}
var visited = [];
$(document).ready(function() {
$("input[type=color]").on("input", function() {
$(this).parent().parent().find('input').first().val(this.value);
});
$("textarea, input").attr("autocomplete", "off");
if (window !== window.parent) {
const url = new URL(document.referrer);
$(".isIframe").removeClass('d-none');
$(".notIframe").hide();
}
});
</script>
<script>
function Duplicate(name) {
Copy(name);
}
function Copy(name) {
canvas.getItemByAttr("name", name).clone(function(cloned) {
cloned.set({
"name": genNextName()
})
_clipboard = cloned;
Paste(name);
canvas.renderAll();
});
}
function RenameLayer(name) {
let layerObj = canvas.getItemByAttr("name", name);
let newName = prompt("Rename Layer?", layerObj.name);
while (checkIfNameExists(newName)) {
alert("Your layer name: " + layerObj.name + " is NOT unique please rename your layer differently.")
newName = prompt("Rename Layer?", layerObj.name);
}
setTimeout(() => {
layerObj.name = newName;
canvas.renderAll();
})
}
function checkIfNameExists(newName) {
count = 0;
canvas.forEachObject(function(obj, i) {
if (obj.name == newName) {
count++;
}
});
if (count > 0) {
return true;
} else {
return false;
}
}
function Paste(name) {
_clipboard.clone(function(clonedObj) {
canvas.discardActiveObject();
clonedObj.set({
left: clonedObj.left + 10,
top: clonedObj.top + 10,
evented: true,
});
if (clonedObj.type === 'activeSelection') {
clonedObj.canvas = canvas;
clonedObj.forEachObject(function(obj) {
canvas.add(obj);
});
clonedObj.setCoords();
} else {
canvas.add(clonedObj);
}
_clipboard.top += 10;
_clipboard.left += 10;
canvas.setActiveObject(clonedObj);
canvas.requestRenderAll();
});
}
function genNextName() {
canvas.renderAll();
var total = canvas.getObjects().length;
return String.fromCharCode(65 + total).toLowerCase()
}
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.borderColor = '#5cdce4';
fabric.Object.prototype.cornerColor = 'white';
fabric.Object.prototype.cornerStrokeColor = 'blue';
fabric.Object.prototype.cornerStyle = 'circle';
fabric.Object.prototype.cornerSize = 10;
fabric.Object.prototype.borderScaleFactor = 2;
</script>
</body>
</html>
This solution is not optimal. But to be honest, the whole code needs serious refactoring. However, perhaps such a solution at the moment will be able to suit you.

canvasjs Charts takes too much time to render

through WebSocket fetching the data from The developers.binary but canvasjs is rendering to the charts taking too much time but I saw that a lot of charts all are rendering normally not taking much time. I want to know that why it happens
what should I do to render the charts quickly?
I need to visible the charts quickly
is it taking time to the API call or I've mistaken anything?
window.addEventListener('load', function(e) {
var ws, b, rnd, spot, time, dps, xd, digit, cnt, random, id, lng, str, chart, xVal, yVal, mType, mColor, rndMenu;
ws = new WebSocket("wss://ws.binaryws.com/websockets/v3?app_id=3738&l=" + lng);
str = ["R_100", "R_10", "R_25", "R_50", "R_75", "RDBEAR", "RDBULL"];
dps = [];
time = [0];
spot = [0];
digit = [0];
mType = "none";
mColor = "#32cd32";
lng = "EN";
xVal = 0;
yVal = 0;
cnt = 20;
rndMenu = document.querySelectorAll('div.menu > span');
function toggleDigit(d, m) {
var nameClass = document.querySelector("#digits > span:nth-child(" + d + ")").className;
if (nameClass != "digits_moved_" + m) {
document.querySelector("#digits > span:nth-child(" + d + ")").classList.remove(nameClass);
document.querySelector("#digits > span:nth-child(" + d + ")").classList.add("digits_moved_" + m);
}
}
function rndGet() {
random = document.querySelector("body > div.menu > span.menu-active").title;
rnd = "R_10";
xd = 3;
}
rndGet();
ws.onopen = function(evt) {
ws.send(JSON.stringify({
ticks: rnd
}));
};
ws.onmessage = function(msg) {
b = JSON.parse(msg.data);
if (b.tick) {
if (b.echo_req.ticks == rnd) {
id = b.tick.id;
ws.send(JSON.stringify({
ticks_history: rnd,
end: "latest",
start: 1,
style: "ticks",
count: cnt + 1
}));
} else {
ws.send(JSON.stringify({
forget: id
}));
ws.send(JSON.stringify({
forget_all: "ticks"
}));
ws.send(JSON.stringify({
ticks: rnd
}));
};
};
if (b.history) {
if (b.echo_req.ticks_history == rnd) {
for (var i = 0; i < cnt + 1; i++) {
time[i] = b.history.times[cnt - i];
spot[i] = b.history.prices[cnt - i];
spot[i] = Number(spot[i]).toFixed(xd);
digit[i] = spot[i].slice(-1);
}
for (var i = 0; i < cnt + 1; i++) {
xVal = new Date(time[i] * 1000);
yVal = parseFloat(spot[i]);
if (i == 0) mType = "circle";
else mType = "none";
if (yVal == Math.max.apply(null, spot)) {
mColor = "#29abe2";
mType = "circle";
} else if (yVal == Math.min.apply(null, spot)) {
mColor = "#c03";
mType = "circle";
} else {
mColor = "#32cd32";
}
dps.push({
x: xVal,
y: yVal,
markerType: mType,
markerColor: mColor,
markerBorderColor: "#ccc"
});
}
chart.render()
spot.reverse();
digit.reverse();
for (var i = 1; i < cnt + 1; i++) {
document.querySelector("#digits > span:nth-child(" + i + ")").innerHTML = digit[i];
if (spot[i - 1] < spot[i]) {
toggleDigit(i, "up");
} else if (spot[i - 1] > spot[i]) {
toggleDigit(i, "down");
} else if (spot[i - 1] == spot[i] && i - 1 > 0) {
if (document.querySelector("#digits > span:nth-child(" + (i - 1) + ")").className == "digits_moved_up") {
toggleDigit(i, "up");
} else if (document.querySelector("#digits > span:nth-child(" + (i - 1) + ")").className == "digits_moved_down") {
toggleDigit(i, "down");
}
}
}
};
};
};
chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: false,
theme: "light2",
title: {
titleFontSize: 0,
text: ""
},
toolTip: {
enabled: true,
animationEnabled: true,
borderColor: "#ccc",
borderThickness: 1,
fontColor: "#000",
content: "{y}"
},
axisX: {
includeZero: false,
titleFontSize: 0,
labelFontSize: 0,
gridThickness: 0,
tickLength: 0,
lineThickness: 0
},
axisY: {
includeZero: false,
titleFontSize: 0,
labelFontSize: 0,
gridThickness: 0,
tickLength: 0,
lineThickness: 0
},
data: [{
type: "spline",
lineColor: "#ccc",
lineThickness: 2,
markerType: "none",
markerSize: 5,
markerBorderThickness: 0,
dataPoints: dps
}],
});
e.preventDefault()
}, false);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Asim chart</title>
<style>
body {
margin: 0;
padding: 0 10px;
font-size: 16px;
text-align: center;
font-family: "Arial", sans-serif;
}
h1 {
font-size: 34px;
}
.menu {
margin-bottom: 16px;
display: flex;
}
.menu span {
padding: 3px 0;
flex-basis: auto;
flex-grow: 1;
text-align: center;
font-size: 16px;
border-radius: 5px;
color: #fff;
background-color: #666666;
}
.menu span:hover {
background: #191919;
}
span.menu-active {
background: #191919;
}
.digits {
margin-bottom: 20px;
display: flex;
}
.disclaimer {
font-size: 11px;
text-align: center;
font-family: "Arial", sans-serif;
color: #707070;
}
.digits span {
padding: 25px 0;
flex-basis: auto;
flex-grow: 1;
text-align: center;
font-size: 24px;
border-radius: 15px;
color: #fff;
}
.digits_moved_down {
background-color: #c03;
}
.digits_moved_up {
background-color: #29abe2;
}
.chartContainer {
min-height: 350px;
min-width: 50px;
}
</style>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body class="EN">
<h1>charts</h1>
<h3>charts difference</h3>
<div class="menu">
<span class="" title="R_100">100</span>
<span class="menu-active" title="R_10">10</span>
<span class="" title="R_25">25</span>
<span class="" title="R_50">50</span>
<span class="" title="R_75">75</span>
<span class="" title="RDBEAR">ODD/EVEN</span>
<span class="" title="RDBULL">MATCH/DIFFERS</span>
</div>
<p>Charts might take up to 30 secs to load.. please wait...</p>
<div id="digits" class="digits">
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
</div>
<div class="chartContainer" id="chartContainer"></div>
<div class="disclaimer">
</div>
</body>
</html>
Chart is getting rendered within 20-30 milliseconds. However, API call & the response seems to be taking 3-5 secs. Below is the code showcasing the time taken:
window.addEventListener('load', function (e) {
var timeNow;
var ws, b, rnd, spot, time, dps, xd, digit, cnt, random, id, lng, str, chart, xVal, yVal, mType, mColor, rndMenu;
ws = new WebSocket("wss://ws.binaryws.com/websockets/v3?app_id=3738&l=" + lng);
str = ["R_100", "R_10", "R_25", "R_50", "R_75", "RDBEAR", "RDBULL"];
dps = [];
time = [0];
spot = [0];
digit = [0];
mType = "none";
mColor = "#32cd32";
lng = "EN";
xVal = 0;
yVal = 0;
cnt = 20;
rndMenu = document.querySelectorAll('div.menu > span');
function toggleDigit(d, m) {
var nameClass = document.querySelector("#digits > span:nth-child(" + d + ")").className;
if (nameClass != "digits_moved_" + m) {
document.querySelector("#digits > span:nth-child(" + d + ")").classList.remove(nameClass);
document.querySelector("#digits > span:nth-child(" + d + ")").classList.add("digits_moved_" + m);
}
}
function rndGet() {
random = document.querySelector("body > div.menu > span.menu-active").title;
rnd = "R_10";
xd = 3;
}
rndGet();
ws.onopen = function (evt) {
ws.send(JSON.stringify({
ticks: rnd
}));
};
ws.onmessage = function (msg) {
b = JSON.parse(msg.data);
if (b.tick) {
if (b.echo_req.ticks == rnd) {
id = b.tick.id;
ws.send(JSON.stringify({
ticks_history: rnd,
end: "latest",
start: 1,
style: "ticks",
count: cnt + 1
}));
} else {
ws.send(JSON.stringify({
forget: id
}));
ws.send(JSON.stringify({
forget_all: "ticks"
}));
ws.send(JSON.stringify({
ticks: rnd
}));
};
};
if (b.history) {
if (b.echo_req.ticks_history == rnd) {
for (var i = 0; i < cnt + 1; i++) {
time[i] = b.history.times[cnt - i];
spot[i] = b.history.prices[cnt - i];
spot[i] = Number(spot[i]).toFixed(xd);
digit[i] = spot[i].slice(-1);
}
for (var i = 0; i < cnt + 1; i++) {
xVal = new Date(time[i] * 1000);
yVal = parseFloat(spot[i]);
if (i == 0) mType = "circle";
else mType = "none";
if (yVal == Math.max.apply(null, spot)) {
mColor = "#29abe2";
mType = "circle";
} else if (yVal == Math.min.apply(null, spot)) {
mColor = "#c03";
mType = "circle";
} else {
mColor = "#32cd32";
}
dps.push({
x: xVal,
y: yVal,
markerType: mType,
markerColor: mColor,
markerBorderColor: "#ccc"
});
}
var startTime = new Date().getTime();
chart.render();
console.log("Chart rendered in: ", new Date().getTime() - startTime + "ms");
spot.reverse();
digit.reverse();
for (var i = 1; i < cnt + 1; i++) {
document.querySelector("#digits > span:nth-child(" + i + ")").innerHTML = digit[i];
if (spot[i - 1] < spot[i]) {
toggleDigit(i, "up");
} else if (spot[i - 1] > spot[i]) {
toggleDigit(i, "down");
} else if (spot[i - 1] == spot[i] && i - 1 > 0) {
if (document.querySelector("#digits > span:nth-child(" + (i - 1) + ")").className == "digits_moved_up") {
toggleDigit(i, "up");
} else if (document.querySelector("#digits > span:nth-child(" + (i - 1) + ")").className == "digits_moved_down") {
toggleDigit(i, "down");
}
}
}
};
};
};
chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: false,
theme: "light2",
title: {
titleFontSize: 0,
text: ""
},
toolTip: {
enabled: true,
animationEnabled: true,
borderColor: "#ccc",
borderThickness: 1,
fontColor: "#000",
content: "{y}"
},
axisX: {
includeZero: false,
titleFontSize: 0,
labelFontSize: 0,
gridThickness: 0,
tickLength: 0,
lineThickness: 0
},
axisY: {
includeZero: false,
titleFontSize: 0,
labelFontSize: 0,
gridThickness: 0,
tickLength: 0,
lineThickness: 0
},
data: [{
type: "spline",
lineColor: "#ccc",
lineThickness: 2,
markerType: "none",
markerSize: 5,
markerBorderThickness: 0,
dataPoints: dps
}]
});
e.preventDefault()
}, false);
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Asim chart</title>
<style>
body {
margin: 0;
padding: 0 10px;
font-size: 16px;
text-align: center;
font-family: "Arial", sans-serif;
}
h1 {
font-size: 34px;
}
.menu {
margin-bottom: 16px;
display: flex;
}
.menu span {
padding: 3px 0;
flex-basis: auto;
flex-grow: 1;
text-align: center;
font-size: 16px;
border-radius: 5px;
color: #fff;
background-color: #666666;
}
.menu span:hover {
background: #191919;
}
span.menu-active {
background: #191919;
}
.digits {
margin-bottom: 20px;
display: flex;
}
.disclaimer {
font-size: 11px;
text-align: center;
font-family: "Arial", sans-serif;
color: #707070;
}
.digits span {
padding: 25px 0;
flex-basis: auto;
flex-grow: 1;
text-align: center;
font-size: 24px;
border-radius: 15px;
color: #fff;
}
.digits_moved_down {
background-color: #c03;
}
.digits_moved_up {
background-color: #29abe2;
}
.chartContainer {
min-height: 350px;
min-width: 50px;
}
</style>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</head>
<body class="EN">
<h1>charts</h1>
<h3>charts difference</h3>
<div class="menu">
<span class="" title="R_100">100</span>
<span class="menu-active" title="R_10">10</span>
<span class="" title="R_25">25</span>
<span class="" title="R_50">50</span>
<span class="" title="R_75">75</span>
<span class="" title="RDBEAR">ODD/EVEN</span>
<span class="" title="RDBULL">MATCH/DIFFERS</span>
</div>
<p>Charts might take up to 30 secs to load.. please wait...</p>
<div id="digits" class="digits">
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
<span class="_"></span>
</div>
<div class="chartContainer" id="chartContainer"></div>
<div class="disclaimer">
</div>
</body>
</html>

How can I change opacity of not hovered columns on highchart?

Is that possible to change the opacity of not hovered points in Highcharts, without change the default opacity?
I have this columns charts with opacity: 1 for all columns by default. But I want to set all columns with opacity: 0.3, except the hovered one, when user hover a column, like in this example:
Chart without hover in any column:
Chart with hover:
Here is the code:
Html:
this.graphic = Highcharts.chart('graph-roa', {
chart: {
zoomType: 'xy',
marginTop: 20
},
title: {
text: undefined
},
credits: {
text: '',
href: ''
},
xAxis: [{
categories: ['13/07','14/07','15/07','16/07','17/07','20/07', '21/07']
}],
yAxis: [
{
lineWidth: 1,
gridLineWidth: 0,
labels: {
formatter() {
return this.value;
},
style: {
color: Highcharts.getOptions().colors[1]
}
},
title: {
align: 'high',
offset: 3,
text: 'Reais',
rotation: 0,
y: -10
}
},
{
title: {
text: ''
},
labels: {
format: '',
style: {
color: '#fff'
}
},
opposite: true
}
],
tooltip: {
shared: true,
},
legend: {
layout: 'vertical',
align: 'left',
x: 700,
verticalAlign: 'top',
y: 10,
floating: true,
backgroundColor: ('#000' && '#fff') || 'rgba(255,255,255,0.25)'
},
series: [{
name: 'Valor',
type: 'column',
color: '#106D98',
data: [20,60,40,100,20,20,20],
cursor: 'pointer',
}]
});
.graph {
// width: auto;
height: 180px;
display: block;
margin-top: 20px;
}
.demais-dados-roa {
font-family: $tt-norms-regular;
font-size: 14px;
margin-bottom: 2em;
.label {
color: $sec-5;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div class="row demais-dados-roa justify-content-between atual no-gutters">
<div class="col-auto">
<h3 class="graphic-title">
Repasse Esc.
</h3>
<em class="fas fa-info-circle" (click)="tooltipVisible = true"></em>
</div>
<div class="col-auto">
<div class="row no-gutters">
<h3 class="graphic-title ml-auto">
1,50k
</h3>
</div>
<div class="row no-gutters">
<p class="label">
Acum. Julho
</p>
</div>
</div>
</div>
<div id="graph-roa" class="graph"></div>
You can achieve it by using the mouseOver and mouseOut callbacks to changes the opacity of the points.
Demo: https://jsfiddle.net/BlackLabel/1srupnxk/
point: {
events: {
mouseOver() {
let series = this.series;
series.points.forEach(p => {
p.graphic.css({
opacity: 0.3
})
})
this.graphic.css({
opacity: 1
})
},
mouseOut() {
let series = this.series;
series.points.forEach(p => {
p.graphic.css({
opacity: 1
})
})
}
}
},
API: https://api.highcharts.com/highcharts/series.column.point.events.mouseOver
Here's the code.
The idea is:
.outer:hover > * { opacity: 0.4; } here all the red items are slightly faded on hover.
Now .outer:hover > *:hover is to style the current item that is hovered.
.outer {
display: inline-block;
}
.inner {
height: 100px;
width: 20px;
background: red;
display: inline-block;
margin-right: 10px;
}
.outer:hover > * {
opacity: 0.4;
}
.outer:hover > *:hover {
transform: scale(1.1);
opacity: 1;
}
<div class="outer">
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
<div class="inner"></div>
</div>

Strange behavior Highcharts pie chart in document mode IE8

I have 4 pie charts next to each other in a bootstrap grid which all show well in IE11 document modes IE5, IE7, IE9+, but not on IE8.
What it does in document mode IE8:
When I refresh the page with ctrl+f5: the charts show correct. When I refresh with f5: the charts have a way to big container and display out of screen (and way out of the grid)
My JS:
$(function () {
var chart;
var options = {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
height: 200
},
legend: {
align: 'right',
verticalAlign: 'top',
x: 0,
y: 40,
layout: 'vertical'
},
credits: {
enabled: false
},
title: {
margin: 30,
style: {
color: '#6e685c',
fontSize: '10px'
}
},
tooltip: {
pointFormat: 'Aantal: <b>{point.y}</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
size:'100%',
dataLabels: {
enabled: true,
color: '#454545',
format: '{point.y}',
distance: 10
}
}
}
}
$(document).ready(function () {
// Build the chart
options.title.text = 'Financieel fout';
options.series = [{
type: 'pie',
name: 'Kwaliteit',
data: [{
name: 'Goed',
color: '#93ab48',
y: 3
}, {
name: 'Fout',
color: '#ac4742',
y: 3
}, {
name: 'Onzeker',
color: '#e09647',
y: 1
}]
}];
$('#graph-1').highcharts(options);
// Build the chart
options.title.text = 'Financieel onzeker';
options.series = [{
type: 'pie',
name: 'Kwaliteit',
data: [{
name: 'Goed',
color: '#93ab48',
y: 3
},{
name: 'Fout',
color: '#ac4742',
y: 1
}]
}];
$('#graph-2').highcharts(options);
// Build the chart
options.title.text = 'Service desk';
options.series = [{
type: 'pie',
name: 'Kwaliteit',
data: [{
name: 'Goed',
color: '#93ab48',
y: 3
}, {
name: 'Fout',
color: '#ac4742',
y: 3
}, {
name: 'Onzeker',
color: '#e09647',
y: 1
}]
}];
$('#graph-3').highcharts(options);
// Build the chart
options.title.text = 'Controle';
options.series = [{
type: 'pie',
name: 'Kwaliteit',
data: [{
name: 'Goed',
color: '#93ab48',
y: 3
},{
name: 'Fout',
color: '#ac4742',
y: 1
}]
}];
$('#graph-4').highcharts(options);
});
$("body").width($("body").width()-200).delay(1000).width($("body").width()+200);
});
The HTML:
<div class="row">
<div class="col-md-6 graph-container border-right">
<h4>Rechtmatigheid</h4>
<div class="clearfix">
<div id="graph-1" class="col-md-6 no-horizontal-padding"></div>
<div id="graph-2" class="col-md-6 no-horizontal-padding border-right"></div>
</div>
</div>
<div class="col-md-3 graph-container border-right no-horizontal-padding">
<h4 class="padding-left">Kwaliteit</h4>
<div class="graph-container">
<div id="graph-3" class=""></div>
</div>
</div>
<div class="col-md-3 graph-container no-horizontal-padding">
<h4 class="padding-left">Workload</h4>
<div class="graph-container">
<div id="graph-4" class="no-horizontal-padding"></div>
</div>
</div>
</div>
And the CSS
/***************************************************************/
/* GRAPHS */
/***************************************************************/
.graph-container{
}
.graph-container.border-right{
border-right: 1px solid #e5e5e5;
}
.graph-container .graphs-info{
margin: 20px 0px;
}
.graphs-info{
color: #6e685c;
line-height: 26px;
}
.graphs-info .content-title{
font-size: 17px;
font-weight: bold;
display: block;
margin-bottom: 20px;
}
.graphs-info .graphs-info-title{
display: inline-block;
margin-right: 6px;
}
.graphs-info .error{
color: #830020;
}
.padding-left{
padding-left: 20px !important;
}
Do I do something wrong or is this a bug? And will this occur in IE8 (actual browser)
Use comments in HTML for IE8, like this:
<!--[if IE 8]>
<style>...</style>
<![endif]-->
The bug didn't occur on IE8 running on Host OS Windows XP. Therefor the problem is actually non-existent. Another heads up that I should really test on actual IE8 and not the document modes.

Categories

Resources