Giter Club home page Giter Club logo

react-smart-data-table's Introduction

react-smart-data-table

npm version jest Contributor Covenant Workflow Status Total alerts Language grade: JavaScript

A smart data table component for React.js meant to be configuration free, batteries included.

About

This is meant to be a zero configuration data table component for React.js in the spirit of plug and play.

Just feed it an array of equal JSON objects and it will create a template free table that can be customized easily with any framework (or custom CSS).

If you want more control over the data rendering process or don't need the smarts, check out react-very-simple-data-table.

Features

It currently supports:

  1. Humanized column names based on object keys
  2. Sortable columns
    • Accepts a custom sort compareFn function
  3. Rows filtering / searchable
  4. Search term highlight in the results
  5. Column visibility toggles
  6. Automatic pagination
  7. Server-side/remote data
  8. Control over row clicks
  9. Smart data rendering
    • URLs and E-Mail addresses rendered as the href in an anchor tag <a />
    • boolean value parsing to yes/no word
    • Image URLs rendered as the src for an image tag <img />
  10. Custom override if the default behavior is unwanted for some columns
  11. Custom components
    • Paginator
  12. Control the order of the columns
    • Using the above, it's also possible to select which columns to display

Installation

yarn add react-smart-data-table

# or

npm install react-smart-data-table

There is some very basic styling you can use to get started, but since v0.8.0 you need to import it specifically. You can also copy the file and use it as the basis for your own theme.

// Import basic styling
import 'react-smart-data-table/dist/react-smart-data-table.css'

Context

You can access the SmartDataTable's internal context in your own component by using the useSmartDataTableContext hook.

Note: You must be within the context of SmartDataTable, e.g. passing a custom component to emptyTable, loading, or paginator.

import { useSmartDataTableContext } from 'react-smart-data-table'

const MyComponent = () => {
  const { columns, data } = useSmartDataTableContext()

  return (
    <div>
      <h3>My Component</h3>
      <p>
        Columns: {columns.length}
      </p>
      <p>
        Rows: {data.length}
      </p>
    </div>
  )
}

Props

Name Default Type Description
data [] {array|string} An array of plain objects (can be nested) or a URL
dataKey 'data' {string} The object key where the async data is available
dataKeyResolver null {function} Supply a function to extract the data from the async response
dataRequestOptions {} {object} Fetch API options passed directly into the async request call
dataSampling 0 {number} Percentage of the data to sample before computing the headers
dynamic false {boolean} Use this if your column structure changes dynamically
emptyTable null {element} Pass a renderable object to render when there is no data
filterValue '' {string} Filters all columns by its value
headers {} {object} The object that overrides default column behavior
hideUnordered false {boolean} Hides all the columns not passed to orderedHeaders
loader null {element} Element to be rendered while fetching async data
name 'reactsmartdatatable' {string} The name for the table
onRowClick undefined {function} If present, it will execute on every row click
orderedHeaders [] {array} An ordered array of the column keys
paginator elements {element} Pass a renderable object to handle the table pagination
parseBool false {boolean|object} When true, boolean values will be converted to Yes/No
parseImg false {boolean|object} When true, image URLs will be rendered as an img tag
perPage 0 {number} Paginates the results with the value as rows per page
sortable false {boolean} Enables the columns of the table to be sortable
withFooter false {boolean} Copy the header to the footer
withHeader true {boolean} Can be used to disable the rendering of column headers
withLinks false {boolean} Converts e-mails and url addresses to links
withToggles false {boolean|object} Enables the column visibility toggles

emptyTable

// Any renderable object can be passed
const emptyTable = <div>There is no data available at the time.</div>

headers

