exporting ng2-chart canvas to png image - javascript

I would like to create a link to allow the user to download the displayed graph. The way i am currently trying to get it to work is with .toDataUrl is that considered a safe way or is there another way of going about doing this.
HTML:
<canvas id="myChart" baseChart [colors]="colorsOverride" [datasets]="barChartData" [labels]="barChartLabels" [options]="barChartOptions" [legend]="barChartLegend"
[chartType]="barChartType" (chartHover)="chartHovered($event)" (chartClick)="chartClicked($event)">
</canvas>
<div class="footer">
<button (click)="exportGraph()">Export Graph</button>
</div>
Components:
export_graph = <HTMLCanvasElement>document.getElementById("myChart");
downloadLink: string;
exportGraph(){
this.downloadLink = this.export_graph.toDataURL("image/png");
}
When i try to export this is the error message i get in my console:
Cannot read property 'toDataURL' of null

You should use an anchor tag <a> instead of <button>, you can style it to look just like a button. Then you can attach a click event and do it this way:
plunker: http://plnkr.co/edit/xyfWok58R3eQdYk7pAds?p=preview
first, add the download link to your html
DOWNLOAD THIS
then create the downloadCanvas function
downloadCanvas(event) {
// get the `<a>` element from click event
var anchor = event.target;
// get the canvas, I'm getting it by tag name, you can do by id
// and set the href of the anchor to the canvas dataUrl
anchor.href = document.getElementsByTagName('canvas')[0].toDataURL();
// set the anchors 'download' attibute (name of the file to be downloaded)
anchor.download = "test.png";
}
it is important to do the document.getElement... on click instead of before-hand. This way you know for sure the html view and <canvas> has rendered and is done drawing (you see it on the page).
the way you are doing it in your question, you are looking for <canvas> element before it's even rendered on the page, that why it's undefined.

Related

How to reference an image within quotation marks in a script

I am trying to reference an image instead of using text within the script tag in a html page. I am attempting to use an image for a button instead of text. When the button is pressed it changes to the text 'Paused' as shown below.
pauseButton.innerHTML = "Paused";
When it is pressed again it displays the words 'Pause'.
pauseButton.innerHTML = "Pause";
Instead I would like it to display an image I created. This code shows a section where I tried to reference the image.
pauseButton.innerHTML = "url(Images/pausebackground.png)";
Instead of displaying the image it displays 'url(Images/pausebackground.png)' in the form of text.
How can I reference the image within the quotation marks?
You need to put HTML code into innerHTML (as the name suggests). Use an <img> tag:
pauseButton.innerHTML = '<img src="Images/pausebackground.png">';
An image in HTML uses the <img> tag, which has a src attribute pointing to the image URL, as so:
<img src="Images/pausebackground.png">
To insert the image into the HTML, you could use innerHTML, but it is best to add an actual HTML element:
var image = document.createElement('img'); // Create the HTML element
image.setAttribute('src', 'Images/pausebackground.png'); // Set the image src
pauseButton.appendChild(image); // Place it inside the button
To set a different image, all you need to do is change the src attribute on the image tag.
The innerHTML property will change the html inside the element:
<div>
Here is the inner html.
</div>
If you wish to add a image to the inner html, you could use a normal image tag, but remember, just setting the innerHTML will remove anything that is inside of it already.
pauseButton.innerHTML = '<img src="Images/pausebackground.png" />'
If you wish to use the image as a background of the button (which I guess you would rather do) you could either just set the image as the elements style.backgroubndImage property or rather, create a css class and add it to the button when you need (through js).
// Alt 1, changing the style of the element:
pauseButton.style.backgroundImage = "url(Images/pausebackground.png)";
// Alt 2, creating a css class and adding it to the element when needed:
// CSS.
.my-special-button-class {
background-image: url(Images/pausebackground.png)
}
// JS.
pauseButton.classList.add("my-special-button-class");

Change the background image of an element

So I'm having some issues with creating a really simple function that's supposed to change the background image of a div element to match whatever image is being hovered upon by the mouse.
The HTML looks like
<div id = "image">
Hover over an image below to display here.
</div>
<img class = "preview" alt = "Styling with a Bandana" src = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/389177/bacon.jpg" onmouseover = "upDate(this)" onmouseout = "unDo()">
That's just the div element I want to change, alongside one of the images.
So our function is supposed to take in an image element as a parameter. But I'm having a lot of trouble accessing this image parameter's src attribute and using that in the .style.backgroundImage property.
My current code is:
function upDate(previewPic){
var div_element = document.getElementById('image').innerHTML;
var picurl = "url(previewPic.getAttribute('src'))"
div_element.style.backgroundImage = "url(picurl)";
}
And this gets me an error of Uncaught TypeError: Cannot set property 'backgroundImage' of undefined on my browser console.
If you can tell, I'm trying to put the actual div object into a variable, then put the picture url into a variable. Then I want to use the .style.backgroundImage property. This isn't working. But the solution is probably really simple. What could I do to fix it?
There are multiple issues with your code.
Getting the inner html is just setting your variable to a string representation of what's inside the element, which is nothing since it's an <img> tag.
Essentially, you're putting everything in quotes, so javascript doesn't do anything with it.
Remove the .innerHTML from the first line of the function, and then take the parts javascript needs to evaluate as code out of the quotes.
Change your code to:
function upDate(previewPic){
var div_element = document.getElementById('image');
var picurl = "url(" + previewPic.getAttribute('src') +")"
div_element.style.backgroundImage = picurl;
}
This should work.
If I understand on some image hover you want to change div background?
I would do it with jquery:
$('img').hover(function(){
$('div').css(''background-image:'url("image_link")');
});

