Click here to Skip to main content
15,888,401 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hey,

As I say at the end: Sorry for the none-code question. Ignore it if you want :)

I am about to write a chart for a web app. That's no problem. I use chart.js[^], which I've used on several other projects.

My boss had the idea that we could send emails to lost clients with this data to show that current trends are favorable, and that they should consider returning to us.

I have an idea that could make these charts even more useful. I was thinking I could have a handler generate the chart as an image and serve that up when the image is requested. Then, by adding a custRef to the image url, we can customize this image for all our online media we send to each customer.

This is just an idea so far. The image will have to look like the chart.js charts we use on our web apps. I found that I could use PhantomJS to create the chart in an html canvas just like I do on the website. Generating and capturing the image then serving it up via a handler should work beautifully...
Shouldn't it?

That's my question. Aside from the image only being available online, are there any pitfalls I am unaware of? I could invest time trying this out for myself, but it's only worth it if I'm sure it's gonna work.

Sorry for the none-code question. Ignore it if you want :)


btw: this is also so that our second tier brokers (third party sales guys) can copy an image tag and use it directly in emails, posts, tweets etc

What I have tried:

I won't start this until next week anyway, but here's the plan:

Embed an image with the image url pointing to an httpHandler

Use PhantomJS to render the chart from chart.js server-side.

Capture the canvas and an image (prolly png)

return the png from the handler in memory.
Posted
Updated 20-May-16 7:23am
Comments
Sergey Alexandrovich Kryukov 20-May-16 12:53pm    
There is nothing wrong with this question, except a need for some extra clarity.
So please, no need to apologize.

Let's check up your scenario step by step. First of all, your chart should probably be generated automatically, by some client-side code. At this step, I simply mean that you need to generate chart from data programmatically, not manually (interactively). Is that correct?

If so, the question is: why on the client side? The data is usually generated on the server-side, from database, etc., unless it is directly supplied by the user, which would be doubtful. So, what do you have on the server-side?

Let's say, the graphics is already generated on the client side. There is nothing wrong with it if you want to present the data on a Web page, nothing else. But the situation is different when you have to send the same chart by e-mail, because JavaScript doesn't send any mails. There are two problems with that. But first, do I understand you correctly. Do you really mean that the same chart generated on a Web page in a Canvas element should be, in certain cases, sent via e-mail?

If I understand the previously scenario step correctly, those two problems are: 1) you have to sent data back to the server side, to compose and send e-mail; 2) In e-mail, you can send HTML, but the char based on Canvas (chart.js or not) is not just HTML. This is HTML+CSS+JavaScript. So, first of all, why generating the data for the mail on client side at all, if both the source of data and the mailing code have to be on the server side?

That all boils down to the same question: what do you have on the client side? Also, a trivial question: why not allowing the users to save page locally whenever they want? Do you really want to render the char (only) as PNG? If yes, I would understand it, because it's much more likely supported on the client system than fully-fledged Canvas graphics. I guess it's related to what you mean by "lost clients".

If I understand it all or most of it correctly, it makes an interesting question. However, I don't like your approach so far. Say, PhantomJS is designed for different purposes and is specific to WebKit. As you mention "clients", you solution should be for production, it seems totally non-suitable and even unsafe (read Wikipedia article on PhantomJS). At the same time, the problem can be solved reliably on the combination of server- and client-side processing. (Due to mailing, you cannot get away without using server-side programming anyway.)

My last thing is: would SVG sent in mail (perhaps embedded in HTML, which is directly supported by HTML5) be acceptable? This is vector graphic; for charting, it's infinitely better than any bitmap, by obvious reasons. And charting can be totally based on SVG, which is better than Canvas. How about that?

—SA

I don't know whether it would work from server-side code, but the HTMLCanvasElement.toDataURL()[^] should let you export the canvas as a Base64-encoded image.
JavaScript
var canvas = document.getElementById("chart-canvas");
var imageData = canvas.toDataURL("image/png"); // "data:image/png;base64,...."
document.getElementById("chart-image").src = imageData;
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 20-May-16 13:33pm    
I did not know about it; thank you, I up-voted the question, even though it is incomplete and not fully correct.