/*
  Use the following structure to overwrite the default behavior for columns
  Undefined column keys will present the default behavior
    text:       Humanized text based on the column key name
    invisible:  Columns are visible by default
    sortable:   Columns are sortable by default
    filterable: Columns are filterable by default
    isImg:      Will force the render as an image, e.g. for dynamic URLs
    transform:  Allows the custom rendering of the cells content
                Should be a function and these are the arguments passed:
                  (value, index, row)
                The index is the position of the row as being rendered and
                not the index of the row in the original data
  Nested structures can be defined by a string-dot representation
    'key1.key2.key3.[...].key99'
*/
const headers = {
  columnKey: {
    text: 'Column 1',
    invisible: false,
    sortable: true,
    filterable: true,
  },
  'nested.columnKey': {
    text: 'Nested Column',
    invisible: false,
    sortable: (a, b) => b['nested.columnKey'] - a['nested.columnKey'],
    filterable: true,
  },
  // If a dummy column is inserted into the data, it can be used to customize
  // the table by allowing actions per row to be implemented, for example
  tableActions: {
    text: 'Actions',
    invisible: false,
    sortable: false,
    filterable: false,
    transform: (value, index, row) => {
      // The following results should be identical
      console.log(value, row.tableActions)
      // Example of table actions: Delete row from data by row index
      return <button onClick={() => deleteRow(row)}>Delete Row</button>
    },
  },
}

onRowClick()

const onRowClick = (event, { rowData, rowIndex, tableData }) => {
  // The following results should be identical
  console.log(rowData, tableData[rowIndex])
}

paginator

The CustomComponent passed down as a prop will be rendered with the following props which can be used to perform all the necessary calculations and makes it fully compatible with Semantic UI's Pagination component.

const CustomComponent = ({
  activePage, totalPages, onPageChange,
}) => (/* ... */)

<SmartDataTable
  // ...
  paginator={CustomComponent}
/>

// To change the page, call the onPageChange function with the next activePage

<MyCustomElement
  // ...
  onClick={e => this.onPageChange(e, { activePage: nextActivePage })}
/>

parseBool

// Default
const parseBool = {
  yesWord: 'Yes',
  noWord: 'No',
}

parseImg

// You can pass a regular style object that will be passed down to <img />
// Or a Class Name
const parseImg = {
  style: {
    border: '1px solid #ddd',
    borderRadius: '4px',
    padding: '5px',
    width: '150px',
  },
  className: 'my-custom-image-style',
}

orderedHeaders / hideUnordered

If you want to control the order of the columns, simply pass an array containing the keys in the desired order. All the omitted headers will be appended afterwards unpredictably. Additionally, you can pass the hideUnordered in order to render only the headers in orderedHeaders and hide the remaining.

const hideUnordered = true

const orderedHeaders = [
  'key1',
  'key2.subkey3',
  ...
]

withToggles

You can control the Toggles by passing an object with the following structure:

// Default toggles enabled
const withToggles = true

// Default toggles enabled with default select all
const withToggles = {
  selectAll: true,
}

// Toggles with a custom locale
const withToggles = {
  // The options to be passed as props to the `SelectAll` component
  selectAll: {
    // The text to be displayed in the Select All input
    locale: {
      // The default label for the `unchecked` state
      selectAllWord: 'Select All',
      // The default label for the `checked` state
      unSelectAllWord: 'Unselect All',
    },
    // You should not need to use this, but it is here for completeness
    handleToggleAll: (isChecked: boolean): void => {
      // ...
    },
  },
}

Examples

Async data loading (fetch)

By passing a string to the data prop, the component will interpret it as an URL and try to load the data from that location using fetch. If a successful request is returned, the data will be extracted from the response object. By default, it will grab the data key from the response. If it's in a different key, you can specify it with the dataKey prop. Just in case it's not a first-level attribute, you can supply a custom function to locate the data using the dataKeyResolver prop.

response from /api/v1/user

{
  "status": "success",
  "message": "",
  "users": [{ "id": 0, "other": "..." }, { "id": 1, "other": "..." }, "..."]
}

response from /api/v1/post

{
  "status": "success",
  "message": "",
  "results": {
    "posts": [{ "id": 0, "other": "..." }, { "id": 1, "other": "..." }, "..."]
  }
}

