Coder Social home page Coder Social logo

danielbayerlein / dashboard Goto Github PK

View Code? Open in Web Editor NEW
1.3K 31.0 188.0 2.22 MB

πŸ“Ί Create your own team dashboard with custom widgets. Built with Next.js, React, styled-components and polished.

License: MIT License

JavaScript 98.75% Dockerfile 0.82% Shell 0.42%
dashboard widget jenkins jira bitbucket sonarqube pagespeed-insights elasticsearch github react

dashboard's Introduction

Dashboard

Dashboard

Create your own team dashboard with custom widgets.

Actions Status JavaScript Style Guide Dependabot Status Deploy to now

Table of Contents

Installation

  1. Download or clone the repository.
  2. Install the dependencies with npm install.

Server

Development

Run npm run dev and go to http://localhost:3000.

Production

Build your dashboard for production with npm run build and then start the server with npm start.

Docker

  1. Build your dashboard for production with npm run build
  2. Build the image with docker build -t dashboard .
  3. Start the container with docker run -d -p 8080:3000 dashboard
  4. Go to http://localhost:8080

Create a Dashboard

You can create multiple dashboards. For example populate pages/team-unicorn.js inside your project:

import Dashboard from '../components/dashboard'
import DateTime from '../components/widgets/datetime'
import lightTheme from '../styles/light-theme'

export default () => (
  <Dashboard theme={lightTheme} name='Unicorn Dashboard'>
    <DateTime />
  </Dashboard>
)

This dashboard is available at http://localhost:3000/team-unicorn.

For an example, see pages/index.js.

Available Widgets

Example

import DateTime from '../components/widgets/datetime'

<DateTime interval={10000} />

props

  • interval: Refresh interval in milliseconds (Default: 10000)

Example

import JenkinsJobStatus from '../components/widgets/jenkins/job-status'

<JenkinsJobStatus
  url='https://builds.apache.org'
  jobs={[
    { label: 'JMeter', path: 'JMeter-trunk' },
    { label: 'Log4j Kotlin', path: 'Log4jKotlin', branch: 'master' }
  ]}
/>

For Jenkins multibranch projects add branch to the object.

props

  • title: Widget title (Default: Job Status)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: Jenkins URL
  • jobs: List of all jobs
  • authKey: Credential key, defined in auth.js

Example

import JenkinsJobHealth from '../components/widgets/jenkins/job-health'

<JenkinsJobHealth
  url='https://builds.apache.org'
  jobs={[
    { label: 'JMeter', path: 'JMeter-trunk' },
    { label: 'Log4j Kotlin', path: 'Log4jKotlin', branch: 'master' }
  ]}
/>

For Jenkins multibranch projects add branch to the object.

props

  • title: Widget title (Default: Job Health)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: Jenkins URL
  • jobs: List of all jobs
  • authKey: Credential key, defined in auth.js

Example

import JenkinsBuildDuration from '../components/widgets/jenkins/build-duration'

<JenkinsBuildDuration
  url='https://builds.apache.org'
  jobs={[
    { label: 'JMeter', path: 'JMeter-trunk' },
    { label: 'Log4j Kotlin', path: 'Log4jKotlin', branch: 'master' }
  ]}
/>

For Jenkins multibranch projects add branch to the object.

props

  • title: Widget title (Default: Build Duration)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: Jenkins URL
  • jobs: List of all jobs
  • authKey: Credential key, defined in auth.js

Example

import JiraIssueCount from '../components/widgets/jira/issue-count'

<JiraIssueCount
  title='JIRA Open Bugs'
  url='https://jira.atlassian.com'
  query='type=Bug AND project="Bitbucket Server" AND resolution=Unresolved ORDER BY priority DESC,created DESC'
/>

For Jenkins multibranch projects add branch to the object.

props

  • title: Widget title (Default: JIRA Issue Count)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: JIRA Server URL
  • query: JIRA search query (jql)
  • authKey: Credential key, defined in auth.js

