Giter VIP home page Giter VIP logo

hox's People

Contributors

accwill avatar awmleer avatar brickspert avatar chelestewang avatar daolou avatar dependabot[bot] avatar h-a-n-a avatar howel52 avatar kotorik avatar kuitos avatar miracles1919 avatar ttys026 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

hox's Issues

useCounterModel 引入问题

我的react版本为16.11.0
import { useCounterModel } from "./counter";
这种引入方式会报错,不清楚是否与react版本有关
我看到在提供的CodeSandbox中引入的方式全部为
import useUserModel from "./useUserModel";
是否意味着每一个hox模块都要单独使用一个文件

yarn build 出错

使用yarn workspace方式时,yarn build的时候缺少库 @types/testing-library__dom

[16:36:03] Using gulpfile ~/../hox/gulpfile.js
[16:36:03] Starting 'build'...
[16:36:03] Starting 'clean-lib'...
[16:36:03] Finished 'clean-lib' after 2.4 ms
[16:36:03] Starting 'copy-files'...
[16:36:03] Finished 'copy-files' after 78 ms
[16:36:03] Starting 'ts'...
/.../node_modules/@types/testing-library__react/index.d.ts(13,49): error TS7016: Could not find a declaration file for module '@testing-library/dom'. '/.../node_modules/@testing-library/dom/dist/index.js' implicitly has an 'any' type.
  Try `npm install @types/testing-library__dom` if it exists or add a new declaration (.d.ts) file containing `declare module '@testing-library/dom';`
/.../node_modules/@types/testing-library__react/index.d.ts(16,15): error TS7016: Could not find a declaration file for module '@testing-library/dom'. '/.../node_modules/@testing-library/dom/dist/index.js' implicitly has an 'any' type.
  Try `npm install @types/testing-library__dom` if it exists or add a new declaration (.d.ts) file containing `declare module '@testing-library/dom';`
TypeScript: 2 semantic errors
TypeScript: emit succeeded (with errors)
[16:36:10] 'ts' errored after 6.67 s
[16:36:10] Error: TypeScript: Compilation failed
    at Output.mightFinish (/.../node_modules/gulp-typescript/release/output.js:130:43)
    at applySourceMap.then.appliedSourceMap (/.../node_modules/gulp-typescript/release/output.js:65:22)
[16:36:10] 'build' errored after 6.75 s
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

useCounterModel.data 相关

如果取到并调用 useCounterModel.data ( container.data )中 setState,container.data 会改变一次,但不会触发 useModel 中的 setState,导致当前页面不会订阅 state 更新,但实际上 container.data 已经改变,所以比如跳转到有相应 model 的页面时,会拿到已经改变的数据

model执行时机问题

model在应用一启动就会立刻执行。但是我们通常项目里面,后端的接口都是要求要先登录。这样一来,model在应用一启动还没有登录的情况下发请求的话肯定会失败。
所以我的问题是,为什么不把model设计成在某个组件真正使用的时候才触发发请求的动作?

或者,有没有什么办法可以做到在满足某些前置条件的情况下才允许model执行?

model中不能使用useEffect进行一些异步请求操作吗,报错了

import { createModel } from 'hox';
import { useState, useEffect } from 'react';
import { usePersistFn } from '@umijs/hooks';
import { queryCurrent } from '@/services/user';
import useTokenModel from '@/models/useToken';

const defaultUserInfo = {
  userId: null,
  userName: null,
  avatar: null,
};

function useUserInfo() {
  const [access, setAccess] = useState({});
  const [userInfo, setUserInfo] = useState({ ...defaultUserInfo });
  const [userInfoLoaded, setUserInfoLoaded] = useState(false);
  const { token } = useTokenModel((model) => [model.token]);

  const resetUserInfo = usePersistFn(() => {
    setAccess({});
    setUserInfo({ ...defaultUserInfo });
    setUserInfoLoaded(false);
  });

  const loadUserInfo = usePersistFn(() => {
    queryCurrent().then((res) => {
      if (res?.code === 0) {
        const { userInfo: ui, accessList = [] } = res.result;
        const newAccessListObj = {};
        accessList.forEach((element) => {
          newAccessListObj[element] = true;
        });
        setAccess(newAccessListObj);
        setUserInfo({ ...ui });
        setUserInfoLoaded(true);
      }
    });
  });

  useEffect(() => {
    if (token === null) {
      resetUserInfo();
    } else {
      loadUserInfo();
    }
  }, [token]);

  return {
    access,
    userInfo,
    userInfoLoaded,
  };
}

