Giter Club home page Giter Club logo

fabric8-ui's Introduction

fabric8-ui

Build Status codecov

Development environment

Run fabric8-ui with remote backends

You need to setup your shell to point to the right cluster so that it can talk to the required back end services like KeyCloak, WIT, Forge, OpenShift etc.

We provide various sample environments out of the box which make it easier to get started. They are all located as bash scripts in environments.

The default one you should use when you want to develop on the console is to reuse openshift.io production cluster:

source environments/openshift-prod-cluster.sh

There are others too. For example if you want to try run fabric8 locally on minishift and connect fabric8-ui to it then try:

source environments/local-cluster.sh

NOTE: If you want to target a local WIT backend, check our wiki How To pages.

Build and Run

Requires node version 8.3.0 and npm 5.3.0. Consider using Node Version Manager.

Run npm install. This will download all the required dependencies to be able to start the UI.

Run npm start. This will start the UI with live reload enabled. Then navigate to http://localhost:3000.

Run test

We use jest test loader because it's faster than karma execution.

All tests

npm run test

Note: the first execution of the test take longer, subsequent calls are cached and much faster.

Watch mode

If you want to run all test in a feature-flag folder in watch mode:

npm run test -- feature-flag -- --watch=true

Note: You don't need to specify full path for the name of the test.

Debug

npm run test:debug

or to debug a specific test:

npm run test:debug -- feature-flag.service
  • Go to chrome: chrome://inspect
  • Let go the debugger and put debugger in your test.

To debug in your prefer IDE consolt Jest debugging documentation.

VS Code

Run ext install EditorConfig to read the .editorconfig file

Feature flag

To learn how to toggle your work in progress development, read our wiki page on fabric8-toggles.

HTML, CSS and Less

| Code Guidelines

fabric8-ui uses HTML5 elements where appropriate, and practices practicality over purity. Use the least amount of markup with the fewest intricacies as possible.

Attribution order, syntax definitions and declaration order are an important aspect of the fabric8-ui code and should be followed according the the guidelines.

fabric8-ui uses Less for it's stylesheets. If you find yourself wanting to create a shared style that multiple components will use, then we recommend adding it to an existing .less file in the src/assets/stylesheets/shared/ directory. Only update these styles if you are making a truly global style, and are going to synchronize your changes across all of the various UI projects.

If you only want to make a change to a specific component, do so in that component's .less file, according to Angular best practices.

The file osio.less is imported into every component Less file using @import (reference), so all files inside of the /shared directory will be used by each component.

Code Quality

fabric8-ui utilizes stylelint and htmlhint to check the less and html code. As part of each linter, we include three files: .stylelintrc, .stylelintignore and .htmlhintrc.

The .stylelintrc configuration file controls our configuration for the stylelinter, which only checks folders and files that are not included in the .stylelintignore file. This allows us to exclude certain areas of the application, as needed.

The .htmlhintrc configuration file controls our HTML verification configuration. In the creation of this configuration, we have taken into account the various Angular elements that will exist in the HTML pages.

Running the code quality checks

Each linter is built into the build process, so running npm run build or npm start will display any errors, their location (file name and line number), and any error message(s). Whenever a file that is watched by the code quality checks is changed, the build (if started with npm start) will re-run, checking only the altered files.

If you would like to run either of these checks individually, without kicking off a full build, you can do so by installing stylelint and htmlhint globally:

npm install stylelint -g
npm install htmlhint -g

After installing stylelint and htmlhint globally, you can run the following commands:

  • stylelint "**/*.less"

This will run stylelint against all .less files in fabric8-ui/src, using the .stylelintrc configuration file.

  • htmlhint

This will run htmlhint against all html files in fabric8-ui/src, using the .htmlhintrc configuration file. This command will not ignore the files and folders dictated in the webpack.common.js file, leading to the possibility of errors being displayed that will not appear at build time.

Alternatively, if you would like to check a subset of folders, or a specific file, you can do so by altering your htmlhint command:

  cat src/app/layout/header/header.component.html | htmlhint stdin

Integrations

fabric8-ui uses rxjs to provide loose coupling between modules (both those in the code base and those integrated via NPM). To do this, fabric8-ui makes extensive use of the Broadcaster.

Context

Space changed

When the current space the user is viewing changes, fabric8-ui broadcasts with the key spaceChanged and the
new Space as the payload.

UI integrations

Notifications

To send a notification to the user, the module should import ngx-fabric8-wit and inject the Notifications service, and call the message() method, passing in a Notification. You can subscribe to the result of message() to observe any NotificationActions that result from the notification.