It certainly cannot be done on the server side. The solution should be using this code on the client side (how else? :-) to obtain image data. There is no need to use imageData for rendering on the page, because the chart is already rendered on Canvas.

Instead, one would need to use Ajax to deliver imageData to the server side. Don't forget that the image should be sent in e-mail, which can be done only on the server side.

This solution suffers from the same problems described in my Solution 2. I credited your solution there. Besides, you and I never tried it. I think I offer reasonable alternatives in my solution, please see.

—SA
Andy Lanng 23-May-16 4:01am    
This was the approach I was looking at. SA's solution brings up SVG, which I will look into as an alternative. I was unaware of SVG so my biggest set back would be rendering the canvas server-side. Thanks for the attention ^_^
Sorry for the incomplete answer. I just want to leave main points as a placeholder and add some more detail when you confirm my assumptions I've made in my comment to the question, of correct me and clarify.

In this comment, I explained the reasons for processing on both client-side and server-side.
Your steps would be

  1. Data (Server-side) to JavaScript (client side);
  2. Client side: JavaScript generates chart (which remains static);
  3. Client side: optional request to send mail, data sent back via Ajax;
  4. Server side: compose e-mail from data, send it;

Can you see the redundancy? The data is already on the server side, and this is where you send e-mail. I don't know the detail of your scenario, who and what should trigger the e-mail operation, but here is how it looks: the server-side code gets the HTTP request, without any graphics on the client side, generates graphics from data (which is also on the server side) directly, composes and sends e-mail. And then the chart can be directly rendered in a bitmap.

There is a problem with that: you have to have two different methods of generation of the same chart: one on the server side, and another on the Canvas, that is, by JavaScript on the client side. Unless you use server-side JavaScript (rare enough these days), it would be two completely different libraries. You would have to achieve logically identical charts by technically different ways. This is doable, but still would be a problem, the problem of development, but even more of maintenance.

This problem can be solved if you get rid of Canvas. I can see two more options: 1) generate all graphics on the server side only as a bitmap; 2) generate all graphics on the server side only as SVG. In both cases, the graphics can be delivered to the client side a the ready-to-show object. If this is a bitmap, it could be embedded in HTML as the img element with href="your-file.PNG"; the same exact file will be embedded in the e-mail HTML part when required. The case of SVG is "infinitely better", because this is vector graphics. Another benefit is using much less traffic than with good-quality bitmap. It can also be sent in e-mail and rendered in HTML (HTML5 required). The big benefit is: JavaScript is not required. You can make the chart dynamic on the client-side with JavaScript, but the chart can be static and just embedded in HTML without any scripts, which would be suitable for e-mail. It is impossible to achieve with Canvas.

There are other benefits of SVG over canvas. The graphic rendering quality is better in some respect. And you can have quite advanced charting based on SVG. To get the feeling of it, please pay attention for D3:
D3.js — Wikipedia, the free encyclopedia[^],
D3.js — Data-Driven Documents[^],
and some impressive examples: D3.js Gallery[^].

By the way, I found a post explaining "Why not Canvas?": How to Make Charts with SVG | CSS-Tricks[^].

This article overviews some other possibilities based on SVG. You can probably find some more: SVG charts[^].

Before you asked about sending a chart in e-mail, you had quite viable Canvas-based solution, in your case, via chart.js. The mailing requirement essentially breaks this solution; it starts to present ridiculous difficulties, which can be easily avoided in the alternative ways.

[EDIT]

I did not know Solution 1, but it can make some alternative. However, there is the same issue for sending e-mail. It can be solved by getting the obtained image data and sending it back to the server side, where the image data can be used to make a bitmap for sending via e-mail.

—SA
 
Share this answer
 
v4
Comments
Andy Lanng 23-May-16 4:33am    
There is much to consider and research here. I have a few jobs to finish before I jump into this.

BTW: the graphic on the client side will be interactive, but a link will be generated allowing our brokers to include the graph image in any other media.

lofty ambitions and this is all only a proof of concept so far ^_^
Sergey Alexandrovich Kryukov 23-May-16 7:23am    
I understand, it looks like a considerably big work.
Interactive graphics is another vote in favor or SVG. Again, look at D3; but it could be something else.
Anyway, I suggest not the final choice, but the logic of choice.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900