Appending a circle to an svg using javascript called by php - javascript

I have been searching for an answer that will work and have been unable to find one.
I have a game map that I am using for an RP guild. I am using the map to display influence which we hold in that game's world. I have no issue displaying the map if I have it all coming through in echo statements in php, however, what I would like to do is only have the influence areas draw on the map as pulled from the database.
I have the following function which works when called from within my .js file:
function drawInfluence(id, x, y, inf, dis) {
svg = document.getElementById("small_map");
var pt = svg.createSVGPoint();
pt.x = x;
pt.y = y;
var c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute('id',"c"+id);
c.setAttribute('r',"15");
c.setAttribute('cx',pt.x);
c.setAttribute('cy',pt.y);
c.setAttribute('fill',inf);
c.setAttribute('stroke-width','5');
c.setAttribute('stroke',dis);
svg.appendChild(c);
}
This function works perfect if I call it like this:
$(document).ready(function() {
$("#small_map").load( function() {
drawInfluence(1, 150, 150, "red", "blue");
});
});
However, if I use:
$(document).ready(function() {
$("#small_map").load( function() {
$.ajax({
url: 'scripts/inf_map_load.php',
success: function () {
// There is nothing to do here right now
}
});
});
});
with a PHP file that looks like:
<?php
echo' drawInfluence(1, 150, 150, "red", "blue");';
?>
or like
<?php
echo' <script type="text/javascript">drawInfluence(1, 150, 150, "red", "blue");</script>';
?>
I receive no output at all.
The function is in my .JS file along with my other JQuery callbacks for other functions (which are working perfectly fine.)
I have also tried:
$(document).ready(function() {
$("#small_map").load( function() {
$.ajax({
url: 'scripts/inf_map_load.php',
success: function () {
alert("Testing");
drawInfluence(1, 150, 150, "red", "blue");
}
});
});
});
And the circle will draw where it's supposed to as well as the alert popping up I can't use the drawInfluence from this area though because the end goal is to have the the information for the javascript call to be read from a database which contains multiple rows of data which will each have a unique identifier for hover and click events. Writing the entire document using php echo statements works, but is not the most efficient and I would prefer to use callbacks rather than inline svg javascript.

After playing around with it some more I found that placing an empty div tag with an id and using the following code I was able to get the script to do what I wanted though it draws the influence areas before the map finishes loading. Not a big issue but not aesthetically pleasing either.
In my .JS file:
$(document).ready(function() {
$("#map_load").load("scripts/inf_map_load.php");
});
My PHP file
<?php
echo'<script type="text/javascript">drawInfluence(1, 150, 150, "red", "blue")';
?>
And the empty div which made it work
<div id="map_load"></div>
I still don't know if this was the best way to do what I needed, but it's working now and that was more important at the moment. Appreciate the replies I did get.

Related

How to load a GV file in d3-graphviz?

I am trying to visualise a GV file with D3-Graphviz library. I have called the GV file directly in my code:
<script src="https://unpkg.com/#hpcc-js/wasm#0.3.11/dist/index.min.js"></script>
<script src="https://unpkg.com/d3-graphviz#3.0.5/build/d3-graphviz.js"></script>
<div id="graph" style="text-align: center;"></div>
<script>
let dots = new FileReader();
dots.readAsText('G.gv')
let dotIndex = 0;
let graphviz = d3.select("#graph").graphviz()
.transition(function () {
return d3.transition("main")
.ease(d3.easeLinear)
.delay(500)
.duration(1500);
})
.logEvents(true)
.on("initEnd", render);
function render() {
var dotLines = dots[dotIndex];
var dot = dotLines.join('');
graphviz
.addImage("images/Officer.png", "50px", "50px")
.addImage("images/Manager.png", "50px", "50px")
.addImage("images/Employee.png", "50px", "50px")
.addImage("images/Service.png", "50px", "50px")
.renderDot(dot);
}
My GV file currently looks like this:
digraph G {
graph [center=true rankdir=LR ratio=compress size="15,10"]
"MainOfficer" [label="MainOfficer" fontsize=10 image="images/MainOfficer.png" shape=plaintext]
"Employee" [label="MainOfficer" fontsize=10 image="images/Employee.png" shape=plaintext]
"Supporter" [label="MainOfficer" fontsize=10 image="images/Manager.png" shape=plaintext]
}
However, when I opened the HTML file, no graph is shown, and when I checked into the console the error is Failed to execute ReadAsText as parameter 1 is not of type "Blob".
I have tried multiple ways to load the G.gv file into the website (from converting it into text and parse to the Javascript code, to rendering GV file to SVG), however none of my approach worked.
So I would like to ask that is there anyway I could load a GV file to d3-Graphviz, so that my graph could be shown without my need to paste the GV file content directly to the Javascript file?
Thank you!

