Coder Social home page Coder Social logo

ora's Introduction

ora

Elegant terminal spinner



Install

npm install ora

Usage

import ora from 'ora';

const spinner = ora('Loading unicorns').start();

setTimeout(() => {
	spinner.color = 'yellow';
	spinner.text = 'Loading rainbows';
}, 1000);

API

ora(text)

ora(options)

If a string is provided, it is treated as a shortcut for options.text.

options

Type: object

text

Type: string

Text to display after the spinner.

prefixText

Type: string | () => string

Text or a function that returns text to display before the spinner. No prefix text will be displayed if set to an empty string.

suffixText

Type: string | () => string

Text or a function that returns text to display after the spinner text. No suffix text will be displayed if set to an empty string.

spinner

Type: string | object
Default: 'dots'

Name of one of the provided spinners. See example.js in this repo if you want to test out different spinners. On Windows, it will always use the line spinner as the Windows command-line doesn't have proper Unicode support.

Or an object like:

{
	interval: 80, // Optional
	frames: ['-', '+', '-']
}
color

Type: string
Default: 'cyan'
Values: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'gray'

The color of the spinner.

hideCursor

Type: boolean
Default: true

Set to false to stop Ora from hiding the cursor.

indent

Type: number
Default: 0

Indent the spinner with the given number of spaces.

interval

Type: number
Default: Provided by the spinner or 100

Interval between each frame.

Spinners provide their own recommended interval, so you don't really need to specify this.

stream

Type: stream.Writable
Default: process.stderr

Stream to write the output.

You could for example set this to process.stdout instead.

isEnabled

Type: boolean

Force enable/disable the spinner. If not specified, the spinner will be enabled if the stream is being run inside a TTY context (not spawned or piped) and/or not in a CI environment.

Note that {isEnabled: false} doesn't mean it won't output anything. It just means it won't output the spinner, colors, and other ansi escape codes. It will still log text.

isSilent

Type: boolean
Default: false

Disable the spinner and all log text. All output is suppressed and isEnabled will be considered false.

discardStdin

Type: boolean
Default: true

Discard stdin input (except Ctrl+C) while running if it's TTY. This prevents the spinner from twitching on input, outputting broken lines on Enter key presses, and prevents buffering of input while the spinner is running.

This has no effect on Windows as there is no good way to implement discarding stdin properly there.

Instance

.text get/set

Change the text after the spinner.

.prefixText get/set

Change the text before the spinner.

No prefix text will be displayed if set to an empty string.

.suffixText get/set

Change the text after the spinner text.

No suffix text will be displayed if set to an empty string.

.color get/set

Change the spinner color.

.spinner get/set

Change the spinner.

.indent get/set

Change the spinner indent.

.isSpinning get

A boolean of whether the instance is currently spinning.

.interval get

The interval between each frame.

The interval is decided by the chosen spinner.

.start(text?)

Start the spinner. Returns the instance. Set the current text if text is provided.

.stop()

Stop and clear the spinner. Returns the instance.

.succeed(text?)

Stop the spinner, change it to a green and persist the current text, or text if provided. Returns the instance. See the GIF below.

.fail(text?)

Stop the spinner, change it to a red and persist the current text, or text if provided. Returns the instance. See the GIF below.

.warn(text?)

Stop the spinner, change it to a yellow and persist the current text, or text if provided. Returns the instance.

.info(text?)

Stop the spinner, change it to a blue and persist the current text, or text if provided. Returns the instance.

.stopAndPersist(options?)

Stop the spinner and change the symbol or text. Returns the instance. See the GIF below.

options

Type: object

symbol

Type: string
Default: ' '

Symbol to replace the spinner with.

text

Type: string
Default: Current 'text'

Text to be persisted after the symbol.

prefixText

Type: string
Default: Current prefixText

Text to be persisted before the symbol. No prefix text will be displayed if set to an empty string.

suffixText

Type: string
Default: Current suffixText