export default createModel(useUserInfo);

报错信息如下:

Warning: Cannot update a component (`Executor`) while rendering a different component (`Executor`). To locate the bad setState() call inside `Executor`, follow the stack trace as described in https://fb.me/setstate-in-render
    in Executor

具体报错是在执行

setAccess(newAccessListObj);
setUserInfo({ ...ui });
setUserInfoLoaded(true);

不知道为何啊

How initialize a model only when used (lazy)

e.g. we had a custom hook needs fetch data from network.

function someModel() {
  let [state, setState] = useState({loading:false, valid:false})
  useEffect(()=>{
     setState({loading:true, valid:false})
      axios().then(()=>{
         setState({loading:false, valid:true})         
     })
  }, []);
  return state;
}

export default createModel(someModel); //the network request will happens here.

The useEffect() will happen when using 'createModel', what should I do If I want the request happens only when I using that model?

e.g.

import useSomeModel ..

function SomeComponent() {
  let model = useSomeModel(); //I want the request happens on the first time using this model
}

与上下文 Context 以及 useContext 的配合问题

Hello,这是一个很棒的工具!

不过由于 createModel 将容器组件创建于 root 节点之外,无法与 Context 配合食用

可否在创建 model 时指定挂载的组件?例如

createModel(useXXX, {
  station: 'test-station'
})

<Provider>
   <HoxStation id="test-station" />
</Provider>

可能会产生异步问题,目前无法与 Context 协同是一个小遗憾

hox v2 RFC

背景