component

// Using `dataKey`
<SmartDataTable
  data="/api/v1/user"
  dataKey="users"
  name="test-table"
/>

// Using `dataKeyResolver`
<SmartDataTable
  data="/api/v1/post"
  dataKeyResolver={(response) => response.results.posts}
  name="test-table"
/>

Simple sortable table (with Semantic UI)

import React from 'react'
import ReactDOM from 'react-dom'
import faker from 'faker'
import SmartDataTable from 'react-smart-data-table'

const testData = []
const numResults = 100

for (let i = 0; i < numResults; i++) {
  testData.push({
    _id: i,
    fullName: faker.name.findName(),
    'email.address': faker.internet.email(),
    phone_number: faker.phone.phoneNumber(),
    address: {
      city: faker.address.city(),
      state: faker.address.state(),
      country: faker.address.country(),
    },
  })
}

ReactDOM.render(
  <SmartDataTable
    data={testData}
    name="test-table"
    className="ui compact selectable table"
    sortable
  />,
  document.getElementById('app'),
)

Demos

You can try react-smart-data-table with different UI libraries in the demo pages below. You can experiment with different features as well.

Take a look at the full featured example's source code.

Also, see it in full integration with a simple user/group management dashboard application. Feel free to play around with it, it's built with hot reloading.

If you want to play around, check out this codepen.

FAQ

If you're having trouble with react-smart-data-table, please check out the answers below. Otherwise, feel free to open a new issue!

  • Check this answer to see how to hide the pagination for an empty table
  • Check this answer if you're integrating with Server Side Rendering (SSR)
  • Check this answer if you want to implement a double click event on a row
  • Check this answer if you want to control the active page manually (e.g., based on a URL parameter)
  • Check this answer if you want to style individual columns differently

Forking / Contributing

If you want to fork or contribute, it's easy to test your changes. Just run the following development commands. The start instruction will start a development HTTP server in your computer accessible from your browser at the address http://localhost:3000/.

yarn start

react-smart-data-table's People

Contributors

dependabot[bot] avatar joaocarmo avatar lgtm-com[bot] avatar tisoap 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-smart-data-table's Issues

Column ordering

Hi.. thanks for this awesome component !

Btw, is there a way to order the columns ? Maybe we can add some sort of 'position' field in headers

Adding row double click

Hello,

Is there a way to implement a rowDoubleClick() Event ?
Sometimes it is better not to select a row with a single click, because every time a user (accidentally ) clicks in the table, the single click event is triggered.

Pagination customization/localization

Hello, thanks for this nice component.
Will you consider adding some sort of customization for the "pagination" ?
like localization or maybe simple arrows ?

Thanks again

Individual Column alignment

Expected Behavior

Can we use specific alignment ?, if yes, then how we can do that.
Suppose I want to do right align in right with header and data .

save the column width, sorts and filters

I am looking to replace Ag-Grid but it has a feature I can’t do without.
I did not see the option for columns to be resizable by user. Do you have it?
My components refresh the data every 30 seconds, with Ag-Grid I can save the column width, sorts and filters before the redraw and can restore them after.

Will I be able to do it with react-smart-data-table?

Not displaying all the fields

if an API returns that a load with multiple rows, let's say
row1: k1:v1,k2:v2,k3:v3
row2:k1:va1,k2:va2,k3:va3,k4:va4

in row K4 was empty so JSON did not return that key.

Expected Behavior

the table should be as


| K1 | K2| K3 | K4|

|V1 | V2 |. V3 |. |

|Va1 | Va2 |Va3 |Va4 |

Actual Behavior

instead, it only displays 3 columns ignoring 4th column since 1st row doesn't have it
| K1 | K2| K3 |

|V1 | V2 |. V3 |

|Va1 | Va2 |Va3 |

maybe it is only considering columns from 1st row only ignoring the rest

Custom headers not working

Hi,

