GithubHelp home page GithubHelp logo

facebookarchive / flow-remove-types Goto Github PK

View Code? Open in Web Editor NEW
468.0 9.0 52.0 107 KB

๐Ÿšฟ Removes Flow type annotations from JavaScript files with speed and simplicity.

License: MIT License

JavaScript 90.71% Shell 9.29%

flow-remove-types's People

Contributors

andreypopp avatar dennisss avatar hzoo avatar leebyron avatar lrowe avatar motiz88 avatar phillipj avatar pravi avatar wain-pc avatar yungsters 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

flow-remove-types's Issues

Alternative mode that removes whitespace

In some cases I do want to remove the whitespace for better looking output (in particular, unlike babel, buble preserves the whitespaces after transpiling), which is currently not possible.

I've managed to create a fork that does so with sourcemap support using https://github.com/rich-harris/magic-string - wondering if we can add an option to enable this:

var { code, map } = flowRemoveTypes(input, {
  whitespace: false
});

If this looks like a good idea, I'll open a PR. rollup-plugin-flow will also need to be updated to accommodate this option.

flow-remove-types/register with modules

I have a module using Flow in source /* @flow*/ and require('flow-remove-types/register');. It works standalone. Then I use this module in application which is using Flow too (/* @flow*/ and require('flow-remove-types/register');). Got a syntax error, because in register.js we have:

  var transformedSource = filename.indexOf('node_modules/') === -1
    ? removeTypes(source)
    : source;

and module's file sources are not processed, as their filenames contains 'node_modules/'.
What about to compile unconditionally?

var transformedSource = removeTypes(source);

P.S. Ubuntu 14, Node.js 6.9.1.

Pretty option and no-flow files not working together it seems :)

I get the following error when I use flow-remove-types pretty option with files which arent under "flow":

Error transforming /home/katja/Dokumente/alo/node_modules/lodash/cloneDeep.js with 'flow-remove-types' plugin: Cannot read property 'length' of undefined
TypeError: Error transforming /home/katja/Dokumente/alo/node_modules/lodash/cloneDeep.js with 'flow-remove-types' plugin: Cannot read property 'length' of undefined
    at generateSourceMappings (/home/katja/Dokumente/alo/node_modules/flow-remove-types/index.js:287:35)
    at Object.generateMap (/home/katja/Dokumente/alo/node_modules/flow-remove-types/index.js:116:28)
    at Object.transform (/home/katja/Dokumente/alo/node_modules/rollup-plugin-flow/index.js:15:28)
    at /home/katja/.nvm/versions/node/v4.4.5/lib/node_modules/rollup/src/utils/transform.js:19:35

It seems the problem might be in the following code sequence:

At https://github.com/flowtype/flow-remove-types/blob/master/index.js#L40

    if (pragmaStart === -1 && !all) {
      return resultPrinter(options, source);
    }

At https://github.com/flowtype/flow-remove-types/blob/master/index.js#L111

    generateMap: function () {
      return {
        version: 3,
        sources: [ 'source.js' ],
        names: [],
        mappings: pretty ? generateSourceMappings(removedNodes) : ''
      };
    }

At https://github.com/flowtype/flow-remove-types/blob/master/index.js#L281