Example

import JiraSprintDaysRemaining from '../components/widgets/jira/sprint-days-remaining'

<JiraSprintDaysRemaining
  title='Sprint Days'
  url='https://jira.atlassian.com'
  boardId={42}
/>

props

  • title: Widget title (Default: JIRA Sprint Days Remaining)
  • interval: Refresh interval in milliseconds (Default: 3600000)
  • url: JIRA Server URL
  • boardId: JIRA board id
  • authKey: Credential key, defined in auth.js

Example

import BitbucketPullRequestCount from '../components/widgets/bitbucket/pull-request-count'

<BitbucketPullRequestCount
  title='Bitbucket Open PR'
  url='https://bitbucket.typo3.com'
  project='EXT'
  repository='blog'
  users={['stekal', 'marleg', 'denhub']}
/>

props

  • title: Widget title (Default: Bitbucket PR Count)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: Bitbucket Server URL
  • project: Bitbucket project key
  • repository: Bitbucket repository slug
  • users: Bitbucket user slugs as an array
  • authKey: Credential key, defined in auth.js

Example

import PageSpeedInsightsScore from '../components/widgets/pagespeed-insights/score'

<PageSpeedInsightsScore url='https://github.com' />

props

  • title: Widget title (Default: PageSpeed Score)
  • interval: Refresh interval in milliseconds (Default: 43200000)
  • url: URL to fetch and analyze
  • strategy: Analysis strategy (Default: desktop)
    • Acceptable values: desktop | mobile
  • filterThirdPartyResources: Indicates if third party resources should be filtered out (Default: false)

Example

import PageSpeedInsightsStats from '../components/widgets/pagespeed-insights/stats'

<PageSpeedInsightsStats url='https://github.com' />

props

  • title: Widget title (Default: PageSpeed Stats)
  • interval: Refresh interval in milliseconds (Default: 43200000)
  • url: URL to fetch and analyze
  • strategy: Analysis strategy (Default: desktop)
    • Acceptable values: desktop | mobile
  • filterThirdPartyResources: Indicates if third party resources should be filtered out (Default: false)

Example

import SonarQube from '../components/widgets/sonarqube'

<SonarQube
  url='https://sonarcloud.io'
  componentKey='com.icegreen:greenmail-parent'
/>

props

  • title: Widget title (Default: SonarQube)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: SonarQube URL
  • componentKey: SonarQube project key
  • authKey: Credential key, defined in auth.js

Example

import ElasticsearchHitCount from '../components/widgets/elasticsearch/hit-count'

<ElasticsearchHitCount
  title='Log Hits'
  url='http://ec2-34-210-144-223.us-west-2.compute.amazonaws.com:9200'
  index='blog'
  query='user:dilbert'
/>

props

  • title: Widget title (Default: Elasticsearch Hit Count)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • url: Elasticsearch URL
  • index: Elasticsearch index to search in
  • query: Elasticsearch query
  • authKey: Credential key, defined in auth.js

Example

import GitHubIssueCount from '../components/widgets/github/issue-count'

<GitHubIssueCount
  owner='danielbayerlein'
  repository='dashboard'
/>

props

  • title: Widget title (Default: GitHub Issue Count)
  • interval: Refresh interval in milliseconds (Default: 300000)
  • owner: Owner of the repository
  • repository: Name of the repository
  • authKey: Credential key, defined in auth.js

Example

import Title from '../components/widgets/title'

<Title>API Status</Title>

Available Themes

Example

import lightTheme from '../styles/light-theme'

<Dashboard theme={lightTheme}>
  ...
</Dashboard>

Preview

dashboard-light

Example

import darkTheme from '../styles/dark-theme'

<Dashboard theme={darkTheme}>
  ...
</Dashboard>

Preview

dashboard-dark

Authentication