Firstly, a fantastic module and very nearly perfect for my requirements but I am having an issue getting custom headers to display. It always displays the data set I am passing it (passed on as a prop from its parent from an axios request).

Here's a relevant snippet of my code:

const headers = {
columnKey: {
text: 'Id',
invisible: true,
sortable: false,
filterable: false
},
columnKey: {
text: 'Title',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'First Name',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'Last Name',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'Full Name',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'Post Code',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'Email',
invisible: false,
sortable: true,
filterable: true
},
columnKey: {
text: 'Unique Reference',
invisible: false,
sortable: true,
filterable: true
},
tableActions: {
text: 'Placeholder',
invisible: false,
transform: (value, index, row) => {
return (
<button onClick={() => console.log("the button worked")}>Show Details
)
}
}
}

<SmartDataTable
data={data}
dataKey=''
headers={headers}
name='test-table'
filterValue={filterValue}
perPage={perPage}
sortable
withLinks
withHeader
loader={(


Loading...

)}
/>

Many thanks in advance and keep up the great work!

Not fully compatible with Semantic UI's Pagination component

Contrary to what the documentation says, react-smart-data-table is not fully compatible with Semantic UI's Pagination component. Passing the default Pagination component directly to the paginator prop yields the following error in the browser console:

Warning: React does not recognize the `perPage` prop on a DOM element. If you
intentionally want it to appear in the DOM as a custom attribute, spell it as
lowercase `perpage` instead. If you accidentally passed it from a parent component,
remove it from the DOM element.

I've created a repository with a runnable example of this error here.

This happens because react-smart-data-table is passing down more props than necessary to the custom paginator component, and by default Semantic UI's Pagination is passing down those props to native DOM elements.

Edit: I opened a PR with a proposed fix.

Give styles to specific row

I'm trying to implement some sort of multi-row select to perform an operation on the selected items. Icould simply add a checkbox in a column, but I'd prefer a more accessible solution giving a different background color to selected items. Is there a way to assign styles/classes to these rows?

Error - need an appropriate loader

https://imgur.com/a/GAig8

Failed to compile.

./node_modules/react-smart-data-table/lib/SmartDataTable.js
Module parse failed: Unexpected token (114:6)
You may need an appropriate loader to handle this file type.
| ) : 'rsdt-sortable-icon'
| return (
| <i className={'rsdt ' + sortingIcon} onClick={(e) => { this.handleSortChange(column) }} />
| );
| }

Update table when data updates

I'm having trouble updating the table when new data is available.
The work flow is this:
User enters value into input
-> clicks search
-> search function makes an API call
-> new data is stored to this.state

Here is the sample code:

import { Container, Input, Divider } from 'semantic-ui-react';
import { Auth } from 'aws-amplify';
import { TableExamplePagination } from '../components';
import SmartDataTable from 'react-smart-data-table'