Text to be persisted after the text after the symbol. No suffix text will be displayed if set to an empty string.

.clear()

Clear the spinner. Returns the instance.

.render()

Manually render a new frame. Returns the instance.

.frame()

Get a new frame.

oraPromise(action, text)

oraPromise(action, options)

Starts a spinner for a promise or promise-returning function. The spinner is stopped with .succeed() if the promise fulfills or with .fail() if it rejects. Returns the promise.

import {oraPromise} from 'ora';

await oraPromise(somePromise);

action

Type: Promise | ((spinner: ora.Ora) => Promise)

options

Type: object

All of the options plus the following:

successText

Type: string | ((result: T) => string) | undefined

The new text of the spinner when the promise is resolved.

Keeps the existing text if undefined.

failText

Type: string | ((error: Error) => string) | undefined

The new text of the spinner when the promise is rejected.

Keeps the existing text if undefined.

spinners

Type: Record<string, Spinner>

All provided spinners.

FAQ

How do I change the color of the text?

Use Chalk:

import ora from 'ora';
import chalk from 'chalk';

const spinner = ora(`Loading ${chalk.red('unicorns')}`).start();

Why does the spinner freeze?

JavaScript is single-threaded, so synchronous operations blocks the thread, including the spinner animation. Prefer asynchronous operations whenever possible.

Related

ora's People

Contributors

1999 avatar aminya avatar andygrunwald avatar bendingbender avatar brandon93s avatar clavin avatar coreyfarrell avatar ellingtonc avatar erezrokah avatar fgribreau avatar fonger avatar forresst avatar fregante avatar g-rath avatar guybedford avatar harrypeach avatar hoducha avatar insin avatar jbcarpanelli avatar jeetiss avatar joeycozza avatar josmardias avatar parro-it avatar samverschueren avatar scrabouillmax avatar sindresorhus avatar srbrahma avatar stroncium avatar tommy-mitchell avatar xavdid 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  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

ora's Issues

no output when redirect or piped

Hi,
when doing mycli sub show > stdout.txt, ora.succeed() content is not displayed nor it is written to stdout.txt file. Same if doing mycli sub show | grep ....While console.log works as exepected.

Here is a gist showing the problem: https://gist.github.com/sulliwane/a2817f02e1bd8f0686098ef04f1c3625

I tried using these options, without success:

{
  stream: process.stdout,
  enabled: true,
}

note: if using my dockerized CLI, ora output is correctly displayed.

fails to clear when the line length is too long

fails to clear current line when the line length is too long, to be exactly, more than process.stdout.columns. for example, when I set spinner.text = 'abracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebraabracadebra', spinner refuses to clear but moves to the next line, leaving last line dead ...

dingtalk20180312165630

updated on 12 Mar, 19:01: by viewing the source code, now I know the solution is to break input into lines according to terminal.columns ......

Feature: Progress

Hey cool project!

I was using ora and wanted to see the progress of some asynchronous calls but couldn't see a way to adjust the terminal output.

I thought it would be cool if ora could accept a progress callback - that will be part of the render.

An example usage would be something like:

'use strict';
const Ora = require('.');

let progress = 0;

const timeoutPromise = timeout =>
  new Promise(resolve => {
    setTimeout(() => {
      resolve();
    }, timeout);
  }).then(() => {
    progress++;
  });

const promises = [
  timeoutPromise(1000),
  timeoutPromise(2000),
  timeoutPromise(3000),
  timeoutPromise(300),
  timeoutPromise(4000)
];

const progressCb = () => {
  const percent = Math.round(progress / promises.length * 100);
  return `${percent}/100%`;
};

const spinner = new Ora({
  progress: progressCb,
  text: 'Loading unicorns',
  spinner: process.argv[2]
});

spinner.start();

Promise.all(promises).then(() => spinner.succeed());

progress-demo

spinner.stop() let non parseable characters

