GithubHelp home page GithubHelp logo

designer's Introduction

Designer

好设计

前言:

历时一个多月,利用自己的闲暇时间,终于完成了我的第一个开源项目Designer v1.0初级版本,后续将会继续开发迭代,用于学习和经验总结。项目主要是仿想去App——一个很文艺,充满设计感的电商类APP,为了丰富功能,里面还加入了仿开眼视频的模块。

项目截图

项目截图Part 1.png项目截图Part 2.png

《一》项目简介

1、项目初衷:

我们知道,Kotlin可以很大程度上提高我们编写代码的效率,而且完全兼容Java,支持lambda表达式、Null safe等,相信使用了Kotlin的朋友,都不会再想使用Java编写代码了。那么组件化呢,组件化的优势就更多了,特别是对于解决大型项目的迭代研发所面临的代码冗余、业务耦合、项目臃肿,资源文件大把重复等等问题帮助非常大。

组件化的优点:

其一:它把项目的基础类公共部分进行单独抽离封装,有利于更好地对库的依赖进行管理,不至于随着项目的迭代而变得乱糟糟。

其二:将业务拆分成多个模块进行独立管理,每个业务模块都能独立运行。能单独提测,大大节省开发时间

其三:对项目进行业务划分,结构清晰明了,出现问题时有利于很快的进行排查错误,节省后期维护和调试的时间。

2、项目简介

本项目采用组件化开发+Kotlin语言编写,页面布局全使用ConstraintLayout完成。网上能找到一些组件化开发的开源项目,也能找到很多Kotlin相关的开源项目,但是组件化+Kotlin结合的开源项目,还是比较少,所以我就大胆的把两者结合实践了一把,确实是遇到了不少的坑,特别是库的依赖经常报错,但是经历这个过程,自然而然获得的收获也就更大了。后续我也会把开发过程中遇到的一些问题进行汇总分享出来。

《二》项目架构及技术要点

1、项目架构图

image.png

2、项目涉及的技术要点:

1、组件化+Kotlin结合开发,如何管理第三方依赖

2、BaseActivity和BaseFragment等基类及通用布局的封装

3、MVP+Dagger 2+Retrofit+Rxjava(包括了多个BaseUrl请求的场景处理)

4、组件化开发下ARouter的运用

5、EventBus的使用

6、Google原生数据库Room的使用

7、Glide的使用(封装加载图片工具类GlideUtils,圆形、圆角图片、背景图片加载等)

8、Kotlin下使用ButterKnife

9、CommonAdapter万能适配器(包括多类型布局的运用—首页的逛模块和视频分类详情都有运用)

10、GSYVideoPlayer实现视频播放(包括全屏切换功能)

11、5.0新特性CoordinatorLayout +AppBarLayout效果实现(视频分类详情)

12、沉浸式状态栏(Activity和在Fragment中的使用及不同手机的适配)

13、DataBinding的使用

14、约束布局ConstraintLayout的使用

写在结尾:

Designer项目可以说得上是倾注了我蛮多心血了,每个页面和功能都当成是上线的App来做,力求做到精致和完善,其中还包括了很多自己项目开发中的经验汇总和对新技术的探索和整合,希望对各位读者有所帮助,欢迎点个star,follow,或者给个小心心,嘻嘻😝也可以分享给你更多的朋友一起学习,您的支持是我不断前进的动力。如果有任何问题,欢迎在GitHub上给我提issue或者留言。

下载Apk体验

致谢:

MVPArms官方快速组件化方案开源,来自5K star的信赖

RxJava

Retrofit

GSYVideoPlayer

ARouter

Kotlin中使用Room

baseAdapter

ConstraintLayout 完全解析 快来优化你的布局吧

声明

感谢想去App和开眼App提供参考,个人使用了抓包的方式使用了其中的API,并非攻击,如构成侵权,请及时通知我删除或者修改。

