8 ms·
Easy SVG sparklines
- leeoniya 3y agothis works well when you have a few sparklines with a dozen datapoints each, but less well when you have many sparklines with hundreds of datapoints.
- 082349872349872 3y agoI'd bet an SVG <path> can easily handle hundreds, if not thousands, of datapoints.
- solardev 3y agoThen you have to deal with scaling, responsiveness, data decimation, etc. It's not really a good idea to just have a multi thousand point line chat rendered real tiny
- nkozyra 3y agoIf you know what size you're dealing with it's not a huge deal. You can quantize the data and for (small) sparklines that's probably fine because most people view them as miniature glimpses at data rather than granular and accurate.
- thehappypm 3y ago+1, the whole point of a sparkline is to compactly show a trend. Packing a gazillion data points is not the right use
- solardev 3y agoTotally. I just mean that logic has to live somewhere, whether in client-side JS or a server. It's not a great practice to just blindly render SVGs out of raw data.
- 082349872349872 3y agoAha, I misunderstood — I'd thought you were thinking of rendering multiple small SVGs. Good point, although decimation for sparklines shouldn't be that difficult: I've done completely stupid decimation (recursively split stopping whenever linear fit is close enough) for live GPS traces and (because people are only using them qualitatively) no one ever complained.
- leeoniya 3y agoit can for sure "handle" it. the question is "how well"? a sparkline with 100 datapoints is very realistic. and having a couple columns in a table with 100 rows filled with these svg sparklines will have ui lag that you'll definitely feel. sadly, svg is not a great performer in these 1k+ datapoints cases and you gotta switch to canvas.
- Gordonjcp 3y agoYou're populating a tiny template with a tiny list of numbers to produce a tiny plaintext document that will cache like Scrooge McDuck. Why do you think this is going to be a problem?
- nnf 3y agoSimple, data-driven graphics like this is one area where SVG really shines, I think. No need to load a JavaScript charting library if you just want some simple line charts like this. I create SVG images fairly often, and maybe half the time I find myself hand-coding them, or at least hand-tweaking them, since I enjoy the magic of seeing code turn into something visual.
- kongprofit 3y agodo you have a blog
- unmole 3y agoSVGs are amazing for interactive visualisation too. Like Flamegraphs: https://www.brendangregg.com/flamegraphs.html https://www.brendangregg.com/flamegraphs.html
- antonhag 3y agoAn alternative if you want a bit more help with charting, without client side JS, is to use d3-shape (https://github.com/d3/d3-shape https://github.com/d3/d3-shape) to server-side render SVGs.
- bencevans 3y agoI've recently used this approach for generating Open Graph images for display when a link to the site is used on Twitter, WhatsApp, Facebook, etc [1]. I was pleasantly surprised at how quickly something could be implemented. The last time I'd done something similar was using Cairo and needing to write more of the scaling dynamics. I don't think I ever got it to adjust to dynamic content very well. This time I put together a prototype in Inkscape, converted it to a template and render it to PNG with Sharp [2]. [1]: https://hntrends.net/api/og?word=twitter https://hntrends.net/api/og?word=twitter [2]: https://github.com/lovell/sharp https://github.com/lovell/sharp
- pictur 3y agopretty good. can user interactive charts be prepared in this way?
- nkozyra 3y agoSure, but you'll need JS for anything complex. You could use SVG+CSS to show/hide specific things like data values on mouseover but it would be a global on/off for the whole chart.
- mindok 3y agoYes, but depending on the interactions it can get complex quickly. D3.js handles all the interactions in JS on the client. ContEx (elixir server-side charting) handles certain events (e.g. data point click) server side (see https://contex-charts.org/barcharts https://contex-charts.org/barcharts - turn on “show clicked bar” option). Showing data point detail, e.g. “On hover” would require client side code. (Disc: ContEx author)
- Lockal 3y agoBut SVG is slower than Canvas. The main use case for sparklines is embedding them into cells, many hundreds or even thousands of them [1]. With hundreds of SVG files page becomes becomes visibly slower (first paint, scroll, interactions). I suggest to invest some time and check canvas solution too. [1]: https://www.google.com/search?q=sparkline&tbm=isch https://www.google.com/search?q=sparkline&tbm=isch
- thehappypm 3y agoHard to imagine that pure-HTML SVG is really slower than Canvas which relies on JS..
- TeMPOraL 3y agoEspecially if we're talking using "many hundreds or even thousands of them" on a page.
- Lockal 3y agoIt is, it is! SVG is DOM, with event handling on every node, with attempts to apply CSS rules. Canvas for non-interactive charts is just "draw once and forget". It is a sequence of moveTo + lineTo, then you have a bitmap and nothing else. Extremely basic graphics, modern JS engines will handle it in the blink of an eye. I don't even mention the fact that article suggests to return each SVG sparkline in a separate request.
- thehappypm 3y agoGuess it depends on your definition of performance.
- klysm 3y agoCanvas is faster _because_ it relies on JS. It’s a much dumber and stateful API - the browser has to do much less work.
- fuzzy2 3y agoAh, but Canvas does not rely on JS. You would update it using JS, yes. When you don’t update it, it’s just another image. Browsers are quite good at images. In the end, I think it’s down to the complexity of the graph and the dimensions (in pixels, because images need memory, too).
- yawnxyz 3y agoThis is cool! For those who don't know, there's a font called Sparks that uses glyphs to create sparklines: https://github.com/aftertheflood/sparks https://github.com/aftertheflood/sparks
- ukuina 3y agoWhy are the compressed fonts _5MB_!?
- pmarreck 3y agoall their examples and URLs (save for the code itself on github) but even the font files themselves are dead because that company closed in 2020 :/ Very neat idea, though! I did find this example: https://observablehq.com/@tomgp/sparks-with-live-data https://observablehq.com/@tomgp/sparks-with-live-data For those examples to work (which they still do), the URL references to the font data in the stylesheet should ostensibly still be valid: https://tools.aftertheflood.com/sparks/styles/font-faces.css https://tools.aftertheflood.com/sparks/styles/font-faces.css
- watersb 3y agoApparently, the host 'tools.aftertheflood.com' is still mapped to GitHub Pages. Backing out from the CSS file (many thanks!), turns out the top-level web page is still up -- BUT the links to download the zip file font collections DONT WORK. So you still need to scrape the CSS file to get working links to the individual fonts... (I was going to post those URLs here, but there are 84 of them. Use a command like this to scrape the CSS file: grep -o "http[^']*" < sparks.css However, this GitHub Pages site still hosts web pages that show some great examples and links to ObservableHQ notebooks (which also still work, hosted at observablehq.com). https://tools.aftertheflood.com/ https://tools.aftertheflood.com/
- yawnxyz 3y agooh that's a bummer, didn't know that killed the examples and links to the font files :( I just created a new issue and uploaded a zip file of their fonts to their Github: https://github.com/aftertheflood/sparks/files/12009401/AtF.Spark.zip https://github.com/aftertheflood/sparks/files/12009401/AtF.S... (Finally a justification for my font hoarding)
- drewcoo 3y agoThe "unfinished" tiny line graph with no fill is actually closer to what Tufte meant by sparklines. He meant those to be placed in text, word-sized, along with words to help communicate better. https://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=000AIr https://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=... I feel like many people use "sparkline" to mean "pretty graph." Those, frankly, lack the punch of a sparkline.
- umtksa 3y agolove it and tried it on node-red to add a simmple sparkline to my dashboard
- spoiler 3y agoI've used a similar technique to implement one of the graphs for small "header dashboard" for a trading tool at my previous job. It was replacing an old decrepit tool and I wanted to add some pizzaz to the tool, and had an obsession with SVG and micro interactions at the time, so I've basically implemented most of the little graphics using hand-emitted SVG that was manipulatied through React. The updates happened in one batch too, so the performance was always great
- umtksa 3y agothis looks like a subject I like to read on a blog
- deleted 3y ago[deleted]
- CamperBob2 3y agoI've always thought it would be neat to use sparklines to display trends in comment scores. You could see if a comment was monotonically being voted up or down or if it's considered controversial, and if so, to what extent. It would help distinguish between bandwagon/brigading activity and genuine organic rejection or appeal. And it's often interesting to see trends or cycles emerge as people in different geographical regions wake up and log on. Some comments play much better in the US than in Asia or the EU and vice versa, and sparklines would be a good way to observe that.
- dreadlordbone 3y agoJavascript version here: https://jsfiddle.net/buk3dsqv/ https://jsfiddle.net/buk3dsqv/
- entropie 3y agoIt would be nice if you consider to put it in a jsfiddle, or something.
- dreadlordbone 3y agoGood point, updated that to a jsfiddle.
- stevekrouse 3y agoI ported your jsfiddle to run on val town! Main function: https://www.val.town/v/stevekrouse.sparklineSVG https://www.val.town/v/stevekrouse.sparklineSVG Rendered example: https://www.val.town/v/stevekrouse.sparklineEx2 https://www.val.town/v/stevekrouse.sparklineEx2
- deleted 3y ago[deleted]
- entropie 3y agoThank you ♥
- javajosh 3y agoI like it! But instead of modifying your data to suit SVG's default coordinate system, I suggest using a top-level "g" tag with a "transform/scale" attribute. Like this: <svg class="natural-units" width="200px" height="200px" viewBox="-1 -1 2 2" > <desc>A static svg unit circle</desc> <g transform="scale(1,-1)"> <circle class='unit-circle' r="1" fill="none" stroke-width=".001 "/> </g> </svg> Example adapted from: https://simpatico.io/svg.md#naturalunits https://simpatico.io/svg.md#naturalunits In this way you can use the intuition about the coordinate system that you built in school.
- bla3 3y agoDoesn't this flip all text in the SVG upside down?
- javajosh 3y agoAlas, yes. And you have to reflip it with another g/scale. But such is life!
- ComputerGuru 3y agoA bigger problem is that it breaks text rendering. Transforms turn off pixel snapping in the hinting engine so you’ll get blurry text or lines. (At least if you applied it as a css transform you would. Maybe if you did it natively in svg you wouldn’t?)
- chefandy 3y agoMaybe it's just because I have so much experience with design and visual art, but I think SVG is one of the most, if not the most underutilized web format. It's great for the self-contained static vector graphics that it's most commonly used for, but it can do so much more. SMIL animations can be a little clunky, but having an alternative to gif and video that doesn't require JS is pretty rad-- especially for throbbers and things like that. That you can work with SVGs so easily using JS and CSS is awesome. You can even build your own filter stacks using its built-in effects... though last time I did that with a detailed full-screen art piece, performance was rough.
- javajosh 3y ago>SVG is one of the most, if not the most underutilized web format Yes. I think the problem is that you have to learn to author with it before you program with it, and the learning curve is actually fairly steep. OTOH the feedback is immediate and satisfying. Personally, I've ignored SVG's built-in animation capabilities in favor of pumping DOM modifications into the scenegraph with a (requestAnimationFrame) timer. This gives you exquisite control requiring very little code. https://simpatico.io/svg.md#clocksvg https://simpatico.io/svg.md#clocksvg
- gabereiser 3y ago+1 for requestAnimationFrame. SMIL animations are cool until you try doing 1,000 of them. Still, I do agree that SVG is underutilized. Not only can it do so much more but it has effects that can be used in conjunction with DOM elements. Things like dropshadow, glow, blur, greyscale, duotone, etc. Check out this SVG glitch effect [0] [0] https://codepen.io/DirkWeber/pen/YzBYWY https://codepen.io/DirkWeber/pen/YzBYWY
- chefandy 3y agoYeah it's great with JS, and I use it for most dynamic things I do with SVG. I'd still stick with SMIL for little animated icons that would be deployed multiple places and other little problems like that. > Yes. I think the problem is that you have to learn to author with it before you program with it, and the learning curve is actually fairly steep. Good point.
- mindok 3y agoCool explanation! I use quite a lot of SVG visualisations generated server-side. Some basic charts (including sparkline) are bundled up into ContEx (an elixir library) - see https://contex-charts.org/ https://contex-charts.org/ (disclosure - author).
- alexpls 3y agoThanks! And thanks also for your work on ContEx, its Sparkline module [1] was a big inspiration for what I ended up implementing. [1] https://github.com/mindok/contex/blob/master/lib/chart/sparkline.ex https://github.com/mindok/contex/blob/master/lib/chart/spark...
- bob1029 3y agoThis is fantastic. I'm already using string interpolation & builders for my HTML/JS/CSS source, so why not the same for SVG? I didn't realize the syntax was so straightforward. It looks like you could even build the final SVG with some clever SQL queries if all you need to do is produce a time series visual (i.e. string aggregation over Path).
- jjcm 3y agoI ended up hand crafting my svg graphs for non.io for many of the same reasons. I originally was looking around at 3rd party libraries, but one of my goals with the site was to use as few external libraries as possible. I made an attempt at dynamically generating the svg points myself, and found it incredibly easy. For context, here's the 22 lines of code it took to create a simple svg graph: https://github.com/jjcm/soci-frontend/blob/master/components/soci-ledger.js#L228 https://github.com/jjcm/soci-frontend/blob/master/components... And here's the final output: https://non.io/Animation-example https://non.io/Animation-example
- renewiltord 3y agoCool idea! ChatGPT-4 was able to generate something for me pretty quick https://chat.openai.com/share/d0e8102c-9ea5-4709-8898-b278caa14ee0 https://chat.openai.com/share/d0e8102c-9ea5-4709-8898-b278ca... that looks pretty similar https://jsfiddle.net/13awmx8y/ https://jsfiddle.net/13awmx8y/
- stevekrouse 3y agoI thought it'd be fun to play with sparklines on Val Town, which is a server-side platform for running JavaScript. First I did the opposite of this post and used all the libraries (react, htm, and react-sparkline): https://www.val.town/v/stevekrouse.sparklineEx https://www.val.town/v/stevekrouse.sparklineEx Then I found a comment below that does it in vanilla js, so I ported that over to Val Town as well: https://www.val.town/v/stevekrouse.sparklineEx2 https://www.val.town/v/stevekrouse.sparklineEx2
- jwr 3y agoI'm going to be the Smug Lisp Weenie here (I wonder who gets the reference), and comment on this: > One of my favourite things about creating sparklines like this is that I can create the SVGs entirely on the backend. I don’t need to worry about using a JavaScript charting library, or sending the “points” data to the frontend. The browser requests an SVG. The server returns it. Simple! Me, I don't care where I create the SVGs. Most of my Clojure code is shared between backend and frontend (compiled and running on the JVM in the backend and compiled to JavaScript in the frontend). So I can generate SVGs wherever, it doesn't matter, the code is only written once. Or rather, it might matter, because my website uses server-side rendering, so the same thing must be generated on both sides. I'll see myself out now.
- lucideer 3y agoI mean... isomorphic code isn't unique to Clojure & is how many JS/NodeJS apps work...
- mighmi 3y agoWhat's Clojure's WASM story like? That would be much more exciting than having to transpile to JS.
- jwr 3y agoWhy would it be more exciting? I've been running a massive SaaS app for the last several years. JavaScript is not a performance problem, especially after compiling using the Google Closure compiler "advanced" mode. Rendering is a performance problem: think large tables. WASM would bring me no significant advantages.
- nologic01 3y agoSVG feels like the neglected stepchild of the web universe for reasons that are not entirely clear. While its obviously not the solution to any and all visualizations in the browser its a remarkable addition to html and the dom. It should not really be considered a foreign format but the natural native one. SVG can go a long way on its own or together with server side templates (as this post nicely demonstrates) but imho its pairing with js libraries such as d3 or vega is (still) out of this world in terms of the user experience they create.
- andersrs 3y agoAh! So all that complicated looking syntax is just a turtle with a pen.
- ukuina 3y agoThis references Logo, a programming language where you control a turtle to draw shapes. https://en.wikipedia.org/wiki/Logo_%28programming_language%29 https://en.wikipedia.org/wiki/Logo_%28programming_language%2...