trying to modify the js function so that it gives the same output as it was when called the other js function

I am exporting the content on the webpage to the PDF file, for this i have used jsPDF API and i could able to get it work but now i want to use html2PDF as it resolves few issues which were faced when using jsPDF API.
I have written the function $scope.exportUsingJSPDF which is called when the button Export Using JSPDF is clicked. Similarly i want to implement the function $scope.exportUsingHTML2PDF which uses html2PDF API but could not succeed. Any inputs on how to modify $scope.exportUsingHTML2PDF so that it iterates the divs and shows the div content as shown when invoked using $scope.exportUsingJSPDF by clicking Export using JSPDF API.
Complete online example: https://plnkr.co/edit/454HUFF3rmLlkXLCQkbx?p=preview
js code:
//trying to implement the below function same as $scope.exportUsingJSPDF, so
// that when user click on Export using HTML2PDF button, it exports the content to the PDF and generaes the PDF.
$scope.exportUsingHTML2PDF = function(){
var pdf = new jsPDF('l', 'pt', 'a4');
var pdfName = 'test.pdf';
pdf.canvas.height = 72 * 11;
pdf.canvas.width = 72 * 8.5;
html2pdf(document.getElementByClassName("myDivClass"), pdf, function(pdf){
pdf.save(pdfName);
});
}
$scope.exportUsingJSPDF = function() {
var pdf = new jsPDF('p','pt','a4');
var pdfName = 'test.pdf';
var options = { pagesplit: true};
var $divs = $('.myDivClass') //jQuery object of all the myDivClass divs
var numRecursionsNeeded = $divs.length -1; //the number of times we need to call addHtml (once per div)
var currentRecursion=0;
//Found a trick for using addHtml more than once per pdf. Call addHtml in the callback function of addHtml recursively.
function recursiveAddHtmlAndSave(currentRecursion, totalRecursions){
//Once we have done all the divs save the pdf
if(currentRecursion==totalRecursions){
pdf.save(pdfName);
}else{
currentRecursion++;
pdf.addPage();
//$('.myDivClass')[currentRecursion] selects one of the divs out of the jquery collection as a html element
//addHtml requires an html element. Not a string like fromHtml.
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
console.log(currentRecursion);
recursiveAddHtmlAndSave(currentRecursion, totalRecursions)
});
}
}
pdf.fromHTML($('.myDivClass')[currentRecursion], 15, 20, options, function(){
recursiveAddHtmlAndSave(currentRecursion, numRecursionsNeeded);
});
}
PS: I was trying to modify $scope.exportUsingHTML2PDF so that it gives the same output as generated when clicked on "Export using JSPDF" button which calls the function $scope.exportUsingJSPDF.
The problem lies with your function using exportUsingHTML2PDF, the error is that you need to pass in the html to the function of html2PDF. Manage the page css on the basis of your need.
EDIT: You have wrong library. Please check html2pdf.js library within the plunker
Working plunker: html2pdf
$scope.exportUsingHTML2PDF = function() {
var element = document.getElementById('element-to-print');
html2pdf(element, {
margin: 1,
filename: 'myfile.pdf',
image: {
type: 'jpeg',
quality: 0.98
},
html2canvas: {
dpi: 192,
letterRendering: true
},
jsPDF: {
unit: 'in',
format: 'letter',
orientation: 'portrait'
}
});
}
With JSPDF and HTML2PDF, you have to get used to two fundamentally different coding styles:
JSPDF: imperative (javascript statements)
HTML2PDF: declarative (directives embedded in HTML)
So for page breaks:
JSPDF: pdf.addPage();
HTML2PDF: <div class="html2pdf__page-break"></div>
That should work, however HTML2PDF is buggy and gives a "Supplied data is not a JPEG" error when <div class="html2pdf__page-break"></div> is included (at least it does so for me, in Plunkr), despite being totally what the documentation tells us to do.
I haven't got time to debug it. You'll need to do some research. Someone will have posted a solution somewhere on the web.

