Code Monkey home page Code Monkey logo

cq-gradle-plugin's People

Contributors

jdigger avatar sikarwarvimal avatar

Stargazers

 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

cq-gradle-plugin's Issues

Uninstall configuration setting

Hi Jim,

I am facing an issue using the plugin.For the first time installation,the content pages get loaded correctly but on subsequent builds,we are getting "class cannot be correctly instantiated" errors. We had to delete/uninstall all application-specific bundles and then run the build to make our pages load correctly.We believe this is because for every build the uninstall task is removing the previously installed bundles and causing issues due to the behavior described by the enhancement.(#3)

We are using 3.0.2 version of your plugin and also set unistallBundlesPredicate to true/false but there is no difference in terms of uninstall task.

Please provide inputs or pointers to avoid uninstalling the bundles for every build.

Add arbitrary bundles in createPackage config

I'm trying to merge the bundle and content parts into one single project. That way the source structure would look like this...

src
├── main
│   ├── java
│   ├── content
├── test

Whether that's a good idea or not, I don't know yet. But it would finally place related and dependent things into one place.

In order to get the previously built bundle into the content zip file, I'd need a way to tell the createPackage task to include the jar.archivePath, which is a File object pointing to the bundle jar file.

Probably even better would be if there was a way to provide arbitrary bundles directly as files...

apply plugin: 'cqpackage'

createPackage {
  bundles << jar.archivePath
}

Is this something that would make sense to add to the cqpackage plugin?

uninstallBundles should use dependency ordering

Right now "uninstallBundles" simply uninstalls the bundles in the order it "discovers" them, which is effectively alphabetical. Unfortunately that can also effectively be the opposite order that they should be uninstalled.

It should ask each bundle what other bundles depend on them (or what other bundles it depends on) and build a dependency graph so that it can uninstall from "least connected" to "most connected".

addBundlesToFilterXml should use createPackage.contentSrc

If you set the contentSrc on createPackage, it is not used by default for addBundlesToFilterXml to know where to get the "source" filter.xml file.

The work around looks like:

createPackage.contentSrc = project.file("src/main")
addBundlesToFilterXml.filterXmlReader = new FileReader(new File(createPackage.contentSrc as File, "META-INF/vault/filter.xml"))

Fully dynamically generate the Package Manager information

Especially since there's so much duplication between the metadata files in META-INF/vault, allow the cqpackage plugin to accept some additional information so that those files can be fully generated instead of merely templated now.

Use Environment Vars to Fill In Server Details

Currently in SlingServersConfiguration.groovy, the method defaultServers() uses hard coded values for an local author and publish server. This should be updated to try to pull from the system's environment variables if they are configured.

For Ex.
Could have following environment vars set:
AEM_AUTHOR_MACHINENAME
AEM_AUTHOR_PORT
AEM_AUTHOR_PROTOCOL
AEM_AUTHOR_USERNAME
AEM_AUTHOR_PASSWORD
AEM_PUBLISH_MACHINENAME
AEM_PUBLISH_PORT
AEM_PUBLISH_PROTOCOL
AEM_PUBLISH_USERNAME
AEM_PUBLISH_PASSWORD

The method should try to set values based on the environment variables if they are set. If not then fall back to the hardcoded standard OOTB values.

null symbolicName throws NPE when uninstalling the bundle

This typically happens when the bundle is not OSGI wrapped. We should catch the NPE and point out which bundle has the null symbolicName. We should probably still do the uninstall as well.

Caused by: java.lang.NullPointerException: Cannot invoke method contains() on null object
    at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:88)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:45)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.NullCallSite.call(NullCallSite.java:32)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:55)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.twcable.gradle.sling.osgi.SlingOsgiBundle$_uninstallAllBundles_closure19.doCall(SlingOsgiBundle.groovy:434)
    at sun.reflect.GeneratedMethodAccessor328.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at groovy.lang.Closure.call(Closure.java:439)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1379)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1372)
    at org.codehaus.groovy.runtime.dgm$149.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:271)
    at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.twcable.gradle.sling.osgi.SlingOsgiBundle.uninstallAllBundles(SlingOsgiBundle.groovy:433)
    at com.twcable.gradle.sling.osgi.SlingOsgiBundle$uninstallAllBundles.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
    at com.twcable.gradle.cqpackage.CqPackageHelper$_uninstallBundles_closure14_closure29.doCall(CqPackageHelper.groovy:332)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:54)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.twcable.gradle.sling.SlingSupport.doHttp(SlingSupport.groovy:124)
    at com.twcable.gradle.sling.SlingSupport$doHttp.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.twcable.gradle.cqpackage.CqPackageHelper$_uninstallBundles_closure14.doCall(CqPackageHelper.groovy:330)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at groovy.lang.Closure.call(Closure.java:439)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1379)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1372)
    at org.codehaus.groovy.runtime.dgm$149.invoke(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite$PogoMetaMethodSiteNoUnwrapNoCoerce.invoke(PogoMetaMethodSite.java:248)
    at org.codehaus.groovy.runtime.callsite.PogoMetaMethodSite.call(PogoMetaMethodSite.java:68)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.twcable.gradle.cqpackage.CqPackageHelper.uninstallBundles(CqPackageHelper.groovy:327)
    at com.twcable.gradle.cqpackage.CqPackageHelper$uninstallBundles.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at com.twcable.gradle.cqpackage.CqPackagePlugin$_createUninstallBundlesTask_closure13.doCall(CqPackagePlugin.groovy:279)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:90)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:324)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:278)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1016)
    at groovy.lang.Closure.call(Closure.java:423)
    at groovy.lang.Closure.call(Closure.java:439)
    at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:548)
    at org.gradle.api.internal.AbstractTask$ClosureTaskAction.execute(AbstractTask.java:529)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 57 more