export default class Home extends Component {
    constructor(props) {
        super(props);

        this.state = {};
        this.search = this.search.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    componentDidMount() {
        Auth.currentUserInfo()
            .then(user => this.setState({ user: user }))
            .catch(err => console.log(err));
    }

    handleChange = (e, { name, value }) => this.setState({ [name]: value });

    search() {
      var apiBase = 'https://api.example.com?address='
      var url = apiBase + this.state['searchAddress']
      fetch(url)
      .then(response => response.json())
      .then(data => this.setState({ ['transactions']: data }));

    }

    memberView() {
        const { user } = this.state;
        const { transactions } = this.state;
        
        return (
            <Container>
                <Input fluid action={{ content: 'Search', onClick: this.search }} placeholder='Address...'
                onChange={this.handleChange}
                name="searchAddress"
                />
                <Divider horizontal />
                {!transactions ? '' : <SmartDataTable
                  data={transactions['from']}
                  name='from-table'
                  className='ui compact selectable table'
                  sortable
                />}
                <Divider horizontal />
                {!transactions ? '' : <SmartDataTable
                  data={transactions['to']}
                  name='from-table'
                  className='ui compact selectable table'
                  sortable
                />}

                <Divider horizontal />

            </Container>
        )
    }

    guestView() {
        return (
            <Container>Guest Home</Container>
        )
    }

    render() {
        const { authState } = this.props;
        return (
            <div id="home-module">
                { authState === 'signedIn'? this.memberView(this.props) : this.guestView() }
            </div>
        );
    }
}

Thanks for taking a look!

Enhancement: Columns selector

Hi,
I am using this tool for quite some time now recently we had to use this to parse a JSON that had 150 fields, we found that the columns selector is getting clumsy. We thought of having "SELECT ALL" and "DESELECT ALL" will be really helpful since users are only selecting 10-20 fields at a time. Also is there a way we can save these settings?

thanks a lot for the tool, you don't believe it saved us a lot of man-hours. :)

Appreciate it if you help us with the above enhancement. Thanks once again

"ReferenceError: self is not defined" when using blitz

Expected Behavior

Should show me the table with the data

Actual Behavior

Throwin error "ReferenceError: self is not defined"

Steps to Reproduce

Import the package and writing <SmartDataTable /> in the render function

Screenshot

image

Your Environment

Blitz.js is the fullstack framework includes Node.js, Next.js (Server-side rendering), React and Prisma.

Hide the paginator if the results per page were less than the perPage prop

Quoting an email I received from JA:

I would like to suggest a new feature: Include a prop or an option to hide the paginator if the results per page were less than the perPage prop. Because I think in this case is a little unuseful.

Expected Behavior

Hide the paginator if the results per page were less than the perPage prop.

Actual Behavior

Paginator is always visible.

Steps to Reproduce

const App = () => (
  <SmartDataTable
    data={data.slice(0,5)}
    perPage={10}
  />
)

ReactDOM.render(<App />, document.getElementById('app'))

Screenshot

  • None

Your Environment

  • None

Failed to compile

I have imported like
import SmartDataTable from 'react-smart-data-table';

then got error

./node_modules/react-smart-data-table/lib/SmartDataTable.js Module parse failed: Unexpected token (137:6) You may need an appropriate loader to handle this file type. | } | return ( | <i | className={rsdt ${sortingIcon}} | onClick={() => this.handleSortChange(column)}

Please help with this.

Error using with webpack

Got this error when trying to use with webpack

ERROR in ./node_modules/react-smart-data-table/lib/SmartDataTable.js
Module parse failed: Unexpected token (114:6)
You may need an appropriate loader to handle this file type.
| ) : 'rsdt-sortable-icon'
| return (
| <i className={'rsdt ' + sortingIcon} onClick={(e) => { this.handleSortChange(column) }} />
| );
| }
@ ./node_modules/react-smart-data-table/lib/index.js 2:0-45

Something went wrong ! SyntaxError: unterminated character class

Filtering causes the following error
(Something went wrong ! SyntaxError: unterminated character class)
if, '(' or '[' is entered in filter input field.

Escaping with '' works, but then selection(coloring) wont work. Any work arounds, please.

And extremely thankful for react-smart-data-table. Really helpful.

import SmartDataTable from 'react-smart-data-table' causing module parse failed

I think this would be an awesome library to use for a reactjs application, but it looks like I cannot even import SmartDataTable.

Details on error:

./node_modules/react-smart-data-table/lib/SmartDataTable.js
Module parse failed: /Users/ryanlee/src/live-alerts-frontend/live-alerts/node_modules/react-smart-data-table/lib/SmartDataTable.js Unexpected token (114:6)
You may need an appropriate loader to handle this file type.
| ) : 'rsdt-sortable-icon'
| return (
| <i className={'rsdt ' + sortingIcon} onClick={(e) => { this.handleSortChange(column) }} />
| );
| }

Error

