Code Monkey home page Code Monkey logo

svg-radar-chart's Introduction

Generate SVG radar charts.

an example

npm version ISC-licensed minimum Node.js version support me via GitHub Sponsors chat with me on Twitter

This library is inspired by radar-chart-d3 but tries to do a few things differently:

  • svg-radar-chart does not limit you in which frontend stack you use. It just returns virtual-dom nodes.
  • Because radar-chart-d3 includes D3, it weighs 212k. svg-radar-chart weighs 9k.
  • Because angular-radial-plot includes includes D3, it weighs roughly 160k. svg-radar-chart weighs 9k.

Note: This library is an opinionated tool; I maintain it with my personal use cases in mind. I do'nt intend to cover every feature a radar chart library might possibly need.

Installing

npm install svg-radar-chart

Usage

import {radar} from 'svg-radar-chart'

const chart = radar({
	// columns
	battery: 'Battery Capacity',
	design: 'Design',
	useful: 'Usefulness',
}, [
	// data
	{class: 'iphone', battery: .7, design:  1, useful: .9},
	{class: 'galaxy', battery:  1, design: .6, useful: .8},
	{class: 'nexus',  battery: .8, design: .7, useful: .6},
])

svg-radar-chart returns virtual-dom, so you can decide what to do with it.

To generate an SVG string from it, use virtual-dom-stringify:

import stringify from 'virtual-dom-stringify'

const svg = `
<svg version="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
	<style>
		.axis {
			stroke-width: .2;
		}
		.scale {
			stroke-width: .2;
		}
		.shape {
			fill-opacity: .3;
		}
		.shape:hover {
			fill-opacity: .6;
		}
	</style>
	${stringify(chart)}
</svg>
`

You may now create an SVG file using Node.js:

process.stdout.write(svg)
node generate-chart.js >chart.svg

Or insert it into the DOM:

document.querySelector('#my-chart').innerHTML = svg

Check the website or the example on how to customize charts further.

Smoothing

You can pass the cardinal-closed smoothing function as follows, but it will add another 18k to your bundle, if you use common-shakeify, otherwise a bit more.

import {smoothing} from 'svg-radar-chart/smoothing.js'

radar(columns, data, {
	smoothing: smoothing(.3), // tension of .3
})

API

radar(columns, data, opt = {})

columns must be an object. The values are captions.

data must be an array of data points. The keys in one data points must exist in columns.

opt is optional and has the following default values:

const defaults = {
	size: 100, // size of the chart (including captions)
	axes: true, // show axes?
	scales: 3, // show scale circles?
	captions: true, // show captions?
	captionsPosition: 1.2, // where on the axes are the captions?
	smoothing: noSmoothing, // shape smoothing function
	axisProps: () => ({className: 'axis'}),
	scaleProps: () => ({className: 'scale', fill: 'none'}),
	shapeProps: () => ({className: 'shape'}),
	captionProps: () => ({
		className: 'caption',
		textAnchor: 'middle', fontSize: 3,
		fontFamily: 'sans-serif',
	}),
}

smoothing(points) must return valid SVG <path> commands.

See also

  • svg-patterns – Create SVG patterns programmatically to visualize data.
  • svg-world-map – Render a world map with a pin at a specific location.

Contributing

If you have a question, found a bug or want to propose a feature, have a look at the issues page.

svg-radar-chart's People

Contributors

derhuerst avatar greenkeeper[bot] 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

Watchers

 avatar  avatar  avatar

svg-radar-chart's Issues

IE compatibility?

Hi there,

Thanks so much for your nice work.

Sorry if my question seems dumb to u, but I was wondering how far would we be from making this code in IE?
I tried IE11, added the <meta http-equiv="X-UA-Compatible" content="IE=edge">, but got no success...

Any plans in this direction?

Thanks in advance for your kind answer

Several (sub)paths for one shape with alternating style

Hi, playing with your module and find it great. Now what I would like to do is to:

  1. Have chart shape composed of different paths (number of them is number of columns) e.g. triangles with coordinates a center, then column value on an axis and the next column value.
  2. Have alternating style (well, at least a color) for odd and even columns.

The idea is to have a way to do this radar chart (only alternating colors are the matter here):
ref-radar-opt

I will ask about the captions in another issue.

UPDATE: the chart (image) above was most likely been created with https://github.com/colorfulgrayscale/angular-radial-plot (Angular based component).

Captions on a path and oriented

This is a desirable feature and relatively simple to achieve but I'm not that versed in node.js yet. The captions would look best if they would be in the angle and rotated so the letters are always upside down. Repeating the same image as in other issue for a demonstration (apologizing for that):

ref-radar-opt

Now this is quite good yet even better would to have the captions on the path. For that invisible circle segments (arcs) would need to be added to a chart and used as xlink:href attributes for captions (so they align with the arc). Best example for a coding help is here:

http://bl.ocks.org/nbremer/b603c3e0f7a74794da87

If this would be added to svg-radar-chart, together with alternate colors and possibly a parameter to have linear or logarithmic scales of column values (and scales to adapt as well) it would make svg-radar-chart fully complete and still small in size and versatile.

Add title and caption

It will be perfect if this project can support the title and the legend , as in the picture below

wc9b1

An in-range update of browserify is breaking the build 🚨

The devDependency browserify was updated from 16.3.0 to 16.4.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

browserify is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • ❌ continuous-integration/travis-ci/push: The Travis CI build could not complete due to an error (Details).

Commits

The new version differs by 5 commits.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

How to add a title / text?

Hi Jannis! I guess this is potentially a feature request or a question if you don't have the time.

SVG scares (horrifies me), but your package works wonders and I'm super happy with it. I'm trying to add a title / text to my charts though and I'm not sure where it might go in the package code... do you think you could point me in the right direction / towards the right resources? Thanks!

cannot use smoothing, fails with syntax error

I used this code to generate similar chart as show bellow but the result was have so visual differences:

const radar = require('svg-radar-chart');
const stringify = require('virtual-dom-stringify');

var fs = require('fs');



    const result = [1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 0, 2, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0, 0, 2, 1, 1, 2, 0, 0, 2, 1, 1, 2, 2, 0, 0];
    var final = sort(result);
    console.log(final);

    const chart = radar({
        // columns
        a: 'a',
        b: 'b',
        c: 'c',
        d: 'd',
        e: 'e',
        f: 'f',
        g: 'g',
        h: 'h'
    }, [
        // data
        {
            class: 'sab1',
            a: final[0] / 10,
            b: final[1] / 10,
            c: final[2] / 10,
            d: final[3] / 10,
            e: final[4] / 10,
            f: final[5] / 10,
            g: final[6] / 10,
            h: final[7] / 10
        }

    ]);
    const svg = `
<svg version="1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
	<style>
		.axis {
			stroke-width: .2;
		}
		.scale {
			stroke-width: .3;
		}
		.shape {
			fill-opacity: .3;
		}
		.shape:hover {
			fill-opacity: .6;
		}
	</style>
	${stringify(chart)}
</svg>
`;
    
    //process.stdout.write(svg);
    var fname = 'test' + '.svg';
    fs.writeFile(fname, svg, function (err) {
        if (err) {
            return console.log(err);
        }
        console.log("The file was saved!");
    });

    function sort(result) {

        var newr = [
            [0],
            [0],
            [0],
            [0],
            [0],
            [0],
            [0],
            [0]
        ];

        var j = 0;
        var p = 0;
        for (var i = 0; i != 7; i++) {
            var ip = 0;
            for (var k = j; k != 7; k++) {
                newr[ip].push(result[p]);
                p++;
                ip++;
            }
            j++;
        }
        for (var i = 0; i != 7; i++) {
            ip = i + 1;
            for (var k = i + 1; k != 8; k++) {
                newr[ip].unshift(result[p]);
                p++;
                ip++;
            }

        }
        return subtotall(newr);
    }

    function subtotall(newr) {
        var total = [0, 0, 0, 0, 0, 0, 0, 0];
        for (var i = 0; i < 8; i++) {
            for (var j = 0; j < 8; j++) {
                if (newr[i][j] == 1) {
                    total[i] = total[i] + 1;
                }
            }
        }
        for (var i = 0; i < 8; i++) {
            for (var j = 0; j < 8; j++) {
                if (newr[j][i] == 2) {
                    total[i] = total[i] + 1;
                }
            }
        }
        return total;
    }

Preferred Chart:

image

Output result:

image

every 2nd column removed

Thank you for the great lightweight script which I'm using successfully on 2 charts. The first has 5 columns & works beautifully. For the 2nd I had to comment out the code below:
columns.reduce((all, column) => { all[column.key] = column return all }, columns)

For some reason it is transforming data with this set of 18 columns:
{1: "Collaboration & Teamwork", 2: "Trustworthiness", 3: "Empathy & Respect", 4: "Relationship-centred Care", 5: "Effective Communication", 6: "Application of Expertise", 7: "Problem-solving", 8: "Managing Workflow", 9: "Continual Learning", 10: "Commitment", 11: "Diligence", 12: "Sustainable Engagement", 13: "Motivation", 14: "Resilience", 15: "Adaptability", 16: "Emotional Competence", 17: "Reflective Self-evaluation", 18: "Self-confidence & Identity"}

into a VirtualNode with every 2nd column replaced with a copy of its predecessor, which then results in an SVG chart with every 2nd column missing. See screenshots below. Weird reduce behaviour, or something I'm doing wrong?

image
image

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.