Hi,
I'm using ora spinner in a cli application. This application generates a json as output, when I redirect this output to a file, several characters are placed inside the file beyond my json. See the attached image:
output_json

This behavior makes the output not parseable.
Any advice in how to handle this problem completely cleaning the console after calling spinner.stop()?
Thanks!

if the text is wider than the term every frame is printed on a new line

Problem

If the text is too long, every frame is printed on a new line, eventually filling up the screen.

Example

const ora = require('ora');
const spinner = ora('too long! '.repeat(process.stdout.columns));
spinner.start();
// be prepared to hit control-c a bunch of times

screen shot 2016-03-30 at 8 47 58 pm

### Real-world example - https://github.com/dylang/npm-check/issues/98 ### Possible workaround - Limit text to `process.stdout.columns - 2` (spinner and the space next to the spinner)

Multiple simultaneous spinners

Hi,

I have a script that tests our REST API running multiple concurrent request. Is it possible to list request line by line with a dedicated spinner at the front of each? In my quick tests, it seems that there can only be one spinner at a time. It seem that creating a second one only updated the text of the first one and so forth.

Thanks

2.1 -> 3.0 upgrade surprise: stream: process.stderr change

What is the reasoning behind changing the default stream from stdout to stderr?

It took me quite sometime to figure out what broke in my tests. I understand it is a major version change but would be nice if it was in the CHANGELOG/README.

Wouldnt it be better to keep stdout as default as more people are having the same issue? #61

Add ability to pass in a Promise

Many uses of ora are waiting on a Promise to finish. Would be nice if you somehow could just pass in a Promise have have it handled by ora. This would be especially nice when #8 is implemented, as it would show a success or failure icon depending on the Promise resolve status.

What should the API look like? It could be a sub-method ora.promise(action) or an option ora({promise: action}).

Thoughts? (Anyone)

Release notes for 2.0.0

Since the 2.0.0 release is a bump in the major version from the previous version, can you provide some release notes for it? Especially what's breaking and how an user can migrate from 1.4.0 to 2.0.0.

Thanks.

Running node in docker - TypeError: this.stream.clearLine is not a function

Hi,

I'm running my cli command in docker and the ora fails to start. It seems that there is no function in process.stderr.

Possible fix is to check the function and return the text per line? (my thought, docker is just streaming the output?).

Thank you for any hints/advices. I can make PR that will check the function.

Martin,

Docker file
FROM node:8
#... instal etc
# Use the workdir
WORKDIR /usr/src/my-cli

# Install app dependencies
COPY package.json .
COPY package-lock.json .
COPY cli.js .

RUN npm install

RUN npm link
Crash
TypeError: this.stream.clearLine is not a function
  at Ora.clear (/usr/src/my-cli/node_modules/ora/index.js:53:15)
  at Ora.render (/usr/src/my-cli/node_modules/ora/index.js:59:8)
  at Ora.start (/usr/src/my-cli/node_modules/ora/index.js:74:8)
  at Object.<anonymous> (/usr/src/my-cli/cli.js:42:4)
  at Module._compile (module.js:624:30)
  at Object.Module._extensions..js (module.js:635:10)
  at Module.load (module.js:545:32)
  at tryModuleLoad (module.js:508:12)
  at Function.Module._load (module.js:500:3)
  at Function.Module.runMain (module.js:665:10)

The final state doesn't comme out in stdout

If you use ora in a subprocess, you can't see the animation (which is perfectly normal, but this is not what this issue is about), but when you take the stdout of the command, the final state (when you do a spinner.stop()) doesn't show in it.

I can't tell you how you can fix it, but I have an idea: when you stop the spinner, you make it disappear, and you console.log() the latest frame. I don't know if it will work).

Improve Windows support

I like ora, but I dislike that it defaults to the simple line spinner if process.platform == 'win32' since most alternative Windows terminals do support the other more elegant spinners, too.