Working with multi-level depenendencies

Let's consider a scenario wher you have an NPM module 'C' which sits inside another NPM module 'B' which is included in the parent module 'A'. During development, it is very common to use npm link to create a symlink and test the changes automatically. In this case, there is a high possbility for the parent module 'A' to be totally unaware of the existence of npm module 'C' as the symlinks don't get propagated all the way up. As a result, you might end up seeing the following error in the parent module 'A':

Module not found: Error: Can't resolve 'C' in ...

To address this, we can make the parent module 'A' be aware of the existence of 'C', by making changes in

tsconfig.json

of the parent module 'A'.

Inside "compilerOptions", Add an object key, "baseUrl" which basically identifies the base of the project and all the other urls are relative to this. Add an object key, "paths" as below

{
  "compilerOptions": {
    .
    .
    .
    "baseUrl": ".",
    "paths": {
      .
      .
      .
      "C": ["node_modules/B/node_modules/C"] //relative to the base url
    }
  }
}

By doing this, parent module A now is aware of the existence of the grand child 'C'. This can be modified for n-level dependencies. If your project builds using AOT or in other words if your project uses tsconfig-aot.json or similar, same things can be handled over there as well.

Continuous Delivery & Semantic Releases

In ngx-fabric8-wit we use the semantic-release plugin. That means that all you have to do is use the AngularJS Commit Message Conventions (documented below). Once the PR is merged, a new release will be automatically published to npmjs.com and a release tag created on GitHub. The version will be updated following semantic versioning rules.

Commit Message Format

A commit message consists of a header, body and footer. The header has a type, scope and subject:

<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>

The header is mandatory and the scope of the header is optional.

Any line of the commit message cannot be longer 100 characters! This allows the message to be easier to read on GitHub as well as in various git tools.

Revert

If the commit reverts a previous commit, it should begin with revert:, followed by the header of the reverted commit. In the body it should say: This reverts commit <hash>., where the hash is the SHA of the commit being reverted.

Type

If the prefix is fix, feat, or perf, it will always appear in the changelog.

Other prefixes are up to your discretion. Suggested prefixes are docs, chore, style, refactor, and test for non-changelog related tasks.

Scope

The scope could be anything specifying place of the commit change. For example $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, etc...

Subject

The subject contains succinct description of the change:

  • use the imperative, present tense: "change" not "changed" nor "changes"
  • don't capitalize first letter
  • no dot (.) at the end

Body

Just as in the subject, use the imperative, present tense: "change" not "changed" nor "changes". The body should include the motivation for the change and contrast this with previous behavior.

Footer

The footer should contain any information about Breaking Changes and is also the place to reference GitHub issues that this commit Closes.

Breaking Changes should start with the word BREAKING CHANGE: with a space or two newlines. The rest of the commit message is then used for this.

A detailed explanation can be found in this document.

Based on https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit

Examples

Appears under "Features" header, pencil sub-header:

feat(pencil): add 'graphiteWidth' option

Appears under "Bug Fixes" header, graphite sub-header, with a link to issue #28:

fix(graphite): stop graphite breaking when width < 0.1

Closes #28

Appears under "Performance Improvements" header, and under "Breaking Changes" with the breaking change explanation:

perf(pencil): remove graphiteWidth option

BREAKING CHANGE: The graphiteWidth option has been removed. The default graphite width of 10mm is always used for performance reason.

The following commit and commit 667ecc1 do not appear in the changelog if they are under the same release. If not, the revert commit appears under the "Reverts" header.

revert: feat(pencil): add 'graphiteWidth' option

This reverts commit 667ecc1654a317a13331b17617d973392f415f02.

Commitizen - craft valid commit messages

Commitizen helps you craft correct commit messages. Install it using npm install commitizen -g. Then run git cz rather than git commit.

Running End-to-End (E2E) Tests

A set of E2E tests have been written to verify the operation of major features such as the creation of a build pipeline.

These E2E tests are configured to be run locally in a shell, locally in a docker container, and in a docker container in Centos CI. The tests can be run against a local or remote server by specifying the server's URL as a parameter to the tests.

The E2E tests are available in this repo: https://github.com/fabric8io/fabric8-test

The full set of instructions on installing and executing the E2E tests are avalable here: https://github.com/fabric8io/fabric8-test/blob/master/ee_tests/README.md

Easy E2E Test Setup

Run the following script and follow the on screen prompts to configure the test environment. The process will checkout the fabric8-test project as a sibling to fabric8-ui.

npm run e2e

To clean up the fabric8-test project:

npm run e2e:clean

To delete the e2e configuration file and re-prompt for all data:

npm run e2e:reconfig

To run the e2e tests using the last configuration without prompting:

npm run e2e:last

Mac Users

You may encounter the error readlink: illegal option -- f. To fix this, run the following commands:

brew install coreutils
ln -s "$(which greadlink)" "$(dirname "$(which greadlink)")/readlink"

Monorepo

This monorepo is managed with Lerna.

To get started, install the project dependencies and bootstrap all packages. The bootstrap process will update all packages with all their dependencies and link any cross-dependencies.

npm install
npm run bootstrap

VSCode Extensions

  • Prettier - Code formatter
    • Integrates prettier for auto formatting.
  • ESLint
    • Integrates ESLint reporting in editors.
  • Coverage Gutters
    • Display test coverage generated by lcov.
  • Jest
    • Snapshot syntax highlighting.
    • Augment unit tests with inline error reports.
  • Angular Language Service (angular.ng-template)
    • Provides a rich editing experience for Angular templates.

fabric8-ui's People

Contributors

adamj avatar andrewazores avatar aptmac avatar arunkumars08 avatar c-koehler avatar chrislessard avatar christianvogt avatar corinnekrych avatar debloper avatar dgutride avatar divyanshigupta avatar dlabrecq avatar fabric8cd avatar invinciblejai avatar jarifibrahim avatar jiekang avatar joshuawilson avatar jstrachan avatar ldimaggi avatar michaelkleinhenz avatar mitchharpur avatar nainav avatar nimishamukherjee avatar pmuir avatar raunak1203 avatar rohitkrai03 avatar sahil143 avatar sanbornsen avatar smahil avatar vikram-raj 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

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

fabric8-ui's Issues

Decide how we're going to handle logged in vs not logged in users.

Note: for support questions, please use one of these channels: Chat: AngularClass.slack or Twitter: @AngularClass

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository

  • Do you want to request a feature or report a bug?

  • What is the current behavior?

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via
    https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).

  • What is the expected behavior?

  • What is the motivation / use case for changing the behavior?

  • Please tell us about your environment:

  • Angular version: 2.0.0-beta.X
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Create a space

Description

As a project owner, I'd like to create a new space, so that I can collaborate with other team members on a specific project.

When creating a space, I should specify a name unique to the namespace where the space exists. Currently, this is the user account, and may eventually be an organization account.

Functional Acceptance Criteria:

  1. Spaces can be created with an alphanumeric set of characters.
  2. Space names should be unique to the entity where it is created - user or organization.
  3. Spaces must have names. Blank space names are not permissible.
  4. Spaces must have an associated process template at the time of creation - agile, scrum, etc.

