I'm very new to HTML, SVG, javascript and all what is web programming.
I need to do a synoptic webpage to display different information's on my data acquisition.
I have a python script which read data from physical devices and I'd like to update these acquisition on a web page.
My python script can change svg file fill color of different graphical components.
If , for example, this is my svg file:
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
<g id="Layer_1">
<title>Layer 1</title>
<rect id="svg_1" height="386" width="527" y="94" x="150" stroke="#231F20" fill="yellow"/>
<rect id="svg_2" height="386" width="527" y="114" x="450" stroke="#231F20" fill="yellow"/>
</g>
</svg>
My python script change id="svg_1" or id="svg_2" fill attribute and the file is displayed in this simple html file:
<!DOCTYPE html>
<html>
<head>
<title>HTML SVG</title>
</head>
<body>
<h1>Design</h1>
<img id="demo" alt="" height="600" onload="javascript:(function()
{setTimeout(function(
{document.getElementById('demo').src=document.getElementById('demo').src.split('?'
[0]+'?time='+new Date().getTime();},1000);}())" src="ee.svg" width="800" />
</body>
</html>
the javascript code refreshes svg file every 1 sec.
This simple solution works for few minutes...then the svg file is not anymore displayed...
Any help?
Thanks,
Marcin
Polling is overkill; That is like checking your mailbox every minute for new email.
your Server (Python) should send an Event to all (listening) Clients, on every change
The standard JavaScript EventSource API was developed for that, 3 million years ago
But Microsoft never implemented it in IE, so ahem.. older.. developers reach for WebRTC too often.
For Python code see: Medium.com: Python generator and Server Sent Events
Code should look something like:
Backend:
#route("/stream")
def stream():
def eventStream():
while True:
# Poll data from the database
# and see if there's a new message
if len(messages) > len(previous_messages):
yield "data:
{}\n\n".format(messages[len(messages)-1)])"
return Response(eventStream(), mimetype="text/event-stream")
Front-end:
let eventSource = new EventSource("/stream");
eventSource.onmessage = function(e) {
console.warn(e.detail);
// Yeah, the server sent something!
};
Note: There aren't that many good blogs on SSE (Server Sent Events), because B[mmmm] Microsoft never implemented it in IE, Microsoft Edge (on Chromium) runs a-okay.
For PHP backend see: https://kevinchoppin.dev/blog/server-sent-events-in-php
Related
So I've recently encountered this warning
SVG's SMIL animations (<animate>, <set>, etc.) are deprecated and will be removed. Please use CSS animations or Web animations instead.
Doing as much research as I could, I keep finding excuses about replacing SMIL with web animations (which SMIL is if we're being technical) but this all involves JavaScript and CSS. I use animated SVGs in <img> tags because that's the point of the SVG format: it's an image.
This was really nice and all because it allowed me to at least organize my images on a web that's notorious for being a giant mess (e.g. JavaScript has no imports so you have to fill the global scope).
Now that I can't animate with SVG, is GIF the only option for self-contained animations?
SMIL is not as dead/deprecated as you believe it is. The Chrome developers recently posted this:
We value all of your feedback, and it's clear that there are use cases serviced by SMIL that just don’t have high-fidelity replacements yet. As a result, we’ve decided to suspend our intent to deprecate and take smaller steps toward other options.
In SVG2, most of the SMIL functionality should be available through CSS animations.
But these are still in draft, and only chrome has started implementing some.
Also, chrome message is just a deprecation message, it' not removed yet from this browser, and I doubt other browsers supporting it will remove it any soon.
Anyway, you can already achieve SMIL like animations on browser not supporting it (e.g IE) thanks to javascript polyfills like fakesmile.
Unfortunately, scripts in svg documents loaded through the HTMLImage element (<img>) won't run. So you have to switch from the <img> tag to the <iframe>, <object> or <embed> tags. These tags do allow the execution of scripts, so you just have to import the polyfill in your svg document, and then load your image as you would do within an <img> tag.
Here is an example that will work on IE :
SMILTest.svg
<svg width="120" height="120"
viewPort="0 0 120 120" version="1.1"
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect x="10" y="10" width="100" height="100">
<animate attributeType="XML"
attributeName="x"
from="-100" to="120"
dur="10s"
repeatCount="indefinite"/>
</rect>
<script xlink:href="https://cdn.rawgit.com/FakeSmile/FakeSmile/master/smil.user.js"></script>
</svg>
index.html
...
<object data="SMILTest.svg"></object>
...
Live example
If all your svg images are served from the same domain as your main page, you could also automate it with something like that :
window.addEventListener('load', function(){
var obj = document.querySelectorAll('object[data*=".svg"],iframe[src*=".svg"],embed[src*=".svg"]');
Array.prototype.forEach.call(obj, function(o){
var doc = o.contentDocument;
var s = document.createElementNS('http://www.w3.org/2000/svg','script');
doc.documentElement.appendChild(s);
s.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'https://cdn.rawgit.com/FakeSmile/FakeSmile/master/smil.user.js');
});
});
Live example
I am looking for clarification about combining <title> and <desc> with the element for Accessibility. Is the following a valid implemention?
<svg>
<title>This is an SVG</title>
<desc">Lorem ipsum descriptum...</desc>
<use xlink:href="#symbolID"></use>
</svg>
Or would you place it in the <symbol> element like this?
<symbol id="symbolID">
<title>This is an svg</title>
<desc>Lorem ipsum ...</desc>
<path d="......"/>
</symbol>
Would screen readers be able to pick these up?
Add a role="img" and a screen reader can pick it up. It may announce both the <title> and the <desc> depending on screen reader, browser, and versions of each.
For a little extra compatibility you can added aria-labelledby to tell the screen reader where to look for the explicit accessible name (which also means it may not announce the <desc>). Some combos may read the <title> twice as a result, too, so it behooves you to be brief.
<a href="#"> foo
<svg role="img" aria-labelledby="twitterTitle">
<title id="twitterTitle">Twitter Account</title>
<desc>Twitter account for example</desc>
<use xlink:href="#twitter"/>
</svg>
</a>
I forked your CodePen and marked it up.
You may have already seen these two articles, but if not:
Tips for Creating Accessible SVG at SitePoint by Léonie Watson,
Accessible SVGs at CSS-Tricks by Heather Migliorisi.
I have sport schedules that I would like users to be able to print out on 2 or 4 pages. Tournaments with a large amount of teams would produce hard to read text because there isn't much space for it.
Not sure how to produce printable content with d3js, should I specify values for placement and size in pixels, centimetres, percentage? Percentage sounds good but would need to insert a page break element, maybe provide a separate svg for every page. Can't find a good article on how to do this and am wondering if I've missed something.
The code as is should produce lines with text labels, to fit it all on 2 pages the text in the labels would be very small so want to provide a 4 page version. So my question is: What would be the best way to do this?
I'm thinking of providing 4 or 2 svg elements with a page-break-after css style. The shape and dimensions would be roughly letter or a4 landscape and placement units are based on percentages.
[UPDATE]
Since pageSet and page elements seem to be ignored by Firefox (and inkscape) and wrongly interpreted by Chrome I've tried multiple svg's. This seems to print fine on my new but not latest Firefox and Chrome. Code I use is:
<html><head>
<title>Test tournament bracket</title>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<style>
#media print {
.noPrint {display:none;}
}
</style>
</head>
<body>
<div class="noPrint">
<h1>Forms and non printable content</h1>
</div>
<svg width="70" height="55">
<text x="10"
y="10" font-family="sans-serif"
font-size="12px" fill="black">
Hello
</text>
</svg>
<div style="page-break-after: always;"></div>
<svg width="70" height="55">
<text x="10"
y="10" font-family="sans-serif"
font-size="12px" fill="black">
World
</text>
</svg>
</body></html>
Will give that a shot and see how it turns out.
I just learned that Modernizr uses two different classes for SVG support: no-svg and no-inlinesvg. I can't seem to understand the difference between the two.
According to caniuse.com, Safari 5 and below does not support inline SVG, but does support SVG. I tested this on some D3.js visualizations (them rendering SVG) and Safari 5 displays that correctly.
My first guess was that D3 produces inline SVG, but that does not seem to be the case. So I would love to hear an explanation of the difference between the two.
Inline SVG means using <svg> (and child) tags directly in your html document:
<!DOCTYPE html>
<html>
<body>
<svg width="300px" height="300px" xmlns="http://www.w3.org/2000/svg">
<text x="10" y="50" font-size="30">My SVG</text>
</svg>
</body>
</html>
SVG Support refers to the ability to understand and display SVG files using the <embed> or <object> tags.
Dear Stack Overflow,
I am trying to reference individual SVG graphics which reside in different SVG files
via the tag and ID numbers in a master HTML5 page.
I want to be able to put onclicks on the use tags in the HTML page in order to
make a multiple choice quiz (and then keep a score which I know how to do),
The graphics are going to be bulky. Therefore, these need to be in an external svg files.
Here however, I have used a simple rectangle to make my question easier to
follow
Here is my HTML
<html>
<head></head>
<body>
<svg>
<use xlink:href="LINK.svg#link" />
</svg>
</body>
</html>
and here is My SVG
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg">
<g id="link">
<rect x="0" y="0" width="50" height="50" style="fill:red"/>
</g>
</svg>
This works exactly the way I want it to in Firefox and Opera.
However, it does not work in Chrome or Safari. Not sure about Internet Explorer
Is there an alternative method that will allow me external access to the
SVG data, and scripting from the main HTML page (because I want can keep a score
over multiple SVG elements)
You could access your SVG by using an <object> tag. This link shows you how to script from html to SVG and vice versa.