Help required for the deploy the view package

Hi Jim,

Thank you for this wonderful plugin for gradle.

I am trying to use it for the content packages but I am failing in doing so.

I am new to gradle and in the process of migrating from maven to gradle on Java 1.8

Can you please let me know what I am doing wrong in the way am using your plugin?

The OSGI bundles are building just fine in other core projects.But using the below am able to see only the below tasks being called.

.....
............
..................
:project-view:assemble UP-TO-DATE
:project-view:check UP-TO-DATE
:project-view:build UP-TO-DATE

BUILD SUCCESSFUL

Nothing gets generated under the build directory.

Also if I apply the sling plugin (apply plugin: 'sling-bundle') am getting the below error.

Caused by: java.lang.IllegalStateException: There is not a 'jar' task for project ':saks-view'
at com.twcable.gradle.sling.osgi.SlingBundleConfiguration.getSourceFile(SlingBundleConfiguration.groovy:109)
at com.twcable.gradle.sling.osgi.SlingBundleConfiguration_Decorated.getSourceFile(Unknown Source)
at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:153)
at org.gradle.api.internal.BeanDynamicObject.getProperty(BeanDynamicObject.java:107)
at org.gradle.api.internal.CompositeDynamicObject.getProperty(CompositeDynamicObject.java:78)
at com.twcable.gradle.sling.osgi.SlingBundleConfiguration_Decorated.getProperty(Unknown Source)
at com.twcable.gradle.sling.osgi.SlingBundlePlugin.apply(SlingBundlePlugin.groovy:72)
at com.twcable.gradle.sling.osgi.SlingBundlePlugin.apply(SlingBundlePlugin.groovy)
at org.gradle.api.internal.plugins.DefaultPluginContainer.providePlugin(DefaultPluginContainer.java:188)
at org.gradle.api.internal.plugins.DefaultPluginContainer.addPluginInternal(DefaultPluginContainer.java:137)
at org.gradle.api.internal.plugins.DefaultPluginContainer.apply(DefaultPluginContainer.java:103)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyPlugin(DefaultObjectConfigurationAction.java:115)
... 44 more

    So I added the apply plugin: 'scr' and it fails with the below error

Caused by: org.gradle.api.UnknownDomainObjectException: SourceSet with name 'main' not found.
at org.gradle.api.internal.DefaultNamedDomainObjectCollection.createNotFoundException(DefaultNamedDomainObjectCollection.java:272)
at org.gradle.api.internal.DefaultNamedDomainObjectCollection.getByName(DefaultNamedDomainObjectCollection.java:192)
at org.gradle.api.NamedDomainObjectCollection$getByName.call(Unknown Source)
at com.twcable.gradle.scr.ScrPlugin.mainSourceSet(ScrPlugin.groovy:155)
at com.twcable.gradle.scr.ScrPlugin$_addScrTask_closure1.doCall(ScrPlugin.groovy:55)
at com.twcable.gradle.scr.ScrPlugin.addScrTask(ScrPlugin.groovy:51)
at com.twcable.gradle.scr.ScrPlugin.apply(ScrPlugin.groovy:45)
at com.twcable.gradle.scr.ScrPlugin.apply(ScrPlugin.groovy)
at org.gradle.api.internal.plugins.DefaultPluginContainer.providePlugin(DefaultPluginContainer.java:188)
at org.gradle.api.internal.plugins.DefaultPluginContainer.addPluginInternal(DefaultPluginContainer.java:137)
at org.gradle.api.internal.plugins.DefaultPluginContainer.apply(DefaultPluginContainer.java:103)
at org.gradle.api.internal.plugins.DefaultObjectConfigurationAction.applyPlugin(DefaultObjectConfigurationAction.java:115)
... 44 more