I have started working on windows terminal detection and have quickly tested which terminals support the default dots spinner (cmder, conemu and mingw support it; cmd, powershell and cygwin don't).

I know my findings are just exploratory yet and I know it's a niche, but is this something that you would consider to implement in ora? If so, well, I'd like to help out and continue my work. :)

Request: spinner.info([text])

Right now there's spinner.succeed([text]) and spinner.fail([text]) where the idea is that it's either a success or a failure e.g. due to an error. I'd like a spinner.info([text]), which ends as something like a yellow !.

I want this because it isn't always the case that a function just succeeds or fail, sometimes you can have e.g. a harmless error that when reached you should be made aware of that it's reached but it hasn't succeeded or failed.

So spinner.fail would be for "bad" errors, spinner.info would be for "harmless" errors, and spinner.succeed would be for entirely successful runs.

Thoughts?

Indent spinners

I am wondering how I could indent the spinners so that they are not flush with the left side of the terminal? Seems simple enough but it goes over my head.

Get spinner.isSpinning

It would be great to get a bool to see if an instance of the spinner is currently spinning.

I read through the code (surprisingly small lib for how much it does!) and it seems like we can functionally read spinner.id, which will be null if that instance is not spinning and truthy otherwise.

I'm happy to write some logic around this, but since it's not explicitly documented, I wanted to double check that this is a good way to do it and the functionality won't disappear.

thanks!

should enabled:false also stop spinner.succeed's output?

Hi, thank you for the awesome spinner!

I'm setting enabled:false for a specific environment, and I was expecting it also removes any output by spinner.succeed.
Seems like it's not the case.

Is it expected behavior or a bug?

ES2015ify

I think it would be nice if we ES2015ified ora. We could use classes and clean up the code. Supporting node 0.10 and 0.12 for CLI stuff isn't necessary anymore in my opinion.

optionally report time taken when spinner ends

Living on the CLI with complex task sequences of varying lengths, it would be really useful
to have ora optionally print time on the finish calls.

✔ Create slot SomeText (34s)

Happy to submit a pull request, but wanted to check if there is an appetite for this ?

Preserve lines

It would be nice to keep a log of finished "texts". Can you please add such option?

So, expected result is, that whenever I change the text previous one is preserved on previous line, shifting output further down. Indicator, obviously, should not be preserved :)

cannot change sinnper text in ora.promise

const ora = require('ora');
var data = 'start loading...'
ora.promise(
    new Promise(function(resolve, reject){
        setTimeout(()=>{
            console.log(data, 111)
            data = 'response not found'
            console.log(data, 222)
            reject(data);
        },3000)
    }),
    data
);


| start loading...start loading... 111
response not found 222
× start loading...

syntax error near unexpected token

Here the error:
schermata 2016-12-18 alle 22 34 14

and here my index.js

'use strict';
const ora = require('ora');
const chalk = require('chalk');
const colors = require('colors');

const mese = require('./month');
const festa = require('./festivity');

// Declaring
var d, day, month, year;

// Asssigning
d = new Date();
today = d.getDate();
year = d.getFullYear();

var status = false;

var spinner = new ora({
  text: 'Getting festivities...',
  spinner: 'dots',
  color: 'yellow'
});

spinner.start();

if ( mese() == festa('epifany').month && today == festa('epifany').day) {
  setTimeout(function () {
    spinner.text = "📯 It's epifany! 📯";
    spinner.succeed();
    status = true;
  }, 500);
} else {
  spinner.text = "Oh no... It's a common day...";
  spinner.fail()
}

Thanks in advance.

Add `indent` option

Issuehunt badges

It would be nice to be able to control what is set to cursorTo in order to support indentation of rows, if desired.

yaodingyd earned $40.00 by resolving this issue!

on .start, don't start again if already running

Unexpected issue

arrayOfStuff.map( item => {
  spinner.start();
  spinner.text = `do stuff to ${item.name}`;
  // do stuff that might take a while
})

