Code Monkey home page Code Monkey logo

sparkline's Introduction

sparkline

NPM package version License: MIT Minified size Minified+Gzip size

Generate SVG sparklines with JavaScript without any external dependency.

Instalation

This lib is available as a NPM package. To install it, use the following command:

npm install @fnando/sparkline --save

If you're using Yarn (and you should):

yarn add @fnando/sparkline

You'll have to call sparkline.sparkline(svg, values, options) directly if you're loading the script without compiling your script (e.g. webpack). Otherwise you can simply import sparkline from "@fnando/sparkline";.

API

sparkline(svg, values, options = {})

  • svg: This is a <svg> reference that must contain three required attributes (width, height, and stroke-width). These attributes are used to calculate the drawing area.
  • values: You can either provide an array of numbers or an array of objects that respond to .value. If you have a different data structure, see options.fetch.
  • options: This optional argument allows you to further customize the sparkline. The available options are:
    • fetch: Use this function to return the value if you have a different data structure that's not natively supported by sparkline.
    • onmousemove: By setting this callback function, you'll enable the interactive mode (unless you set options.interactive to false). The callback signature is callback(event, datapoint), where datapoint is an object containing the value, x/y coordinates, and the item index.
    • onmouseout: This callback function is called every time the mouse leaves the SVG area. You can use it to hide things like tooltips.
    • spotRadius: Set the spot radius. The default is 2.
    • cursorWidth: Set the cursor width. The default is 2.
    • interactive: When true, this enables the interactive mode. You don't have to set this option if you're providing a onmousemove callback.

Usage

This is the minimum working example:

<!-- width, height and stroke-width attributes must be defined on the target SVG -->
<svg class="sparkline" width="100" height="30" stroke-width="3"></svg>

<script>
  sparkline(document.querySelector(".sparkline"), [1, 5, 2, 4, 8, 3, 7]);
</script>

You can change the colors by either setting the attributes directly to the SVG element or using CSS, like the following:

/* just the line */
.sparkline {
  stroke: red;
  fill: none;
}

/* line with highlight area */
.sparkline {
  stroke: red;
  fill: rgba(255, 0, 0, .3);
}

/* change the spot color */
.sparkline--spot {
  stroke: blue;
  fill: blue;
}

/* change the cursor color */
.sparkline--cursor {
  stroke: orange;
}

/* style fill area and line colors using specific class name */
.sparkline--fill {
  fill: rgba(255, 0, 0, .3);
}

.sparkline--line {
  stroke: red;
}

Examples

Static

Available at https://codepen.io/fnando/full/KyZLLV/

Interactive

Available at https://codepen.io/fnando/full/GOQLVE/

License

(The MIT License)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

sparkline's People

Contributors

aearly avatar arothuis avatar fnando avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sparkline's Issues

<defs> not allowed inside <svg>

Hi ๐Ÿ‘‹,

First of all thank you very much for this awesome library, I like it a lot!

But I got a question: I'd like to fill the backrgound of my sparkline with a gradient, like so:

<svg
  width="300"
  height="60"
  stroke-width="3"
  style="fill: url(#fade)"
>
  <defs>
    <linearGradient id="fade" gradientTransform="rotate(90)">
      <stop offset="0%" stop-color="currentColor" />
      <stop offset="100%" stop-color="transparent" />
    </linearGradient>
  </defs>
</svg>

But this throws the following error, because sparkline tries to remove all children of the element first.

Uncaught (in promise) DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

Do you have any idea how to prevent this error?

Thanks,
Christian

touch event support?

It seem that the option object only support the mouse events but not touch events. Is it better to support touch move / touch end event also?

Suggestion: Consider minimum values when determining a value's "y"

I see the code calculates the maximum value and uses that when calculating the "y" when plotting a point. I suggest that the algorithm should also consider the minimum values as well, to keep negative values from going below the chart.