#工程无法运行fix 迁移Androidx: https://www.pianshen.com/article/72141877627/ 更新Androidx的butterKnife的问题: https://blog.csdn.net/LeeYKKK/article/details/98209667 Execution failed for task ':app:dataBindingMergeDependencyArtifactsDebug'. Data Binding annotation processor version needs to match the Android Gradle Plugin version. You can remove the kapt dependency com.android.databinding:compiler:3.0.1 and Android Gradle Plugin will inject the right version.https://www.jianshu.com/p/49bb7e6bc229 https://blog.csdn.net/CSDNno/article/details/79897667 Gradle插件版本、gradle版本、kotlin版本 https://blog.csdn.net/u012693479/article/details/106547206 支持lambada需配置jDK8 https://blog.csdn.net/qq_37980878/article/details/116852571 安装NDK: tools–>sdk manager–>Android sdk–>sdk tools–>show package detail–>找到NDK(side by side) 具体版本,完成下载并安装即可(fix : No version of NDK matched the request version 20.0.5594570.Version available locally:22.1.7171670...) 下载gradle慢,可配置本地gradle: //使用本地gradle : https://blog.51cto.com/u_16213304/7096625(先离线下载:https://services.gradle.org/distributions/gradle-5.6.4-bin.zip)

designer's People

Contributors

gracejojo 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

designer's Issues

MEIZU MX6 App进不去,点击没反应

报错: Unable to start activity ComponentInfo{com.jojo.design/com.jojo.design.module_core.ui.home.ACT_Home}: java.lang.IllegalStateException: properties.getProperty(name, defaultValue) must not be null

更新下开发工具啊

兄弟,app花这么大精力搞这么漂亮了,开发工具as,gradle这些也还是升级下呗,我们拉下来代码都编不过

Android Studio 3.5.1 Kotlin 1.3.10 运行报错

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':common-ui:kaptDebugKotlin'.
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:151)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.accept(ExecuteActionsTaskExecuter.java:148)
at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:191)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:141)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionStateTaskExecuter.execute(ResolveBeforeExecutionStateTaskExecuter.java:75)
at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:62)
at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:108)
at org.gradle.api.internal.tasks.execution.ResolveBeforeExecutionOutputsTaskExecuter.execute(ResolveBeforeExecutionOutputsTaskExecuter.java:67)
at org.gradle.api.internal.tasks.execution.ResolveAfterPreviousExecutionStateTaskExecuter.execute(ResolveAfterPreviousExecutionStateTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:94)
at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:95)
at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:73)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:49)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)
at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:49)
at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:43)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:355)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:343)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:336)
at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:322)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:134)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker$1.execute(DefaultPlanExecutor.java:129)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:202)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:193)
at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:129)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.gradle.api.GradleException: Compilation error. See log for more details
at org.jetbrains.kotlin.gradle.tasks.TasksUtilsKt.throwGradleExceptionIfError(tasksUtils.kt:16)
at org.jetbrains.kotlin.gradle.internal.KaptWithKotlincTask.compile(KaptWithKotlincTask.kt:79)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:103)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:48)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:41)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:702)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:669)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$5.run(ExecuteActionsTaskExecuter.java:404)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)
at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)
at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)
at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:393)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:376)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$200(ExecuteActionsTaskExecuter.java:80)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:213)
at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$1(ExecuteStep.java:33)
at java.util.Optional.orElseGet(Optional.java:267)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)
at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:58)
at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:35)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:48)
at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:33)
at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:39)
at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)
at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)
at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:35)
at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:51)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:45)
at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:31)
at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:201)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:70)
at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:45)
at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:43)
at org.gradle.internal.execution.steps.StoreSnapshotsStep.execute(StoreSnapshotsStep.java:32)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)
at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)
at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:96)
at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:89)
at java.util.Optional.map(Optional.java:215)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:54)
at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:38)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:77)
at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)
at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:90)
at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:48)
at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)
at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:120)
... 38 more