In an instance like this where you want to make sure the spinner has started, the spinner does not realize it has already started and will start again and again.

Expected result

If spinner.start() is called multiple times without a stop, the extra start calls are just ignored.

Ora accepting updates from modules?

Hi, (not sure if this is the right place)

I'm using ora, I have it declared like the example in my main node file. I run some things in outside modules. is it possible to update the ora text from within these modules? Perhaps via module.exports?

what would be the best way of doing this?

flickers in st

Flickers really bad in st (every update). Looks great in urxvt.

Can you maybe use [CSI]G (go to beginning of line) rather than updating entire line? Maybe there is no fix. Still a bug.

Idea: Global prefix & suffix

I think this could be a simple, easy and powerfull solution to #44

People could implement their own elapsed time feature or in my case I want to show the current memory usage on every line.

ex:

import util from 'util';
import colors from 'colors';
import filesize from 'filesize';

const spinner = ora({
  text: 'Importing from the database.',
  suffix(){
    return colors.grey(` (Mem used: ${filesize(util.inspect(process.memoryUsage().rss))})`);
  },
  prefix: '­=> '
}).start();

would print:
⠹ => Importing from the database. (Mem used: 98.2mb)

Barelly add any complexity and it would be pretty versatile.

Recurive Loop

Hi, I interestingly managed to create some sort of infinite loop in ora: 1.1.0:

const ora = require('ora');
const spinner = ora("bash:git fetch --all && git reset --hard origin/develop && git pull origin develop").start();

If you omit the "develop" at the end of the string, the problem stops

bug

Issues on Windows!

I just started using this awesome package. Thanks for that.

But it seems that it has some issues on windows. Using it in the #0CJS create-guten-block package.

Here's the issue ahmadawais/create-guten-block#6

TypeError: this.stream.clearLine is not a function

Kindly, take a look.

Which is why on Windows I have to do this

const isWindows = require( 'is-windows' );
const ora = isWindows() ? false : require( 'ora' );

// Init the spinner.
	const spinner = ora ? new ora( { text: '', enabled: true } ) : false;

if ( spinner ) {
		spinner.start(
			`1. Creating the plugin directory called → ${ chalk.black.bgWhite(
				` ${ blockName } `
			) }`
		);
	} else {
		console.log(
			chalk.green( ' 1. Creating the plugin directory called → ' ) +
				chalk.black.bgWhite( ` ${ blockName } ` )
		);
	}

await createPluginDir( blockName );

	if ( spinner ) {
		spinner.succeed();
	}

Which as you can see is less than ideal.

Issues when used with 'through'

Hi, awesome spinner 👍, definitely adds alot of spice to those boring cli tools

I'm using through in my module and it seems to breaking when I introduce ora into the mix.

The following code should write 123 to number.log, but it doesn't.

const ora = require('ora');
const fs = require('fs')
const through = require('through')

const rs = through();

rs.push('123');
rs.push(null);

const ws = fs.createWriteStream('number.log', { flags: "a" });

rs.pipe(ws)

const spinner = ora("spin").start();

However, it works if I use a regular PassThrough stream

var PassThrough = require('stream').PassThrough;

var rs = new PassThrough;
rs.push('123');
rs.push(null);

const ws = fs.createWriteStream('number.log', { flags: "a" });

rs.pipe(ws);
const spinner = ora("spin").start();

Any clue why the incompatibility with through?

breaks other `process.on('SIGINT', ...)` handlers

When using ora, other exit related signal handlers fail to run:

// remove the next line, and "cleanup" prints.
require('ora')('Loading unicorns').start().stop();

process.on('SIGINT', function() {
  // never called if ora was ever enabled
  console.log('cleanup');
});

process.kill(process.pid, 'SIGINT');

This is due to: exit-hook used by restore-cursor not being friendly with other on-exit related strategies.

After v1.2.0 bats tests break

I'm using bats to test my cli app moro.