Any widget can authenticate itself, should your server expect this. We use basic authentication.

  1. Define your credential key in auth.js. For example:
    jira: {
      username: process.env.JIRA_USER,
      password: process.env.JIRA_PASS
    }
  2. Give the defined credential key jira via prop authKey to the widget. For example:
    <JiraIssueCount
      authKey='jira'
      url='https://jira.atlassian.com'
      query='type=Bug AND project="Bitbucket Server" AND resolution=Unresolved ORDER BY priority DESC,created DESC'
    />
  3. Create a .env file or rename .env.example to .env in the root directory of your project. Add environment-specific variables on new lines in the form of NAME=VALUE. For example:
    JIRA_USER=root
    JIRA_PASS=s1mpl3

Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing (CORS) is a W3C spec that allows cross-domain communication from the browser. By building on top of the XMLHttpRequest object, CORS allows developers to work with the same idioms as same-domain requests.

Proxy

You can use a proxy (e.g. hapi-rest-proxy) to enable CORS request for any website.

Server

docker pull chrishelgert/hapi-rest-proxy
docker run -d -p 3001:8080 chrishelgert/hapi-rest-proxy

Dashboard

<SonarQube
  url='http://127.0.0.1:3001/?url=https://sonarcloud.io'
  componentKey='com.icegreen:greenmail-parent'
/>

Resources

License

Copyright (c) 2017-present Daniel Bayerlein. See LICENSE for details.

dashboard's People

Contributors

chrishelgert avatar danielbayerlein avatar dependabot-preview[bot] avatar dependabot[bot] avatar fvicente avatar greenkeeper[bot] avatar guyav avatar marco-streng avatar michl-b avatar mortenbirkelund 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

dashboard's Issues

HTTPS

Hi Daniel,

This is not an issue, more of a question...
How do you resolve applications that are of type https?

<SonarQube
  authKey='sonarqube'
  interval='300000'
       url='http://127.0.0.0:3001/?url=https://sonarqube.com'
       componentKey='TEST'
/>

Great Dashboard!!!

Regards
DG

[README] CORS

We should add a section in the README where we explain the workaround (Proxy via e.g. Node.js Server) for the CORS problem.

Changing the HTML Header Title?

Hi Daniel,
is there any way to modify the title of the dashboard itself shown in browser tabs? Means HTML Head Title.

I didn't found anything so far in your documentation and the code itself.

BR Chris

[Widget] Validate necessary information

it would be good if every widget validates its properties and prints an error message, if the user forget to set a required property (example url for api calls)

npm install failed - on babylon

npm installed failed

npm ERR! Darwin 16.7.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v6.11.4
npm ERR! npm v3.10.10

npm ERR! fetch failed with status code 404

Github API deprecation

The current auth method has been deprecated as of Nov 2020 by GitHub; authentication would need to be revised to the new oauth specifications.

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

There have been updates to the react monorepo:

    • The dependency react was updated from 16.6.1 to 16.6.2.
  • The dependency react-dom was updated from 16.6.1 to 16.6.2.

🚨 View failing branch.

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

This monorepo update includes releases of one or more dependencies which all belong to the react group definition.

react is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

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

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 🌴

Cannot read property 'backgroundColor' of undefined

Cloning this repository, and running install, build and start command, I get the following error as soon as I visit the dashboard with my browser.

(pi@HulenPi:~/dashboard/pages $ npm start

> [email protected] start /home/pi/dashboard
> next start

> Ready on http://localhost:3000
TypeError: Cannot read property 'backgroundColor' of undefined
    at /home/pi/dashboard/.next/server/static/mX9Kv1iErUfmWQOdMcvjO/pages/index.js:363:30
    at flatten (/home/pi/dashboard/node_modules/styled-components/dist/styled-components.cjs.js:1292:21)
    at flatten (/home/pi/dashboard/node_modules/styled-components/dist/styled-components.cjs.js:1272:16)
    at ComponentStyle.generateAndInjectStyles (/home/pi/dashboard/node_modules/styled-components/dist/styled-components.cjs.js:1481:19)
    at StyledComponent.generateAndInjectStyles (/home/pi/dashboard/node_modules/styled-components/dist/styled-components.cjs.js:2160:36)
    at StyledComponent.renderInner (/home/pi/dashboard/node_modules/styled-components/dist/styled-components.cjs.js:2065:33)
    at a.render (/home/pi/dashboard/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:44:64)
    at a.read (/home/pi/dashboard/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:58)
    at renderToString (/home/pi/dashboard/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:53:83)
    at render (/home/pi/dashboard/node_modules/next-server/dist/server/render.js:86:16))