// Generate a source map when *removing* nodes rather than replacing them
// with spaces.
function generateSourceMappings(removedNodes) {
  var mappings = '';
  var end = { line: 1, column: 0 };

  for (var i = 0; i < removedNodes.length; i++) {

If you would have used flow this wouldnt had happened xDD

[Feature Request] Watcher

Would it be possible to add a watch option to this package? This would make development much easier when working on a linked node_module.

I've been able to work around this temporarily by adding the following to the lib's package.json

{
  "devDependencies": {
    "chokidar-cli": "^1.2.0",
    "flow-remove-types": "^1.2.3"
  },
  "scripts": {
    "build": "rm -rf lib/ && flow-remove-types --out-dir lib/ src/ --pretty --all",
    "build:watch": "chokidar 'src/**/*.js' -c 'flow-remove-types {path} > lib/$(echo {path} | cut -c5-) --pretty --all'",
  }
}

Flow-remove-types does not handle functions/object without explicit argument/key names

// works
type A = {[key: string]: string};
type B = (foo: string) => string;

// works in flow, but flow-remove-types fails
type A = {[string]: string};
type B = (string) => string;

Flow documentation is not clear on the syntax and whether omitting names like this should be allowed, but Flow 0.35 parses such definitions without any errors. So flow-remove-types probably should too. cc @leebyron

.flowconfig all=true option is being ignored

I have project with an src/ folder containing type-annotated javascript, and a lib/ folder. In the project's root directory I have a .flowconfig file with the all=true option in the [options] section, so that I don't have to specify the //@flow directive in the beginning of each file. And while this works when type-checking with flow, flow-remove-types still requires the //@flow directive in order to parse flow javascript files.

I'm using flow-remove-types like this: flow-remove-types -d lib/ src/, executed from the project's root folder.

Attribute of class removed

I'm using VueJS + FlowJS, when I remove types, attributes of class not initialized are removed too.
Unfortunately initialize variable is not possible here with VueJS because it come from a parent. So I can't rewrite it, there is an error at runtime.

e.g:

@Component
export default class UserDetails extends Vue {
  @Prop({ type: Number, required: true })
  id: number;
}

After flow-remove-types

@Component
export default class UserDetails extends Vue {
  @Prop({ type: Number, required: true })
}

That I expect:

@Component
export default class UserDetails extends Vue {
  @Prop({ type: Number, required: true })
  id;
}

Is there a solution ?
Thank you very much.

script does not copy .css files when running against dirs

directory example:

โ”œโ”€โ”€ src
|   โ””โ”€โ”€ components
|       โ””โ”€โ”€ MyComponent
|           โ”œโ”€โ”€ MyComponent.jsx   # with flow types
|           โ”œโ”€โ”€ MyComponent.css

After running the following command i get this:

flow-remove-types src/ --out-dir dest/
โ”œโ”€โ”€ dest
|   โ””โ”€โ”€ components
|       โ””โ”€โ”€ MyComponent
|           โ”œโ”€โ”€ MyComponent.jsx   # without flow types
|           โ”œโ”€โ”€ # where is my .css file?

Failing to run on Windows

Having some trouble running this on Windows ๐Ÿ˜ญ (Azure Site)
Works perfectly fine on my Mac/Linux

Version: 1.2.1

D:\home\site\repository\node_modules\.bin\flow-remove-types:2
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
          ^^^^^^^
SyntaxError: missing ) after argument list
    at Object.exports.runInThisContext (vm.js:76:16)
    at Module._compile (module.js:542:28)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

npm ERR! Windows_NT 6.2.9200
npm ERR! argv "D:\\Program Files (x86)\\nodejs\\6.10.0\\node.exe" "D:\\Program Files (x86)\\npm\\3.10.10\\node_modules\\npm\\bin\\npm-cli.js" "run" "build"
npm ERR! node v6.10.0
npm ERR! npm  v3.10.10
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `rm -rf dist && node node_modules/.bin/flow-remove-types -p -m -d dist src`
npm ERR! Exit status 1
....

Not Working With .mjs files

This does not seem to be removing types from .mjs files.

type TSignUpBody = {
     ^^^^^^^^^^^
SyntaxError: Unexpected identifier

Starting the server using:

import 'flow-remove-types/register';
import './index.mjs';

including content from node_modules is impossible without a nonintuitive exclude

The test mock framework I'm working on needs to use flow-remove-types to include some components of a project in its node_modules. From the docs it seems like I should be able to accomplish this with:

require('flow-remove-types/register')({ includes: /.*?\/mapbox-gl\/src\/.*/ });

But this doesn't work because of the logic in https://github.com/flowtype/flow-remove-types/blob/769385af04e8151579701d3c3a1d450a2db3b021/register.js#L49 -- the default exclusion value breaks my inclusion criterion. Instead I have to do something like:

require('flow-remove-types/register')({ includes: /.*?\/mapbox-gl\/src\/.*/, excludes: { test: function() { return false; }} });

This is workable but unintuitive. I'd like to suggest dividing the logic into more levels of priority:

explicit exclusion criteria > explicit inclusion criteria > default exclusion criteria > default inclusion criteria

Failed remove flow types from async function (generic)

Source code:

/* @flow */

type ObjMessageType<T> = {
  message: T
};
const f = async <MessageType>(
  message: MessageType
): Promise<ObjMessageType<MessageType>> => {
   await Promise.resolve();
   return Promise.resolve({
    message
  });       
};

flow-check

Ok
https://flow.org/try : No errors!

flow-remove-types

NOT Ok

flow-remove-types /tmp/test.types.js -d /tmp/build --all --pretty
/tmp/test.types.js
 โ†ณ Syntax Error: Unexpected token, expected ; (8:1)
   7:  ): Promise<ObjMessageType<MessageType>> => {

the error is reproduced only for async function!

BUT

/* @flow */

type ObjMessageType<T> = {
  message: T
};
async function f <MessageType> (
  message: MessageType
): Promise<ObjMessageType<MessageType>> {
   await Promise.resolve();
   return Promise.resolve({
    message
  });       
};

it makes no mistakes neither by flow-check nor by flow-remove-types

flow-check

Ok
https://flow.org/try : No errors!

flow-remove-types

Ok

flow-remove-types /tmp/test.types.js -d /tmp/build --all --pretty
/tmp/test.types.js
 โ†ณ /tmp/build/tmp/test.types.js

flow-node breaks multiline statements

The following input works with regular node, but flow-node tries to eval it as soon as it sees the first newline:

const client = restify.createJsonClient({
  url: 'https://api.just-eat.com'
})

flow-node repl functionality explanation

Dear @leebyron
In there's at documentation, flow-node repl not much explanation functionality of repl

flow-node
var x: Array<number> = {undef: 'undef'}
undefined
x
{ undef: 'undef' }

flow-node repl does not throwing error like flow cli actually ๐Ÿ˜…

Upgrading from 1.0.5 to 1.1.0 results in "Invalid non-string/buffer chunk while parsing file"

The project cvmtl/cvmtl-webui was working on MacOS X 10.2, with NodeJS 6.7.0, but now without any code change results in the following error:

{ TypeError: Invalid non-string/buffer chunk while parsing file: /Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/mapbox-gl/js/mapbox-gl.js
    at validChunk (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/readable-stream/lib/_stream_writable.js:249:10)
    at DestroyableTransform.Writable.write (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/readable-stream/lib/_stream_writable.js:272:53)
    at Stream.ondata (stream.js:31:26)
    at emitOne (events.js:96:13)
    at Stream.emit (events.js:188:7)
    at drain (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/through/index.js:36:16)
    at Stream.stream.queue.stream.push (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/through/index.js:45:5)
    at Stream.transform (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/unflowify/index.js:29:12)
    at _end (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/through/index.js:65:9)
    at Stream.stream.end (/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/through/index.js:74:5)
  filename: '/Users/ajmas/Projects/cvmtl/cvmtl-webui/node_modules/mapbox-gl/js/mapbox-gl.js',

Doing some investigation shows that it is the change of flow-remove-types from 1.0.5 to 1.1.0 that seems to be causing the issue. For the moment I have downgraded to 1.0.5 in my local install to resolve the issue.

Note, this happens when I do:

node_modules/.bin/gulp build

Any ideas as to the cause?

Remove pragma comment completely if no other content present

Is it possible to supply an option to remove pragmas with corresponding comments completely, if comments have no other content but pragma only? Like:
/* @flow foo */ โ†’ /* foo */,
but /* @flow */ โ†’ (empty string).

For now I got emptish comments in my generated code like this: /* */.

PATENTS and license

Are there any plans to match the licensing of React, Jest, Flow, and Immutable (relicense this library under MIT, remove the PATENTS file, etc.)?

Add argument for silent outputwhen running flow-remove-types

Something I'd like to see is the ability to compress or suppress the output when running the command-line tool as not to fill my terminal with copy commands. It's almost never useful information in the write code -> run -> test -> write code cycle and produces a lot of excess output in my terminal.

I could pipe the output to /dev/null but honestly I'd rather avoid doing that if possible because I don't want to lose access to the exit code for the system.

Any thoughts?

Output not parsing flow

When I use the command flow-remove-types src/services/context/index.js > TEST.js
For demo purposes I just selected a few flow syntax from our code to pass through flow-remove-types, I get the following output, the same as the input, nothing has been parsed:

`const Context = require('./models/Context');
const ContextDialogstate = require('./models/ContextDialogstate');
const Dialogstate = require('../dialogstate/models/Dialogstate');

const getContextDialogstateByType = async (dialogstateId: number, type: string) => {
const contextDialogstates = await ContextDialogstate
.where({ dialogstate_id: dialogstateId, type })
.fetchAll({
withRelated: ['context'],
});

return contextDialogstates ? contextDialogstates.toJSON() : null;
};`

(No need to paste input source code and output source code, they are identical)

It doesn't work either when I use the following command flow-remove-types -d lib/src/ ./src, the files are just copied without parsing flow

Nested File Structures Fail

So, I'm working on a project that uses the CST project. That project has very little documentation, so I wanted to see if I could generate some for local development. ESDoc was giving the best results, but it was erroring on many files because the project is using flow for type checking. So I grabbed this module and set it on the src directory in the cst repo and almost immediately encountered an error. It was telling me that a file was not found, and that file was supposed to be the file created by this module! Ultimately, to get the desired results, I had to create the empty directory tree in the destination directory that matched the directory tree in the source directory. After doing that, the command succeeded without issue:

$ flow-remove-types src/ --out-dir src-unflowed/
src/Parser.js
 โ†ณ src-unflowed/Parser.js
src/Traverse.js
 โ†ณ src-unflowed/Traverse.js
src/elementTree.js
 โ†ณ src-unflowed/elementTree.js
src/index.js
 โ†ณ src-unflowed/index.js
src/visitorKeys.js
 โ†ณ src-unflowed/visitorKeys.js
fs.js:549
  return binding.open(pathModule._makeLong(path), stringToFlags(flags), mode);
                 ^

Error: ENOENT: no such file or directory, open 'src-unflowed/elements/Element.js'
  ...
// not using -p to illustrate all dirs with files in them
$ mkdir src-unflowed/elements
$ mkdir src-unflowed/elements/types
$ mkdir src-unflowed/elements/types/utils
$ mkdir src-unflowed/plugins
$ mkdir src-unflowed/plugins/scopes
$ mkdir src-unflowed/utils

// then all files succeeded
$ flow-remove-types src/ --out-dir src-unflowed/
src/Parser.js
 โ†ณ src-unflowed/Parser.js
src/Traverse.js
 โ†ณ src-unflowed/Traverse.js
src/elementTree.js
 โ†ณ src-unflowed/elementTree.js
src/index.js
 โ†ณ src-unflowed/index.js
src/visitorKeys.js
 โ†ณ src-unflowed/visitorKeys.js
src/elements/Element.js
 โ†ณ src-unflowed/elements/Element.js
src/elements/ElementAssert.js
 โ†ณ src-unflowed/elements/ElementAssert.js
...

Please help I get the error: Source "src/" is not a file.

Whenever I execute this command:

./node_modules/.bin/flow-remove-types src/ -D lib/

I get this error:

Source "src/" is not a file.

Here is my directory tree (autogenerated):

|____node_modules
| |____.bin
| | |____babylon
| | |____flow-node
| | |____flow-remove-types
| |____babylon
| | |____bin
| | | |____babylon.js
| | | |____generate-identifier-regex.js
| | |____CHANGELOG.md
| | |____lib
| | | |____index.js
| | |____LICENSE
| | |____package.json
| | |____README.md
| |____flow-remove-types
| | |____flow-node
| | |____flow-remove-types
| | |____index.js
| | |____LICENSE
| | |____package.json
| | |____PATENTS
| | |____README.md
| | |____register.js
| |____vlq
| | |____CHANGELOG.md
| | |____dist
| | | |____vlq.js
| | |____package.json
| | |____README.md
| | |____src
| | | |____vlq.js
|____package.json
|____src
| |____index.js

I am using MacOS Siera and Node version 6.10.0

Here are the steps that caused the error:

mkdir flow-test
cd flow-test
npm init # I left all the options default
npm install --save-dev flow-remove-types
mkdir src
nano src/app.js #Added a hello world with a @flow pragma comment and a flow annotated variable

As per the instructions on the page (https://flow.org/en/docs/install/), I ran:

./node_modules/.bin/flow-remove-types src/ -D lib/

And was delightfully greated with the error:

Source "src/" is not a file.

Is it suitable for production code ?

I would like to use flow on an existing project which is not using babel at all.

Is it safe to use flow-remove-types for production code ? Is there any things to consider before ?

Flow-node chokes on async/await-syntax

If you're using async/await-syntax on NodeJS (available with a flag, and by default from NodeJS 8), the flow-node process chokes on invalid syntax.

It would be nice to support this, not to force people over to Babel.

pretty option does not consider full line annotation (for eg: class property type definitions)

When i pass the following code through flow-remove-types with pretty option

export default class Destroyable {
    destroyed: boolean;

    constructor() {
        this.destroyed = false;
    }

    destructor() {
        this.destroyed = true;
    }

    destroy() {
        this.destructor();
    }
}

i get

export default class Destroyable {
    

    constructor() {
        this.destroyed = false;
    }

    destructor() {
        this.destroyed = true;
    }

    destroy() {
        this.destructor();
    }
}

It retains the newlines where the flow class property type annotations where stripped off, my assumption would be that pretty option should handle this case to remove the newlines

flow-node fails on arguments passed to node executable

flow-node --debug-brk=62295 script.js
module.js:472
    throw err;
    ^

Error: Cannot find module '--debug-brk=62295'
    at Function.Module._resolveFilename (module.js:470:15)
    at Function.Module._load (module.js:418:25)
    at Function.Module.runMain (module.js:605:10)
    at Object.<anonymous> (/Users/jordan/flow-node-bug/node_modules/flow-remove-types/flow-node:103:10)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)

Generics are left behind on class method call and when constructing imported class

I have this bit of code:

const comicImg = $('img[src*="/comics/"]');
...
const comicImage = comicImg.get<HTMLImageElement>(0);
let comicLinkUrl = (comicImage.src: any); // Put this cast here just to confirm that it otherwise works

$(...) returns the class type JQuery, which has the following definition of get on it: get<T: HTMLElement>(index: number): T;

When running this through flow-remove-types, this comes out:

const comicImg = $('img[src*="/comics/"]');
...
const comicImage = comicImg.get<HTMLImageElement>(0);
let comicLinkUrl = (comicImage.src     ); // Put this cast here just to confirm that it otherwise works

Hey look, the generic type is still there in the function call! That can't be right, can it?

Eslint without Babel?

In the readme you mention eslint support and link to eslint-plugin-flowtype, where it says that you need the babel-eslint parser to handle flow types (which negates the use of flow-remove-types entirely). I'm a little confused โ€“ can I use flow-remove-types with eslint?

Annotation of Promise

Hi,

with the new flowtype, Promise need to have an annotation as code below, but flow-remove-types is not removing the annotation:

//@flow
function foo() {

    return new Promise(function (resolve, reject) {
        resolve('hello')
    })
}

exports.dummy = function (param: string) {
    return new Promise<string>(function (resolve, reject) {
        resolve(param)
    })
}

output of flow-remove-types, the still remains:

//     

function foo() {

    return new Promise(function (resolve, reject) {
        resolve('hello')
    })
}


exports.dummy = function (param        ) {
    return new Promise<string>(function (resolve, reject) {
        resolve(param)
    })
}

travis + node support

What version of node is this planning on supporting? I don't see anything in particular since you started with var but also use shorthand object notation - can also add a travis config

register does not work with nyc

Using nyc to instrument test coverage of flow-typed code, this fails:

nyc --require=flow-remove-types/register npm test
# failed to instrument code ... (complains about a flow type)

On the other hand, using babel-register with babel-plugin-transform-flow-strip-types works:

nyc --require=babel-register npm test

I noticed a comment in register.js โ€” could it be this difference (Module.prototype._compile vs require.extensions) that prevents nyc from working? And would you accept a PR that switches register mechanism to require.extensions?

cc @leebyron

Releases?

@leebyron, I see last release was back in Oct 18, 2017.

If accepted I'd be keen to make use of --copy-source feature submitted in PR #64

Syntax Error: Unexpected token

// a.js
// @flow
import React, { createRef } from "react";

const containerRef = createRef<HTMLDivElement>();
a.js
 โ†ณ Syntax Error: Unexpected token (5:47)
   4:  const containerRef = createRef<HTMLDivElement>();

all=true option in the flow configuration file option is being ignored

I have project with an src/ folder containing type-annotated javascript, and a lib/ folder containing the final files. In the project's root directory I have a .flowconfig file with the all=true option in the [options] section, so that I don't have to specify the //@flow directive in the beginning of each file. And while this works when type-checking with flow, flow-remove-types still requires the //@flow directive in order to parse and compile the files properly.

I'm using flow-remove-types like this from the project's root folder: flow-remove-types -d lib/ src/.

Doesnt remove generic type

I was expecting that using yarn flow-remove-types deleteme.js --all --pretty -d no-types

given:

/* @flow */

function foo<T> (a: T): T {
  return a
}

const bar = foo<number>(123)

the output would be:

/*  */

function foo (a) {
  return a
}

const bar = foo(123)

but instead i got:

/*  */

function foo (a) {
  return a
}

const bar = foo<number>(123)

Is this the expected behavior?
Is it possible to remove the generic types with this utility?

some code to cause SyntaxError: Unexpected token => when remove types

const normalizeEvent = cached((name: string): {
  name: string,
  once: boolean,
  capture: boolean,
  passive: boolean,
  handler?: Function,
  params?: Array<any>
} => {
})

removed:

const normalizeEvent = cached((name        )   
               
                
                   
                   
                     
                     
  => {
})

because:

An arrow function cannot contain a line break between its parameters and its arrow.

var func = ()
           => 1; 
// SyntaxError: expected expression, got '=>'

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.