老哥app打不开。。。报如下错误

Caused by: java.lang.IllegalStateException: properties.getProperty(name, defaultValue) must not be null
at com.jojo.design.common_base.utils.BuildProperties.getProperty(BuildProperties.kt:45)
at com.jojo.design.common_base.utils.StatusBarHelper.isMIUI(StatusBarHelper.kt:228)
at com.jojo.design.common_base.utils.StatusBarHelper.setStatusTextColor(StatusBarHelper.kt:69)
at com.jojo.design.module_core.ui.home.ACT_Home.switchFragment(ACT_Home.kt:110)
at com.jojo.design.module_core.ui.home.ACT_Home.onCreate(ACT_Home.kt:50)

Unable to start activity ComponentInfo{com.jojo.design/com.jojo.design.module_core.ui.home.ACT_Home}: java.lang.IllegalStateException: properties.getProperty(name, defaultValue) must not be null

readme中的apk,打开崩溃,崩溃日志:
Unable to start activity ComponentInfo{com.jojo.design/com.jojo.design.module_core.ui.home.ACT_Home}: java.lang.IllegalStateException: properties.getProperty(name, defaultValue) must not be null

Caused by: java.lang.IllegalStateException: properties.getProperty(name, defaultValue) must not be null
at com.jojo.design.common_base.utils.BuildProperties.getProperty(BuildProperties.kt:45)
at com.jojo.design.common_base.utils.StatusBarHelper.isMIUI(StatusBarHelper.kt:228)
at com.jojo.design.common_base.utils.StatusBarHelper.setStatusTextColor(StatusBarHelper.kt:69)
at com.jojo.design.module_core.ui.home.ACT_Home.switchFragment(ACT_Home.kt:110)
at com.jojo.design.module_core.ui.home.ACT_Home.onCreate(ACT_Home.kt:50)
at android.app.Activity.performCreate(Activity.java:6942)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2880)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2988) 
at android.app.ActivityThread.-wrap14(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1631) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6682) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410) 

是不是少了什么文件?不能这么放置的吧。

闪退

在“逛”页面 滑到底部 点击商品,程序崩溃,稳定出现,再次进入“逛”,白屏,无内容

体验apk有几处闪退

  1. 首页,往上滑到尽头,点击最下面的任一item会闪退,报错是
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jojo.design/com.jojo.design.module_mall.ui.ACT_GoodsDetail}: kotlin.KotlinNullPointerException

  2. 某些商品详情页闪退(不记得哪个页面了),报错是
    java.lang.RuntimeException: Canvas: trying to draw too large(123059712bytes) bitmap.

Can not build

FAILURE: Build failed with an exception.

  • What went wrong:
    A problem occurred configuring project ':app'.

Unable to find toolchain: C:\Users\j\AppData\Local\Android\Sdk\ndk-bundle\toolchains\mips64el-linux-android-4.9\prebuilt

app进不去

项目构建成功,运行之后的app点击无响应,手机型号oppo A37m

运行之后打开报错 错误日志如下:

错误日志

Caused by: io.jsonwebtoken.ExpiredJwtException: JWT expired at 2019-01-27T03:00:00Z. Current time: 2019-03-05T15:50:40Z, a difference of 3243040225 milliseconds. Allowed clock skew: 0 milliseconds.
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:385)
at com.jojo.design.module_test.ACT_TestJwt.JWTParse(ACT_TestJwt.java:77)
at com.jojo.design.module_test.ACT_TestJwt.onCreate(ACT_TestJwt.java:48)

关于组件化中使用room的问题

mall模块中使用了数据库通过具体的实体类来创建,那其他的模块也想新增数据库库表,该怎么实现呢?我刚刚学习room不久,只是发现它在创建数据库的时候就必须传入实体类,纠结了好久……:disappointed:

点赞

App做工精细,代码架构清晰、简洁优雅,上品!

支持两下

无意中看到 正好学习下 感谢作者妹子

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.