The below is the sample 'view' project's build.gradle file am using under the project-view folder.

-------------------------------------------------------------build.gradle file--------------------------------------------------------------------

group = 'com.project'
description = 'Project View Package'

apply plugin: 'maven'
apply plugin: 'osgi'
apply plugin: "cqpackage"

sourceCompatibility = 1.8
targetCompatibility = 1.8

createPackage {
bundleInstallRoot
contentSrc
addAllBundles()
}

Remove "native bundle" support

The split start level capabilities has always been dubious, and there are better ways to handle it (including breaking out into different packages). It over-complicates the plugin and the sequence of things starting in CQ.

AddBundlesToFilterXmlTask pulls in non-dependency jars

We have set up a module in a project for packaging the 3rd party dependencies of the project. The module's build.gradle file has just dependencies and enough to build a package. We also have the usual bundle and content modules. Lines 233-126 of AddBundlesToFilterXmlTask.gradle result in adding a line to the xml filter to filter the bundle jar in the 3rd party dependencies package which is not desired.

Help required for the deploy the Osgi Bundles

Hi Jim,

Now I am facing problems with the OsgI bundles.I am applying the plugin sling-bundle and issuing the gradlew clean install.

The Osgi bundle is getting generated locally in the build/libs folder of the project but nothing happens after that.Build is successful but the bundle doesn't get installed or even uploaded.

I am using the defaults except for the install path location.Am I invoking the plugin wrongly?

Please help.

Below is the build.gradle file I am using:

group = 'com.projectname'
description = 'ProjectName Core'
version = '0.1-SNAPSHOT'

configurations {
provided
compile.transitive = true
}

apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'osgi'
apply plugin: 'sling-bundle'

slingServers.author.installPath = '/apps/projectname/install'

sourceCompatibility = 1.8
targetCompatibility = 1.8

dependencies {
compile group: 'org.slf4j', name: 'slf4j-simple', version:'1.6.4'
compile group: 'org.slf4j', name: 'slf4j-api', version:'1.6.6'
compile group: 'org.apache.felix', name: 'org.osgi.core', version:'1.4.0'
compile group: 'org.apache.felix', name: 'org.apache.felix.scr', version:'1.6.0'
compile group: 'commons-collections', name: 'commons-collections', version:'3.0'
compile group: 'commons-lang', name: 'commons-lang', version:'2.3'
compile group: 'com.google.guava', name: 'guava', version:'14.0'
compile(group: 'org.apache.felix', name: 'org.apache.felix.scr.annotations', version:'1.9.10') {
/* This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'org.apache.felix', name: 'org.apache.felix.ipojo', version:'1.8.0') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'org.osgi', name: 'org.osgi.core', version:'4.2.0') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'javax.servlet', name: 'servlet-api', version:'2.5') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'javax.servlet', name: 'jsp-api', version:'2.0') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'com.adobe.aem', name: 'aem-api', version:'6.0.0.1') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. /
}
compile(group: 'org.apache.sling', name: 'org.apache.sling.jcr.jcr-wrapper', version:'2.0.0') {
/
This dependency was originally in the Maven provided scope, but the project was not of type war.
This behavior is not yet supported by Gradle, so this dependency has been converted to a compile dependency.
Please review and delete this closure when resolved. */
}
}

uploadBundle{
}

showBundle {
}

* is not currently on the server, so can not install

When trying to install Grabbit using v3.0.1

grabbit is not currently on the server, so can not install
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77)
    at org.codehaus.groovy.reflection.CachedConstructor.doConstructorInvoke(CachedConstructor.java:71)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrap.callConstructor(ConstructorSite.java:81)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190)
    at com.twcable.gradle.cqpackage.CqPackageCommand.commandPackage(CqPackageCommand.groovy:115)
    at com.twcable.gradle.cqpackage.CqPackageHelper$_installPackage_closure3.doCall(CqPackageHelper.groovy:131)
    at com.twcable.gradle.cqpackage.CqPackageHelper$_installPackage_closure3.call(CqPackageHelper.groovy)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1379)
    at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:1372)
    at com.twcable.gradle.cqpackage.CqPackageHelper.installPackage(CqPackageHelper.groovy:130)
    at com.twcable.gradle.cqpackage.CqPackageHelper$installPackage$5.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:112)
    at com.twcable.gradle.cqpackage.CqPackagePlugin$_installPackage_closure6_closure19.doCall(CqPackagePlugin.groovy:197)

checkBundleStatus gets confused if a server is "missing"

For example, if your configuration says to check author and publisher but publisher is not currently running, checkBundleStatus will keep waiting for all the bundles to be active on publisher (which of course won't happen) and then fail.

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.