When running "npm run dev" then everything works fine.

401 Unauthorized Jira and Sonar

Hi Daniel,

This is not an issue, more of a question.

I'm trying to use the Dashboard, but I'm having issues with authentications. I did all the described steps, and looked at the old issues, but still unsuccessfully.
I'm trying to use it in the dev environment for now, and on Jira and Sonar I only get 401 on the requests. But when I put the URL directly into the browser, I'm getting the API return correctly.
Can you help me with this problem?

Dockerfile

Add Dockerfile (+ .dockerignore) and add documentation to the README.

Indicator when Server is down

When the Browser app cannot reload information from the node server, a indication in the frontend would be nice.
currently there is only a error in js console.

can not start

New user.

Fresh Ubuntu 16.04 VM.
Installed Java node, npm , angular.

I've been trying for some time to get this up and running, no luck.

Complain durring npm install:

β”‚ β”œβ”€β”€ [email protected] 
β”‚ β”œβ”€β”€ UNMET PEER DEPENDENCY typescript@*
β”‚ └─┬ [email protected] 
β”‚   β”œβ”€β”€ [email protected] 
β”‚   └── [email protected] 
β”œβ”€β”€ [email protected] 
└─┬ [email protected] 
  β”œβ”€β”€ [email protected] 
  β”œβ”€β”€ [email protected] 
  β”œβ”€β”€ [email protected] 
  β”œβ”€β”€ [email protected] 
  β”œβ”€β”€ [email protected] 
  └── [email protected] 

npm WARN optional Skipping failed optional dependency /chokidar/fsevents:
npm WARN notsup Not compatible with your operating system or architecture: [email protected]
npm WARN [email protected] requires a peer of typescript@* but none was installed.

Reproduce:

  • Unpack
  • Run npm install
  • run npm run dev
  • open page in browser.
 [email protected] dev /opt/GitHub/Dashboard/dashboard-master
> next

> Using external babel configuration
> Location: "/opt/GitHub/Dashboard/dashboard-master/package.json"
> Using "webpack" config function defined in next.config.js.
Failed to load ./.env.


 DONE  Compiled successfully in 3850ms                                  14:14:31

> Ready on http://localhost:3000
> Building page: /


 DONE  Compiled successfully in 10909ms                                 14:15:12

Error: EPERM: operation not permitted, futime
    at Error (native)
    at Object.fs.futimesSync (fs.js:1091:11)
    at TouchSync.futimes (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:211:17)
    at TouchSync.onopen (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:118:14)
    at TouchSync.open (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:176:12)
    at TouchSync.Touch (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:82:12)
    at TouchSync (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:173:1)
    at Function.module.exports.module.exports.sync.module.exports.touchSync (/opt/GitHub/Dashboard/dashboard-master/node_modules/touch/index.js:20:4)
    at null._onTimeout (/opt/GitHub/Dashboard/dashboard-master/node_modules/next/dist/server/on-demand-entry-handler.js:142:27)
    at Timer.listOnTimeout (timers.js:92:15)

npm ERR! Linux 4.10.0-28-generic
npm ERR! argv "/usr/bin/nodejs" "/usr/bin/npm" "run" "dev"
npm ERR! node v4.2.6
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] dev: `next`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] dev script 'next'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the dashboard package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     next
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs dashboard
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls dashboard
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /opt/GitHub/Dashboard/dashboard-master/npm-debug.log