Paper undefined in JS function using Raphael

Alright, so I am having a bit of trouble with Raphael and automatic updating of elements.
I've got a file called objects.js which looks something like this:
window.onload = function() {
paper = Raphael(document.getElementById('ikoner'), 600, 200);
pump = paper.circle(50,100,50);
pump.data("id","pump");
pump.data("tag",':="output".tag5:');
}
function objectFill (table) {
paper.forEach(function(e){
var tagValue = e.tag.innerHTML;
var tagId = e.id.innerHTML.trim();
if (tagValue == 0) {
paper.getById(tagId).attr({fill:"white"});
}
}
}
On my main page I've got a script which then calls objectFill on a certain interval, and updates the fill color of my objects.
Now to the problem; when I run the page I get the error that paper is undefined in objectFill. How do I make sure that objectFill will be able to find the paper? I've also tried declaring it outside like:
var paper;
window.onload = function() {
paper = Raphael(document.getElementById('ikoner'), 600, 200);
}
But I do not get that to work either. Anyone know what the problem might be?

Reusing SVG.js code for various SVG's

I'm getting to grips with SVG.js
I have a pattern effect that I've created and would like to use in a number of SVG's.
I can create it in one SVG with the following code...
$( document ).ready(function() {
var draw = SVG('geo').size(1200, 1700);
// 100 lines of js creating geometric pattern, effectively this...
var rect = draw.polygon(coordinates).fill('#fff').stroke({ width: 1, color:'#fff'}).opacity(0)
});
This creates an SVG with ID geo. But I'd like to use this code again to generate various SVG's, ideally with different options (colour etc).
SVG('geo') refers to a particular SVG, how do I make it so I can apply this to any SVG I want on the page?
Hope that made sense
You can define a function that does this repeatedly. Something like the following:
function create_svg(dom_id, width, height, coord) {
var draw = SVG(dom_id).size(width, height);
var rect = draw.polygon(coord)
.fill('#fff')
.stroke({
width: 1,
color: '#fff'
})
.opacity(0);
}
$(function() {
create_svg('geo', 1200, 1700, coordinates);
create_svg('geo2', 1000, 1500, other_coordinates);
)};
If you need to use the created SVGs further, later on in the code, you could make the create_svg function return the created SVG object to a variable in your document.ready function.

Drag and drop SVGs with Raphael JS

Looking for some advice (example would be great) on dragging and dropping SVGs using RaphaelJS.
I have found how to drag an object created withint Raphael
window.onload = function() {
var R = Raphael("canvas", 500, 500);
var c = R.circle(100, 100, 50).attr({
fill: "hsb(.8, 1, 1)",
stroke: "none",
opacity: .5
});
var start = function () {
...
},
move = function (dx, dy) {
...
},
up = function () {
...
};
c.drag(move, start, up);
};​
But I need to be able to adapt this to work with a seperate SVG file(s) so for example
myPage.html has myImage.svg, I need to be able to drag myImage.svg around the 'canvas'.
I'm thinking something like
var c = R.SOMEMETHOD('myImage.svg');
...
c.drag(move, start, up);
For example.
Is there a way to do this and if so, an example would be brilliant!
This magic method doesn't exist in RaphaelJS. But there is a way to accomplish this. You can have a look at the raphael-svg-import project on GitHub which works well for basic svgs
Then, you'll want to use a grouping facility as you cannot use the Set functionnality of RaphaelJS
1 - import your SVG
2 - As you import, mark the elements so they belong to the same group
Enjoy !!

Categories

Resources