├── .gitignore
├── LICENSE
├── README.md
├── config
├── env.js
├── jest
│ ├── cssTransform.js
│ └── fileTransform.js
├── paths.js
├── polyfills.js
├── webpack.config.dev.js
├── webpack.config.prod.js
└── webpackDevServer.config.js
├── gulpfile.js
├── package-lock.json
├── package.json
├── public
├── assets
│ ├── js
│ │ └── addonvis.js
│ └── svg
│ │ ├── ic_autorenew_black_24px.svg
│ │ └── ic_autorenew_white_24px.svg
├── data
│ └── obama_budget_proposal_2012.list.json
├── favicon.ico
├── img
│ ├── 7992b5cf.web-clipper_05.jpg
│ ├── azure-round-loader.gif
│ ├── b66f5512.web-clipper.png
│ ├── example.gif
│ ├── install.gif
│ └── loading.gif
├── index.html
└── index.ico
├── python
└── .python-version
├── scripts
├── build.js
├── start-mac.js
├── start.js
└── test.js
└── src
├── App.js
├── App.less
├── App.test.js
├── apis
└── apis.js
├── components
├── DanmuDataTable.jsx
└── DanmuVisDc.jsx
├── containers
├── InfoContainer.jsx
└── MyDialogModal.jsx
├── index.js
├── index.less
├── public
├── assets
│ ├── js
│ │ └── addonvis.js
│ └── svg
│ │ ├── ic_autorenew_black_24px.svg
│ │ └── ic_autorenew_white_24px.svg
├── data
│ └── obama_budget_proposal_2012.list.json
├── favicon.ico
├── img
│ ├── 7992b5cf.web-clipper_05.jpg
│ ├── azure-round-loader.gif
│ ├── b66f5512.web-clipper.png
│ ├── example.gif
│ ├── install.gif
│ └── loading.gif
├── index.html
└── index.ico
├── styles
├── MyDialogModal.css
├── bootstrap-sass
│ ├── bootstrap.scss
│ └── bootstrap
│ │ ├── _bootstrap.scss
│ │ ├── _custom.scss
│ │ ├── _customvariables.scss
│ │ └── bootstrap
│ │ ├── _alerts.scss
│ │ ├── _badges.scss
│ │ ├── _breadcrumbs.scss
│ │ ├── _button-groups.scss
│ │ ├── _buttons.scss
│ │ ├── _carousel.scss
│ │ ├── _close.scss
│ │ ├── _code.scss
│ │ ├── _component-animations.scss
│ │ ├── _dropdowns.scss
│ │ ├── _forms.scss
│ │ ├── _glyphicons.scss
│ │ ├── _grid.scss
│ │ ├── _input-groups.scss
│ │ ├── _jumbotron.scss
│ │ ├── _labels.scss
│ │ ├── _list-group.scss
│ │ ├── _media.scss
│ │ ├── _mixins.scss
│ │ ├── _modals.scss
│ │ ├── _navbar.scss
│ │ ├── _navs.scss
│ │ ├── _normalize.scss
│ │ ├── _pager.scss
│ │ ├── _pagination.scss
│ │ ├── _panels.scss
│ │ ├── _popovers.scss
│ │ ├── _print.scss
│ │ ├── _progress-bars.scss
│ │ ├── _responsive-embed.scss
│ │ ├── _responsive-utilities.scss
│ │ ├── _scaffolding.scss
│ │ ├── _tables.scss
│ │ ├── _theme.scss
│ │ ├── _thumbnails.scss
│ │ ├── _tooltip.scss
│ │ ├── _type.scss
│ │ ├── _utilities.scss
│ │ ├── _variables.scss
│ │ ├── _wells.scss
│ │ └── mixins
│ │ ├── _alerts.scss
│ │ ├── _background-variant.scss
│ │ ├── _border-radius.scss
│ │ ├── _buttons.scss
│ │ ├── _center-block.scss
│ │ ├── _clearfix.scss
│ │ ├── _forms.scss
│ │ ├── _gradients.scss
│ │ ├── _grid-framework.scss
│ │ ├── _grid.scss
│ │ ├── _hide-text.scss
│ │ ├── _image.scss
│ │ ├── _labels.scss
│ │ ├── _list-group.scss
│ │ ├── _nav-divider.scss
│ │ ├── _nav-vertical-align.scss
│ │ ├── _opacity.scss
│ │ ├── _pagination.scss
│ │ ├── _panels.scss
│ │ ├── _progress-bar.scss
│ │ ├── _reset-filter.scss
│ │ ├── _reset-text.scss
│ │ ├── _resize.scss
│ │ ├── _responsive-visibility.scss
│ │ ├── _size.scss
│ │ ├── _tab-focus.scss
│ │ ├── _table-row.scss
│ │ ├── _text-emphasis.scss
│ │ ├── _text-overflow.scss
│ │ └── _vendor-prefixes.scss
└── dc.scss
└── utils
├── BiliBili_crc2mid.js
└── utils.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | /public/data/
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 |
26 | /python/venv
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 h12345jack h12345jack@163.com
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [bilibili-Visualization](https://h12345jack.github.io/bilibili-Visualization/)
2 | bilibili视频可视化工具
3 |
4 | ## How to use
5 |
6 |
7 | [bookmarklet](https://h12345jack.github.io/bilibili-Visualization/)
8 |
9 |
10 |
11 | **! currently it works well in chrome 56, firefox 53, safari 10, other browers are not tested. **
12 |
13 | ## Introduction
14 |
15 | 
16 |
17 | 请保证为**HTML5播放器**
18 |
19 | 点击书签一次后,10s内完成可视化的图表,如果失败请点击refresh。
20 |
21 | 主要包括2个时间相关的图表,一些定类变量和数据详表。
22 |
23 | 
24 |
25 | 
26 |
27 |
28 | ## Ideas
29 | ### Bookmakelet
30 |
31 | 为啥不做成chrome插件?
32 |
33 |
34 | 答:希望跨浏览器,插件方面[bilibili-helper](https://github.com/zacyu/bilibili-helper)搞得不错了。
35 |
36 | 现在的项目不是helper的复刻,而是新的idea。解决可视化+概览的功能。
37 |
38 | ### React+Webpack?
39 | 答: 是一种尝试,希望用react的方式来做原来dom做的很多工作。
40 |
41 | ### Features
42 |
43 | 答:
44 | 1. 弹幕分布 ===> 帮助发现最高潮的部分
45 | 2. 弹幕时间 ===> 帮助理解视频弹幕的特点,是隔了一段时间被发现还是一来就火爆
46 | 3. 到处视频弹幕 ===> 导出csv
47 |
48 |
49 |
50 | ## Todolist
51 | - [x] 解决框无法使用的问题=>去掉JQuery,直接用B站的 => 使用antd + webpack
52 | - [x] 避免出现多个vis按钮 => done
53 | - [x] 避免多次点击无效的情况 => done
54 | - [x] 出现错误时button不显示,将错误打印到控制态 => 出错refresh
55 | - [x] 更友好的使用说明 => maybe more friendly
56 | - [x] 反向获取弹幕者id,及个人空间URL => get idea from [
57 | bilibili-search](https://devhub.io/repos/shafferjohn-bilibili-search)
58 | - [ ] 更多的视频相关元数据信息 => doing
59 | - [ ] 双击跳转到指定视频页面位置 => doing
60 |
61 | if you like it, star will help a lot.
62 |
--------------------------------------------------------------------------------
/config/env.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const path = require('path');
5 | const paths = require('./paths');
6 |
7 | // Make sure that including paths.js after env.js will read .env variables.
8 | delete require.cache[require.resolve('./paths')];
9 |
10 | const NODE_ENV = process.env.NODE_ENV;
11 | if (!NODE_ENV) {
12 | throw new Error(
13 | 'The NODE_ENV environment variable is required but was not specified.'
14 | );
15 | }
16 |
17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
18 | var dotenvFiles = [
19 | `${paths.dotenv}.${NODE_ENV}.local`,
20 | `${paths.dotenv}.${NODE_ENV}`,
21 | // Don't include `.env.local` for `test` environment
22 | // since normally you expect tests to produce the same
23 | // results for everyone
24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`,
25 | paths.dotenv,
26 | ].filter(Boolean);
27 |
28 | // Load environment variables from .env* files. Suppress warnings using silent
29 | // if this file is missing. dotenv will never modify any environment variables
30 | // that have already been set.
31 | // https://github.com/motdotla/dotenv
32 | dotenvFiles.forEach(dotenvFile => {
33 | if (fs.existsSync(dotenvFile)) {
34 | require('dotenv').config({
35 | path: dotenvFile,
36 | });
37 | }
38 | });
39 |
40 | // We support resolving modules according to `NODE_PATH`.
41 | // This lets you use absolute paths in imports inside large monorepos:
42 | // https://github.com/facebookincubator/create-react-app/issues/253.
43 | // It works similar to `NODE_PATH` in Node itself:
44 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
45 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
46 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
47 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421
48 | // We also resolve them to make sure all tools using them work consistently.
49 | const appDirectory = fs.realpathSync(process.cwd());
50 | process.env.NODE_PATH = (process.env.NODE_PATH || '')
51 | .split(path.delimiter)
52 | .filter(folder => folder && !path.isAbsolute(folder))
53 | .map(folder => path.resolve(appDirectory, folder))
54 | .join(path.delimiter);
55 |
56 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
57 | // injected into the application via DefinePlugin in Webpack configuration.
58 | const REACT_APP = /^REACT_APP_/i;
59 |
60 | function getClientEnvironment(publicUrl) {
61 | const raw = Object.keys(process.env)
62 | .filter(key => REACT_APP.test(key))
63 | .reduce(
64 | (env, key) => {
65 | env[key] = process.env[key];
66 | return env;
67 | },
68 | {
69 | // Useful for determining whether we’re running in production mode.
70 | // Most importantly, it switches React into the correct mode.
71 | NODE_ENV: process.env.NODE_ENV || 'development',
72 | // Useful for resolving the correct path to static assets in `public`.
73 | // For example,
.
74 | // This should only be used as an escape hatch. Normally you would put
75 | // images into the `src` and `import` them in code to get their paths.
76 | PUBLIC_URL: publicUrl,
77 | }
78 | );
79 | // Stringify all values so we can feed into Webpack DefinePlugin
80 | const stringified = {
81 | 'process.env': Object.keys(raw).reduce(
82 | (env, key) => {
83 | env[key] = JSON.stringify(raw[key]);
84 | return env;
85 | },
86 | {}
87 | ),
88 | };
89 |
90 | return { raw, stringified };
91 | }
92 |
93 | module.exports = getClientEnvironment;
94 |
--------------------------------------------------------------------------------
/config/jest/cssTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // This is a custom Jest transformer turning style imports into empty objects.
4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
5 |
6 | module.exports = {
7 | process() {
8 | return 'module.exports = {};';
9 | },
10 | getCacheKey() {
11 | // The output is always the same.
12 | return 'cssTransform';
13 | },
14 | };
15 |
--------------------------------------------------------------------------------
/config/jest/fileTransform.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 |
5 | // This is a custom Jest transformer turning file imports into filenames.
6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html
7 |
8 | module.exports = {
9 | process(src, filename) {
10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`;
11 | },
12 | };
13 |
--------------------------------------------------------------------------------
/config/paths.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const path = require('path');
4 | const fs = require('fs');
5 | const url = require('url');
6 |
7 | // Make sure any symlinks in the project folder are resolved:
8 | // https://github.com/facebookincubator/create-react-app/issues/637
9 | const appDirectory = fs.realpathSync(process.cwd());
10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
11 |
12 | const envPublicUrl = process.env.PUBLIC_URL;
13 |
14 | function ensureSlash(path, needsSlash) {
15 | const hasSlash = path.endsWith('/');
16 | if (hasSlash && !needsSlash) {
17 | return path.substr(path, path.length - 1);
18 | } else if (!hasSlash && needsSlash) {
19 | return `${path}/`;
20 | } else {
21 | return path;
22 | }
23 | }
24 |
25 | const getPublicUrl = appPackageJson =>
26 | envPublicUrl || require(appPackageJson).homepage;
27 |
28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer
29 | // "public path" at which the app is served.
30 | // Webpack needs to know it to put the right
104 |