在 hox v1 中,我们的实现方案是在应用的 React 组件树之外,额外创建一个组件树,以存储 hox 中的 model。然而,这种方案渐渐显露出较多的弊端:

  • 对渲染环境的要求比较苛刻,强依赖 react-dom,SSR、RN、小程序都无法使用(#10 #11 #13)。即便可以通过 custom renderer 解决,但是又会导致包体积较大(#26)。
  • 无法和 Context 配合使用,在某些场景下瓶颈非常明显(#20 #36
  • 生命周期不够完善,无法控制何时装载何时卸载(#12
  • 强制将数据存储到全局,无法支持局部状态

为了解决上述问题,在此 RFC 中,尝试将底层实现改为基于 Context。不过基于 Context 虽然可以解决上述全部问题,但也会存在一些新的弊端:

  • API 较为复杂,特别是需要用户手动在组件树中添加 Provider

API

创建 model

import {createModel} from 'hox'

function useCounter() {
  // ...
}

export const CounterModel = createModel(useCounter)
// 或
export default createModel(useCounter)

提供 model

import {CounterModel} from './counter.model.ts'

function App() {
  return (
    <CounterModel.Provider>
      <div>
        {/* ... */}
      </div>
    </CounterModel.Provider>
  )
}

获取/订阅 model

import {useModel} from 'hox'
import {CounterModel} from './counter.model.ts'

function Foo() {
  const counterModel = useModel(CounterModel)
  return (
    ...
  )
}

只读(对应 v1 API 中的 useXxxModel.data

<CounterModel.Provider ref={yourModelRef}> // 通过 ref 的方式获取
</CounterModel.Provider>

传参

<CounterModel.Provider startFrom={123}> // 通过 ref 的方式获取
</CounterModel.Provider>
interface Props {
  startFrom: number
}
const CounterModel = createModel<Props>((props) => {
  const [count, setCount] = useState(props.startFrom)
  // ...
})

由于存在参数传递,需要给 createModel 增加一个 options.memo 参数来控制何时触发重渲染:

const CounterModel = createModel<Props>((props) => {
  const [count, setCount] = useState(props.startFrom)
  // ...
}, { // <- options
  memo: true // 开启 memo 后,Provider 的重渲染逻辑和普通 React 组件被 memo 后的逻辑类似
})

如果语法较为复杂的话,可以考虑把 memo 的默认值设置为 true,因为绝大部分场景下都是需要 memo 的。

其他

是叫 model 好还是叫 store 好?

fast refresh not working in react native

after create hox model and use state value from store fast request seem not working need to refresh to see the view change or sometime can't update state in hox need to refresh. thanks you

遇到的一个问题,或者是BUG

image
image
image
如上图所示,并没有影响到我想显示的效果但是,浏览器会弹出错误,是我的写法那里有问题?还是这是一个bug
希望能有人解答这个问题,不胜感激

hox写了国际化的Hook,订阅方式易出现循环递归嵌套调用,导致组件初始化失败。

以下代码场景:主要实现 语言包加载完成后,在加载主界面,但主界面构建失败(其他组件都使用const {intl} = useLocaleModel()来国际化)。提示可能是出现内部的循环归调用失败..

如直接显示主界面,再切换语言则正常。

暂未上react 的同步模式,目前采用useEffect,setState的方式,来解决加载后刷新的逻辑。

这个方式hox国际化的逻辑 有问题么,还是这种内部订阅方式导致的问题 ??

import React, { useEffect } from 'react';
import useLocalesModel from '@/models/useLocales';
import { useSize } from '@umijs/hooks';
import { Spin } from 'antd';

function Locale({ children }) {
  const [body] = useSize(document.querySelector('body'));
  const { localeLoaded } = useLocalesModel();

  return (
    localeLoaded ? { children }
      : (
        <div
          style={{
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            alignContent: 'center',
            width: body.width,
            height: body.height,
            margin: 'auto',
            textAlign: 'center'
          }}
        >
          <Spin tip="语言加载中..." size="large" />
        </div>
      )
  )
}
export default Locale;

useLocales:

import { useState, useRef, useEffect } from 'react';
import intl from 'react-intl-universal';
import request from 'umi-request';
import { usePersistFn } from '@umijs/hooks';
import _ from 'lodash';

// import scope from 'babel-plugin-console/scope.macro';
// import { useRequest } from '@umijs/hooks;'

import { createModel } from 'hox';

const Locales = [
  {
    name: '简体中文',
    value: 'zh-CN',
    icons: '🇨🇳'
  },
  {
    name: 'English',
    value: 'en-US',
    icons: '🇺🇸'
  }
];

function useLocales() {
  // 缓存json 防止重复请求
  console.log('useLocales running');
  const localeList = useRef(new Map());
  // 用ref 主要为了避免不必要的刷新。
  const curLang = useRef({ lang: null });

  const [localeLoaded, setLocaleLoaded] = useState(false);
  const [curLocale, setCurLocale] = useState(() => {
    const currentLocale = intl.determineLocale({
      urlLocaleKey: 'lang',
      cookieLocaleKey: 'lang',
      localStorageLocaleKey: 'lang'
    });
    const returnLocale = _.find(Locales, { value: currentLocale }) || Locales[0];
    return returnLocale;
  });


  const loadLocale = (locale) => {
    const currentLocale = locale.value;
    if (localeList.current.has(currentLocale)) {
      intl.init({
        currentLocale,
        locales: {
          [currentLocale]: localeList.current.get(currentLocale)
        }
      });
      curLang.current.lang = currentLocale
    } else {
      request.get(`public/locales/${currentLocale}.json`, {
        responseType: 'json'
      })
        .then(res => {
          intl.init({
            currentLocale,
            locales: {
              [currentLocale]: res
            }
          });
          localeList.current.set(currentLocale, res);
          curLang.current.lang = currentLocale;
        })
        .then(() => {
          setCurLocale(locale);
          setLocaleLoaded(true);
        })
    }
  };

  useEffect(() => {
    console.log('effect:', curLocale);
    loadLocale(curLocale);
  })

  const changeCurLocale = usePersistFn((key) => {
    if (curLang.current.lang === key) return;
    const returnLocale = _.find(Locales, { value: key }) || Locales[0];
    loadLocale(returnLocale);
  });

  return { Locales, curLocale, localeLoaded, changeCurLocale, intl }
}

export default createModel(useLocales);

RESOLVE unable to resolve dependency tree

When i excute npm i thow the following exception.
当我执行npm i 的时候会抛出下面的异常,无法解析依赖异常;我想这是因为项目依赖的react版本是17.x,而这个库依赖的版本是16.x,期待作者能够升级react版本到17.x

npm i
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/react
npm ERR!   react@"^17.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.0" from [email protected]
npm ERR! node_modules/hox
npm ERR!   hox@"^1.1.2" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR! 
npm ERR! See /Users/wanglin/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
  • 系统信息
    • SystemInfo
      • macOS Big Sur 11.2.3
    • Node
      • v14.15.5

model如何在不是组件情况下使用

具体场景:webSocket的onMessage ,收到消息时。去更新对应的model的state。
可以这样用吗? ws.onmessage = (e) => { useXxxxModel.updateState(e); };

model的懒加载

类似这样实现懒加载是否可行?

export function createLazyModel<T, P>(hook: ModelHook<T, P>, hookArg?: P) {
  const container = new Container(hook);
  const exe = () => {
    container.hasRun = true;
    render(
      <Executor
        onUpdate={val => {
          container.data = val;
          container.notify();
        }}
        hook={() => hook(hookArg)}
      />
    );
  }
  const useModel: UseModel<T> = depsFn => {
    // ...
    useAction(() => {
     if (!container.hasRun) {
         exe();
     }
    }, []);

    return state!;
  };
  return useModel;
}

bug

照例子写的demo,使用的是本机目录的 hox

./src/counter.js
Module not found: Can't resolve 'hox' in '/.../hox-demo/src'

找到的解决办法: hox 的 package.json 的main 改为 lib/index.js

修改代码热更新后组件状态不更新

修改代码热更新后点击按钮,状态不会更新,不清楚是什么原因

  "dependencies": {
    "@craco/craco": "^5.7.0",
    "hox": "^1.1.2",
    "node-sass": "^4.14.1",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.0",
    "simple-progress-webpack-plugin": "^1.1.2",
    "web-vitals": "^0.2.4"
  },
import { useState } from 'react'
import { createModel } from 'hox'

function useToken() {
    const [token, setToken] = useState('');
    const changeToken = (payload) =>  setToken(payload.token);
  
    return { token, changeToken }
}

export default createModel(useToken);

组件中

import React, { memo, useState } from 'react'
import useToken from './usetoken'

export default memo(function Home() {

    const token = useToken();

    const changeToken = () => token.changeToken({ token: '#123456abc' })
    const clearToken = () => token.changeToken({ token: '' })

    return (
        <div>
                <p>token: {token.token}</p>
                <button onClick={changeToken}>设置token</button>
                <button onClick={clearToken}>清空token</button>
   
        </div>
    )
})

rn

编译ReactNative 遇到
error Unable to resolve module react-dom from node_modules/hox/create-model.js: react-dom could not be found within the project.

如何在一个model使用另外一个 model

现在有一个 model A

const useAModel = usecreateModel(() => {
    const [aList] = useState([])
    return {
        aList
    }
})

我想要在 model B 获取到 aList,通过aList的数据生成bList,该怎么做?这是我尝试的方法

const useBModel = usecreateModel(() => {
    const { aList } = useAModel()
    const [bList] = useState([])

    React.useEffect(() => {
        // 在这里想参考aList数据,生成一个bList
     }, []);

    React.useEffect(() => {
        // 在这里想订阅aList的更新,对bList进行更新
    }, [aList]);

    return {
        bList
    }
})

这种情况useBModel是一个普通的hooks是可以实现的,可是我想用hox将bList存起来,请问使用hox的话该如何做?我尝试上面的办法获得报错是:

The above error occurred in the <Executor> component:
    in Executor

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.

存用户信息,应该用对象,还是不同的字段呢?

方案1:
(用户信息的每个字段,分别使用一次useState)

const useUser = () => {
    const [id, setId] = useState('');
    const [token, setToken] = useState('');
    const [username, setUsername] = useState('');
    const [email, setEmail] = useState('');
    const [points, setPoints] = useState('');
    const [avatar, setAvatar] = useState('');

..省略号...

方案2
(把用户信息放在一个对象里,只用了一次useState)

const useUser = () => {
    const [user, setuser] = useState(
        {
          id:'',
          token:'',
          username:'',
          email:'',
          points:'',
          avatar:'',
        }
    );
 

..省略号...

想问问,哪个方案更好, 应该怎么判断自己用哪个方案呢?

如果用第一种,字段太多了, 会不会用hox 会导致性能低下, 浪费很多内容呢?

谢谢

要怎么把请求返回的数据 用hox存起来?

使用场景

用户登录之后,全局保存用户信息

疑问

之前都是用dva,请求到用户信息之后,可以在effects中使用payload将用户信息存到redux以供全局使用。hox不能带参数,那我要保存接口返回的信息要怎么做?

尝试

  1. 我试着在createModel中暴露一个方法,接收一个参数
import { useState } from 'react';
import { createModel } from 'hox';

function useTopMenuModel() {
  const [menuList, setMenuList] = useState([]);
  const saveMenuList = payload => setMenuList(payload);

  return { menuList, saveMenuList };
}

export default createModel(useTopMenuModel);
  1. 然后在页面中调用
import useTopMenuModel from '@/hox/menuModel';

const modelData = useTopMenuModel();
console.log(modelData);
modelData.saveMenuList(menuList); // menuList是接口返回的信息

这么做可以把menuList存起来,但是会报错

第一次用hooks,在网上也没找到相关问题,劳烦大佬们答疑下,谢谢~

createModel 建议允许传递初值,增强Model的逻辑复用性

比如 toggle类的model 应当具有普遍性,建议扩展 createModel(customHook,defaultValue) API 已便更灵活的使用


import { createModel } from 'hox';
import { useBoolean } from '@umijs/hooks';


function useToggle(defValue) {
  const { state, toggle, setTrue, setFalse } = useBoolean(defValue ?? true);
  const set = (bool) => (bool ? setTrue : setFalse)
  return { state, toggle, set }
}


export const useSiderMenuToggleModel = createModel(useToggle);
export const useTabsToggleModel = createModel(useToggle);

建议修改API以支持初值设置:

export const useSiderMenuToggleModel = createModel(useToggle,false);
export const useTabsToggleModel = createModel(useToggle,true);

withModel 可以支持多个model,同时支持 model 重命名

withModel

  • TODO 支持多个 model
    参数可以支持数组 和 字符串

  • TODO 支持重命名 model,this.props.model 如果本来组件就有这个名字了,就有问题了,需要支持重命名。
    支持接收函数,函数的参数为所有的 model 数据,类似 react-redux {[key]: modelMap[key].data}

hox和plugin-model疑惑

请问hox和@umijs/plugin-model 功能是不是有点重复?我们想使用简单的数据流取代dva,应该是用hox还是plugin-model呢?麻烦大神给点建议~~

useEffect里【同步】更新state无法正常获取到更新?

在useEffect里使用setModel
直接调用时,外部通过这个hook useModel拿不到更新后的model,貌似没有检测到更新,但是内部model确实变了
使用异步,价格setTimeout之后外部就可以正常拿到更新后的model

示例如下:

import { createModel } from 'hox';
import { useEffect, useState } from 'react';

function useModel() {
    const [model, setModel] = useState(null)
    
    useEffect(() => {
        // 这个外部拿不到model更新
        setModel({ a: 1 });
        // 这个外部可以拿到更新
        setTimeout(()=>{
            setModel({ a: 1 });
        }, 0);
    }, []);

    return [model, setModel]
}

export default createModel(useModel);

复杂类型对象的订阅更新机制

如果更新状态时,不改变复杂类型对象地址,则不会引起订阅这个hook的其他组件的更新,是这样的吗

const useAccess = () => {
const [access, setAccess] = useState({
test: true,
adminSubmit: false
});

// 已存在则覆盖。
const updateAccess = (newAccess) => {
setAccess(_.merge(access, newAccess)) // 如果不改变复杂类型对象地址,则不会引起引用这个状态的更新
}

return { access, updateAccess }
};

export default createModel(useAccess);

微信小程序框架Remax中无法使用

Uncaught TypeError: Cannot read property 'createElement' of undefined at Object.createModel (create-model.js? [sm]:70) at index.js? [sm]:39 at require (VM1309 WAService.js:19) at VM1309 WAService.js:19 at index.js? [sm]:12 at require (VM1309 WAService.js:19) at VM1309 WAService.js:19 at index.js? [sm]:11 at require (VM1309 WAService.js:19) at <anonymous>:8:7
应该是因为小程序没有createElement这个方法导致的。

与umi 的 useRequest 一起使用时,捕获不到全局错误

当和umi的useRequest一起使用时,我在组件最外层配置了UseAPIProvider的onError属性,当接口500时,不执行onError的回调函数

// useUser.js
const useUser = () => {
  const [userInfo, setUser] = useState();
  const { run, loading } = useRequest('/api/user', {
    manual: true
  });

  useEffect(() => {
    run().then(user => setUser(user));
  }, []);

  return { userInfo, loading, run };
};

export default createModel(useUser);
// App.js
import { UseAPIProvider } from '@umijs/use-request';
const App = () => {
return (
     <UseAPIProvider
        value={{
          onError: (e) => console.log(e)
        }}
    >
      <Children />
    </UseAPIProvider>
)
}
// Children.js

const Chidren = () => {
     const user = useUser()
     return <h1>Chidren</h1>
}

我直接使用useRequest是可以的捕获到500错误的

TypeScript 支持

为了支持 TypeScript 的类型推导,同时保持对 JavaScript 用户的使用简单性,需要对 API 做一些调整

hook的单例性质让人费解

通过createModel包装之后的自定义hook,它竟然是个单例,更新一个使用该hook的组件,其他使用该hook的组件也会同步更新。这很奇怪,源码主要逻辑基本读懂了,只是不知道为什么这样设计,自定义hook存在的意义不就是复用逻辑吗?做成单例就很奇怪。
就像下面这样,我仅仅点击最上面的增加按钮,下面的数字同步更新了,有点违背直觉。
图片

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.