Bats runs end to end tests just like a shell script.

I know in CI and when there's no TTY, ora gets disabled. But I can't figure out why it was working in v1.2.0?

Let me try to create a test case

// utils/spinner.js
const ora = require('ora')
const mainSpinner = ora({
  text: '',
  spinner: 'flip',
  color: 'red'
})

module.exports = mainSpinner

Then somewhere else

const spinner = require('./utils/spinner.js')

spinner.start()
// ... do some stuff

spinner.succeed(`You clocked in successfully`).start()

In version [email protected] this command works by this bats test file:

@test "it says You clocked in" {
  run faketime '2020-01-01 08:00:00' moro
  assert_success
  assert_output_contains 'You clocked in'
}

But in [email protected] it just prints nothing, as spinner.enabled is undefined.

Any ideas would be appreciated :)

Multiple instances simultaneously?

I cannot find anything in the code/documentation about being able to use multiple ora instances at the same time. This would be very handy when displaying statuses of multiple async operations. For instance, yarn does something similar with the spinning slashes when adding or updating dependencies.

Chainable API

How about starting to return this from the instance functions so that you can chain it. It would make it easier to create a new spinner and start in the same call.

e.g.

const ora = require('ora')
const spinner = ora('Loading unicorns').start()

setTimeout(() => {
  spinner.color = 'yellow'
  spinner.text = 'Loading rainbows'
}, 1000)

setTimeout(() => {
  spinner.stop()
}, 2000)

only enable when this.stream.clearLine is available

Issue

When spawning a command that uses ora, stream.clearLine isn't available. This causes ora to throw an exception when it runs this.stream.clearLine();.

I'm guessing there are other times clearLine may not be available.

Possible solution

The enable check could include checking that this.stream.clearLine is a function, or maybe this.stream.isTTY is true.

We can't choose spinners on Windows besides the Line Spinner

The following line 22 on the Ora constructor always forces the Line spinner on Windows, even if we choose another spinner:

this.spinner = typeof sp === 'object' ? sp : (process.platform === 'win32' ? cliSpinners.line : (cliSpinners[sp] || cliSpinners.dots)); // eslint-disable-line no-nested-ternary

I accept it the reasoning to force a different default value for windows instead of dots as usually normal unconfigured CMD or PowerShell are not configured to handle most special characters.

Simply blocking the option to select another spinner is a bit excessive in my opinion, and blocks functionality.

As an example here's VSCode Integrated Terminal with Powershell running the Dots spinner (modified the local Ora code directly):

ora_dots_spinner

On the other hand if we changed the code above to something like:

this.spinner = typeof sp === 'object' ? sp : (cliSpinners[sp] || (process.platform === 'win32' ? cliSpinners.line : cliSpinners.dots)); // eslint-disable-line no-nested-ternary

Then by default Windows gets the line spinner, everybody else gets dots, but we can still choose another spinner in the options if desired.

How can i use this in conjunction with `log-update`?

I have implemented log-update and I love it! Now I want to make it even prettier by adding the spinning dots.

How would I go about using both?

fs.readdirSync('./database/seeds', (err, files) => {
  files.forEach((filename) => {
      .then(result => {
        logUpdate(`${filename}`);
      })
})

Add new methods .succeed() and .fail()?

Hey,
first of all, great module! Love it.

I thought that since this module is meant to display progress in something, wouldn't it make sense to also display whether that succeeds or fails?

What I'm imagining is 1) a method .suceed() that turns the spinner into a green tick, and 2) a method .fail() that turns the spinner into a red cross (and possibly the text, too?).

What does everyone think about this?

Npm deprecations warning when installing

Npm version: 3.10.10
Node version: 6.9.4

image

That's what I get when I npm install [email protected].

I'm not really sure if that's a problem with this package, I tried to google it but to no avail. I checked my package.json, there is no JSON error plus the file is format using prettier so there would be no format error.

Thanks for that great package. 👍

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.