ERROR in .//react-smart-data-table/lib/SmartDataTable.js
Module parse failed: C:\Project\Toro-Front-End\node_modules\react-smart-data-table\lib\SmartDataTable.js Unexpected token (114:6)
You may need an appropriate loader to handle this file type.
| ) : 'rsdt-sortable-icon'
| return (
| <i className={'rsdt ' + sortingIcon} onClick={(e) => { this.handleSortChange(column) }} />
| );
| }
@ ./
/react-smart-data-table/lib/index.js 2:0-45
@ ./src/components/OrderManagementTable.js
@ ./src/components/OrderManagement.js
@ ./src/components/App.js
@ ./src/index.js
@ multi (webpack)-dev-server/client?http://0.0.0.0:3000 webpack/hot/dev-server react-hot-loader/patch webpack-dev-server/client?http://0.0.0.0:3000 webpack/hot/only-dev-server babel-polyfill whatwg-fetch ./src/index

Header columns trimming Integers from names

The keys in the object has the names such as "Last 1K P99 requests"

Expected Behavior

The header should have "Last 1K P99 requests"

Actual Behavior

"Last K P requests"

Steps to Reproduce

Pass on the keys with Integers in the names

Screenshot

screenshot-localhost_3000-2020 03 20-14_13_47

Problem with search function

The problem with searching data in the table. If you do a pagination and try to make a search from the last page. The result is not displayed. Condition: per page of 10 lines, you are on the 10th page and you are searching for "Lo". A pagination is displayed, but not the result itself.

Displaying duplicate columns when using 'header' props

Expected Behavior

When using props 'headers' to override a column's header name, it should only change the name of the header.

Actual Behavior

It creates a duplicate of that same column. (See CO2 Reduced in attached photo)

Screenshot

Screen Shot 2021-04-13 at 11 16 12 PM

Edit

Getting this error:

Encountered two children with the same key, cO2Redcued. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted β€” the behavior is unsupported and could change in a future version.

PS. The entire team really likes your table, btw! We're using it for a class project and it really helped save us some time. Thank you!!

Not paginating properly

Problem

I'm trying to use the autopaginator using the "perPage" property, the paginator appears and it modifies the number of pages depending on the total number of results, but the first page shows all the rows and when you click on the next page it never change because all the rows are in the first page.

Expected Behavior

I expect it to show 2 pages with 5 rows per page, and when I click on next page It shows the other 5 remaining

Actual Behavior

It shows 2 pages but in the first page there are all the the rows (10 rows). And it shoulds only show 5 per page.

Steps to Reproduce

<SmartDataTable data="https://jsonplaceholder.typicode.com/users" dataKey="" name="test-table" className="ui compact selectable table" perPage='5' />

Screenshot

image

Your Environment

When I installed via NPM I have to force it because I'm using react 17.0.1 and It needs the dependency ^16.8.0

Smart table not rendering data

Not sure why it's not rendering. The array shows fine in console. Here is the DOM - https://imgur.com/a/o1lVT

Here is my code

import React from 'react';
import SmartDataTable from './react-smart-data-table';
import Axios from 'axios';

class BuildInfoLoader extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      buildInfoCollection: []
    }
  }

  fetchAllBuilds = () => {
    const endpoint = '/r/api/v1/apps/builds';
    Axios.get(endpoint)
      .then((response) => {
        console.log('response', response.data.builds)
        this.setState({
          buildInfoCollection: response.data.builds
        })
      })
      .catch((error) => {
        // console.log(error);
      });
  }

  componentDidMount() {
    this.fetchAllBuilds();
  }

  render() {
    return (
      <div>
        <SmartDataTable
          data={this.state.buildInfoCollection}
          name='Build Info'
          className='ui compact selectable table'
          sortable
        />
    </div>
    );
  }
}

export default BuildInfoLoader;

Pagination and activePage prop

Hello @joaocarmo ,

just my next question ...

I try to figure out how to set the table initially to a different page.
Lets say the route entry url looks like ../whatever/fancy/page/2 . Now I listen to an activePage param, here the 2 .

Is there a way to handle this ?

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.