For example, [ -1, 0, 1] should show an increasing line starting at the bottom left going to the top right. In the current code, however, the line starts on the second point (0) and the first value is hidden.

Any chance you could add typescript support to sparkline?

sparkline works fine in Vue3 but vite is not happy with the lack of .d.ts file.
I have handcrafted a .d.ts file for the sparkline function:

//sparkline.d.ts in the dist folder
export  default function sparkline(svg_html_ref: any, data:any[], options?:any) : void;

Error when data are filled with zeros

In case where the data array are filled with all zeros, Expected Number error will occurred:

Error: <path> attribute d: Expected number, "M4 NaN L 4 NaN L 29โ€ฆ"

Base on looking at the source, the Y coord of each datapoint is determined by the max values of datapoints. If data arrays are all 0, then you will run into a divide by zero scenario resulting in the above error.

  // The maximum value. This is used to calculate the Y coord of
  // each sparkline datapoint.
  const max = Math.max(...values);

Suggestion: support responsive size (mouse events)

By adding this, sparkline interactionLayer can support responsive (% - based) sizes (css expanding the sparkline to fit a div, for instance).

var realWidth;

interactionLayer.addEventListener("mouseover", event => {
    realWidth = svg.clientWidth;
});

interactionLayer.addEventListener("mousemove", event => {
    const mouseX = (event.offsetX * width) / realWidth;
...

Suggestion: configurable class names

Currently, the class names of the spot and the circle are hardcoded. The line and the fill do not have a class name.

In order to give clients easy and full control over styling their graphs, it might be an idea to make all these elements' class names configurable (with sensible defaults, i.e. BEM?).

Hover detection and cursor/spot rendering

In interactive mode, when hovering over the graph, a cursor can be rendered. When hovering over this cursor, the hover seems to unregister, making cursor and spot disappear. A possibly related issue is that cursor and spot don't appear when rendering an interactive and active/dynamic sparkline.

It seems the library currently determines the hover value based on the mouse position, by looking it up in the datapoints.

An alternative solution, which will fix these issues, is to divide the graph in invisible layers (akin to voronoi diagrams) that relate to certain value (i.e. in a data-value attribute) or set of values. This can still be combined with event data to give clients full control over what to do on hover.

Suggestion: Consider option to support a max value size

I am passing in an array of values that range from 0.0 to 1.0 and represent the percentage of memory used in a small monitoring dashboard. It would be nice if we could set an option to set the maximum value (in my case 1.0) so that the values are rendered within that range and appear as a percentage fill rather than only fluctuating based on value

Tooltip information not visible

Hi, The sparklines work fine individually. But am facing few issues with respect to the tooltip for the sparklines.

#1. When I define the tooltip info in options & pass that(options) to create sparklines, the page loads fine, but the moment, I hover over the sparkline, the cursor & dot appear for a second & then the page crashes.

#2. When I comment out the tooltip section within "options", then the page loads fine & the cursor/dot appear & page doesn't crash, however, it removes the other SVG(.line) elements from the page & also the cursor is limited to the right side of the sparkline, as in it doesn't move along the sparklines. Attached scr. shot of this issue.

Screen Shot 2020-03-23 at 16 13 03

Suggestion: don't render null data

Use case: rendering a fixed set of time series data where you may be lacking some future data but need the graph to maintain a consistent width. E.g. here's a graph of today's data viewed at 2pm since future data in each interval isn't available and is null, it gets coerced to 0 on the y-axis:

graph1

That looks kind of ugly and possibly misleading. Here is the desired look of this graph where nulls don't get rendered but interval width is still maintained:

graph2

I accomplished that by simply adding this test on line 113:

if(value !== null){
    pathCoords += ` L ${x} ${y}`;
}

I didn't want to make a PR yet because I haven't had a chance to write any tests nor am I sure this is a use case you even want to support. Just thought I'd throw it out there as a suggestion.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.