Tasks:

  1. Extend SpacesService to create spaces in the REST API backend. (#67)
  2. Update SpacesDialogComponent to use SpacesService instead of DummyService to create spaces. (#68)

What does the logged out menu look like?

Define what the nav system looks like when the user is not logged in e.g. they are sent a link.

The right hand dropdown clearly needs updating (e.g. a sign in link), but of greater interest is the main nav structure, where a number of menus no longer make sense (e.g. settings).

This needs some thought, so for now let's assume that all pages require a user to be logged in.

Edit a space

As a owner or participant of spaces, I'd like to edit a space I'm currently collaborating in,
so that I can edit the description and other high-level details for the space.

The spaces should be editable at the route: /<username>/<spacename>

Functional Acceptance criteria:

  1. Editing the description of the space should result in an updated description.

Questions

  1. Should editing the name of the space be allowed?
  2. Should the process template be modified after creation of a space? E.g. from CMMI to Agile/Scrum.

Tasks:

  • Edit a single Space instance in the backend REST API, using it's name
  • UI task - use the method exposed by SpaceService, to capture and store changes to spaces from the UI.

Search for a space in list of spaces

As a viewer or collaborator in spaces, I'd like to search the entire list of spaces I'm currently collaborating in, so that I can pinpoint a specific space to navigate to.

The spaces should be listed and searchable at the route: /<username>/spaces

The spaces should be retrieved from the REST API from the Spaces resource at /api/spaces.

Functional Acceptance criteria:

  1. Entering a search criteria in the search box should initiate a search.
  2. The spaces listed below in the space list, should match the search criteria.
  3. The search criteria should be executed against the name of the space and the description.

Tasks:

  1. Extend SpacesService to query the REST API with filter parameters. (#69)
  2. Update SpacesComponent to use SpacesService for querying. (#70)

Questions?

  1. Should the search results highlight the matches in the name and/or description.

Extend SpacesService to query the REST API with filter parameters.

Description

We need to extend the Angular service SpacesService to search against spaces (name and description) at the spaces REST API.

Implementation

The SpacesService need to implement and expose a new public method to search for spaces using user-supplied criteria.

Reference

User story - #56

Select/View a single space

Description

As a owner or participant of spaces, I'd like to view a single space I'm currently collaborating in,
so that I can view various activities in that space. I should also be able to view other spaces where I am not a collaborator at a given moment, as long as the space is public.

The spaces should be listed at the route: /<username>/<spacename>

The space should be retrieved from the REST API from the Spaces resource at /api/spaces/<spaceId> where spaceId is the UUID of the space.

Functional Acceptance criteria:

  1. On viewing a space, the description of the space should be viewable to inform users about the nature of the space

2. The collaborators in the space should be listed.
3. The number of codebases associated with the space should be displayed.
4. The number of build pipelines associated with the space should be displayed.
5. The number of hypotheses under evaluation should be displayed.
6. New work items could be created, if permissions exist.
7. The list of scenarios (work items) in the current running iterations should be displayed.

Tasks:

  • Fetch a single Space instance from the backend REST API, using it's name
  • Display the space instance in the UI

fabric8 create project UI

fabric8 has a create new project UI:

screenshot 2016-12-07 10 47 16

Which is a front end to fabric8-forge a set of forge addons that can be used with the (currently at) 48 https://github.com/fabric8-quickstarts to generate new projects.

To avoid duplication of work across projects it would be good to get a handle of what work is required going forward as there are a few other efforts that have doing something similar.

I'm sure it's more detailed but at a super high level what's needed here?

This is just a start - lets flesh out or correct where we can

/CC @jstrachan @rajdavies @cmoulliard @pmuir

Update SpacesComponent to use SpacesService for querying.

Description

Currently, SpacesComponent does not search against the local collection of spaces, or the spaces in the backend. This should change for searching of spaces to work.

Implementation

The SpacesComponent should created and observe the user input stream for input events from the search input field. It should debounce the event stream, to wait on user input. And it should respond only to distinct events in the stream. The sequence of debounced and distinct user input events should be sent to the server for querying against the list of spaces. It should then reorder responses from the server, and map them to the original input events. The component should display only the response to the latest input event.

Reference

User story - #56

Get typeaheads working

I was struggling to get both ng2-bootstrap and ng2-typeahead to work at all. Anyone want to take a look and put an example in?

Add Pull request builder

When someone submits a PR, have ci.centos.org build a copy of the app, and serve it up from a unique URL, so the reviewer can use the changed system without having to do local work.

/signup freezes if token is not valid

"Please wait, loading user details from OAuth Provider..." it's what I see if had ever logged in before we changed the tokens in backend.
I suspect this is because the old tokens are not valid anymore. I can't re-login without cleaning my browser.

Question: Should spaces be created in the first stage of the create space dialog?

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [x] question about the decisions made in the repository

  • Do you want to request a feature or report a bug?

Requesting clarity on whether spaces should be created in the first stage of the spaces wizard, or whether the dialog needs to be improved to convey that a new space will be created in the first stage.

  • What is the current behavior?

The first dialog in the wizard has a Next button, which does not imply that the space will be immediately created.

createspacewizard-1

The second dialog however displays that the space has been created. This is confusing to the user, given the presence of a Back button in the dialog.

createspacewizard-2

  • What is the motivation / use case for changing the behavior?

If spaces are to be created in the first dialog of the wizard, then the dialog should not allow for multiple spaces to be created by the user accidentally.

Create an Angular service for querying the Spaces REST API

Description

We need an Angular service to interact with the spaces REST API. For now, it would handle querying/listing of spaces.

Implementation

This service is imported in the module. It should be available as an injectable service.

Reference

User story - #53

Get AoT to work with Chunking

There is something preventing the AoT build from Chunking the code into vendor, polyfills, and main.

Is it possible to use both AoT and Chunking with Angular 2 and Webpack?

space wizard should start with an empty space name

Note: for support questions, please use one of these channels: Chat: AngularClass.slack or Twitter: @AngularClass

  • I'm submitting a ...
    [ ] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository

  • Do you want to request a feature or report a bug?

  • What is the current behavior?

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via
    https://plnkr.co or similar (you can use this template as a starting point: http://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5).

  • What is the expected behavior?

  • What is the motivation / use case for changing the behavior?

  • Please tell us about your environment:

  • Angular version: 2.0.0-beta.X
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

Implement HTML only for new screens

https://drive.google.com/drive/u/1/folders/0B84xd3xHpx5cTnRwekI5c2NWOUU

In powerpoint, turn on outline view to see page names

  • Space wizard selection
  • Forge wizard (For the grid of icons, please just take a png from the slides and paste that in - no need to implement the tiles)
  • Pipeline wizard (For the grid of icons, please just take a png from the slides and paste that in - no need to implement the tiles)
  • Project quickstart (For the form, please just take a png from the slides and paste that in - no need to implement the actual form)

For all the "...no need to implement..." comments, these are existing/external functionality that we want to pull in as extensions.

Update SpaceDialogComponent to use SpacesService

Description

Currently, DummyService is used to create spaces that are persisted only to localstorage, and not the REST API backend.

Implementation

Update SpaceDialogComponent to use SpacesService instead of DummyService to create a new Space.

Reference

User story - #57

Extend SpacesService to edit spaces in the REST API backend.

Description

We need to extend the Angular service SpacesService to edit existing spaces using the spaces REST API. The space name should be used to identify the space.

Implementation

The SpacesService need to implement and expose a new public method to edit existing spaces.

Reference

User story - #55

Login process is cumbersome

The current (Feb 8) initial login process is cumbersome - 4 steps to login with an existing github account - see below.

Requires significant changes

create a REST proxy to the users openshift (online?) cluster so we can start to use Build/Run/Pipelines UI components

a pre-requisite of using the fabric8 Run / Build tabs is gonna be access to the OpenShift Online cluster (rather than the SaaS back end).

So it'd be nice once the user has logged into the console to also sign into the users OpenShift Online account and expose the REST API for OpenShift Online.

I guess one day we may support multiple clusters (free tier, paid tier, on premise cluster maybe?) so we may wanna leave an extra path in the REST URLs for a cluster name which we could default to just being 'online' for now?

So a REST call in the console would be something along these lines:

/k8s/
  /online/
    /api/v1/namespaces/cheese/pods

to access the pods in the cheese namespace in the online (i.e. OpenShift Online) cluster.

Environments are then relative to a cluster name; so we could support then using mixed environments; e.g. OSO, OSD, OSCP clusters in the same pipelines etc.

The REST Proxy is pretty easy really; the hard bit is the SSO ;)

For now we could hard code all users as having a single cluster called 'online' which points to OSO (or maybe a preview cluster until its live). Then over time we could support users being able to register their own clusters too (OSD etc) - though there's even more complexity in the SSO side there too but ultimately we should be able to get that to work if the right OAuth is setup in OSO / OSCP clusters

List all spaces

Description

As a owner or participant of spaces, I'd like to view a list of spaces I'm currently collaborating in,
so that I can view various activities in that space.

The spaces should be listed at the following route in the UI : /<username>/spaces

The list of spaces, that the user collaborates in, should be retrieved from the REST API from the Spaces resource at /api/spaces.

Functional Acceptance criteria:

  1. The list of spaces should contain all private and public spaces that the specified user collaborates on
  2. The description of the space should be provided to inform users about the nature of the space

3. Clicking on a space within the space list should open the space

Tasks

  1. Create a ng SpaceService [#65]
  2. Create a ng list service component [#66]

Update SpacesComponent to list spaces fetched by SpacesService

Description

Currently, SpacesComponent uses DummyService to list spaces. With SpacesService being available, we can use this instead to list and display spaces.

Implementation

Replace DummyService with SpacesService. Inject the SpacesService into the SpacesComponent and store any retrieved spaces, so spaces do not have to be retrieved from the backend every time.

Reference

User story - #53

integrate Spaces/Teams in planner with Namespaces/Teams in OpenShift online

The fabric8 Build/Run console pages are all based 100% on the kubernetes/openshift APIs. i.e. a Team is a namespace with the fabric8-environments ConfigMap inside which lists all the environments the team users etc. More background here

The upstream fabric8 console will keep this model for now; so we need a way to be able to populate the planner with teams + apps created in OpenShift Online; and vice versa so that the top right 'context switch' button & drop down is consistent between the Planner and Build/Run tabs.

e.g. if a user creates a new Team called foo, select it in the top right drop down, then navigate to the Build/Run it should be using the OpenShift Online foo namespace to view things (which would be lazily created on the fly on the users behalf).

Similar if the user switches context in the Create / Build / Run pages to the 'blah' application they create; which makes a BuildConfig in the foo namespace in OpenShift Online we need that new sub context foo / blah to be reflected in the top right context switcher.

We maybe need a little bridge that watches teams/apps being created in the OSO cluster (via our console or the OpenShift console or the CLI) get mirrored into the planner's idea of Teams / apps and vice versa

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.