Select Div of Element in Iframe

I have two pages on the same domain. Home.html and page2.html are their names.
home.html has the following content
<html>
<iframe id="one" src="page2.html" style="display:none"></iframe>
<div id="container">
<h1>Title of Page</h1>
<div id="ShowHere"></div>
</div>
</html>
page2.html has the following content.
<html>
<div id="container">
<span id="target">Some Text</span>
</div>
<span>Don't Show This Text</span>
</html>
I would like to use some javascript to get the contents of "target" from within the iframe with Id="one" on the page home.html and then change the innerhtml of the element id=ShowHere to show the html within the element "target" such that, it shows the words "Some Text" under the word "Title of Page".
I think that the following is a start, put at the bottom of home.html:
<script>
var frameSource = document.getElementById("one").contentWindow.document.documentElement.outerHTML;
// ANSWER TO MY QUESTION
document.getElementById("ShowHere").innerHTML = frameSource;
</script>
I've searched around and seen a few answers that supposedly do this, but none which provide a meaningful explanation of HOW to do this, and none which I can get to work. I'd prefer to use plain vanilla javascript, but Jquery is alright too.
Based on what I am trying to do, which is get the content (i.e. innerhtml) of a div from another page on the same domain, I wonder if there is a better approach than creating an invisible iframe and then reading it. Answers which achieve the desired result, but through another mechanism are also welcome.
Using the answer for this question
So, firstly you have to find the iframe:
var iframe = document.getElementById('one');
Then you should get the iframe contents:
var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
And now you can use getElementById to find DOM-elements in the iframe:
var iframeContent;
if (iframeDocument) {
iframeContent = iframeDocument.getElementById('target').innerHTML;
}
Now in the iframeContent you have the contents of span you need to show on the main page, so you can just find element where you want to display iframeContent and set the innerHTML property:
var divToShow = document.getElementById('ShowHere');
divToShow.innerHTML = iframeContent;
And that's all.
I hope my answer will help you to solve your problem.
Thanks : )
You can use selectors (like getElementById, etc) in iframes similar to those found in your normal window via iframe.contentWindow.document.
So if you wanted to get the contents of target on the second page, you can get it via document.getElementById("one").contentWindow.document.getElementById("target")
Edit:
You also probably should wait until the iframe is loaded before trying to read elements from it. So altogether:
var init = function(){
var frameDocument = document.getElementById("one").contentWindow.document;
document.getElementById("ShowHere").innerHTML = frameDocument.getElementById("target").innerHTML;
};
if(document.getElementById("one").contentWindow.document.getElementById("target")) { // iframe is loaded
init();
} else {
document.getElementById("one").contentWindow.onload = init;
}

Select data attribute within object tags for an SVG

I have a relatively large SVG file, so much so that I would not like to put the entire XML code into my html file. As such, I have been using the object tags to refer to it and implement effects such as changing the transparency within css.
However, I would now like to use some javascript to select this object element and when clicked, change the data attribute to load a different SVG file (essentially alternating between images).
This is a trivial operation using normal img tags but the same approach doesn't seem to work using the object tags.
Here's what I have so far:
<div class="title-bar">
<h1 class="heading">A Gathering of ...</h1>
<object id="trooper" data="images/trooper.svg" type="image/svg+xml"></object>
</div>
For the html, and for the javascript:
addEventListener("load", start);
// else { attachEvent("onload", start); }
function start(){
var logo = document.querySelector("#trooper");
logo.addEventListener("click", logoChange);
}
function logoChange(){
console.log("Clicked");
var src = this.getAttribute("data");
if(src === "images/trooper.svg"){
this.setAttribute("data", "images/rebel.svg");
} else {
this.setAttribute("data", "images/trooper.svg");
}
}
Thanks
the problem is you are using this inside of the logoChange function.
you will have to use the logo variable for getting and setting values.
I would just use the img Tag and avoid the object (don't know the current status, but when I messed around it with Flash some years ago ... strange things happened quite too often):
<img src="images/trooper.svg"></img>
An then just change the source like you used to do ...
(but you can't have JS inside you SVG with img)

Add canvas attributes dynamically?

Say I have the canvas tag in my HTML5 document
<canvas id="fooBar" width="500" height="200"></canvas>
And I also have an empty anchor tag
Spin
and I build my canvas in the head
var fooCanvas = document.getElementById("fooBar");
var barContext = fooCanvas.getContext("2d");
Is there a way I can add:
barContext.fillText("fubar", x,y);
Dynamically via clicking on the anchor tag? What I want is to have a variable in my JS which doesn't always hold the same value, and clicking the a tag would update the canvas fillText attribute every time the link is clicked, My idea to overcome this is to use jQuery and have something like this:
$(document).ready(function(){
$("a").click(function(event){
// Something here
});
});
Obviously this would work on every a tag I have in the document so I'll specify that later on but I'm not too sure on the syntax required to append that canvas attribute to my canvas? Any ideas?
Yes:
var fooCanvas = document.getElementById("fooBar");
var barContext = fooCanvas.getContext("2d");
$(document).ready(function(){
$("a").click(function(event){
barContext.fillText("fubar", x,y);
});
});
Although you might want to use button elements instead of a, since they're not actually links.

Categories

Resources