sonarqube 504 method not allowed

I try using sonarqube widget but get http code 504 , because the method has been using is OPTIONS , and sonarqube Is GET. I try to add method: 'GET' , but i get other erorr 401 noAuth

Can u help ?

Docker deployment doesn't expose static directory

When runnning dashboard with "npm run dev" , all pngs in "static" are reachable from widgets under "/static/xxxx.png".

But when running from Docker, they are not reachable (even the famous favicon).

Adding a mounting point and copying files doesn't seems enought...

An in-range update of styled-components is breaking the build 🚨

The dependency styled-components was updated from 4.2.0 to 4.2.1.

🚨 View failing branch.

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

styled-components is a direct dependency of this project, and it is very likely causing it to break. If other packages depend on yours, this update is probably also breaking those in turn.

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

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 🌴

SyntaxError: Unexpected token =>

~/DEVOPS/TOOLS/DASHBOARDS/dashboard$ sudo npm run dev

[email protected] dev /Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard
next

/Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/next.config.js:4
webpack: (config) => {
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at loadConfig (/Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/node_modules/next/dist/server/config.js:57:28)
at getConfig (/Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/node_modules/next/dist/server/config.js:41:20)
at Object. (/Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/node_modules/next/dist/bin/next:95:39)

npm ERR! Darwin 16.7.0
npm ERR! argv "node" "/usr/local/bin/npm" "run" "dev"
npm ERR! node v0.12.7
npm ERR! npm v2.11.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] dev: next
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] dev script 'next'.
npm ERR! This is most likely a problem with the dashboard package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! next
npm ERR! You can get their info via:
npm ERR! npm owner ls dashboard
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR! /Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/npm-debug.log
~/DEVOPS/TOOLS/DASHBOARDS/dashboard$ /Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/node_modules/next/node_modules/glob-promise/lib/index.js:6
return new Promise((resolve, reject) => {
^^
SyntaxError: Unexpected token =>
at exports.runInThisContext (vm.js:73:16)
at Module._compile (module.js:443:25)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Module.require (module.js:365:17)
at require (module.js:384:17)
at Object. (/Users/a3x52zz/DEVOPS/TOOLS/DASHBOARDS/dashboard/node_modules/next/dist/server/resolve.js:141:20)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)

Websocket integration

First of all: Nice work! I like the react / next approach very much.

Im going to setup a Dashboard using your Framework. But regarding Datasources I want the widgets to be updated via Websockets (because of some Security Issues / Rate Limiting / etc.).
I've created a simple node server which fetches data on regular basis and publishes the latest results to connected clients.

I've hacked around a little bit to integrate sockets and everything seems to be fine right now:

...
import io from 'socket.io-client'

const socket = io('http://somehost');

export default () => (
  <Dashboard theme={darkTheme}>
    <JiraIssueCount
      title='My Issues'
      socket={socket}
      event='myproject:issues'
    />

For me the given widget-url is irrelevant, but I can imagine that a widget potentially could determine by itself if it should fetch data via url (the current approach) or via websocket (and the given eventname it should listen to), depending on the props it was given.

[Widget] Add interval to all widgets

we should add the interval property from DateTime to all existing widgets.
currently the users have to refresh the page manually - which could be really annoying on a tv.

possible solution:

  • global (default) interval on the page
  • interval for every widget (if it not exists, we could use the default interval)

TeamCity

Any plans for a TeamCity build status widget?

Time doesnt update

After playing around with this dashboard for some time, I dont understand how the functionality to update the components works. By using the setTimeout() function, the code is only updated 1 time. Is this on purpose. If i replace the setTimeout() with the setInterval() then it works.

 componentDidMount () {
    const { interval } = this.props
    this.timeout = setInterval(() => this.setState({ date: new Date() }), interval)
  }

Anybody who can explain to me how the setTimeout should be able of updating the components multiple times?

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.