├── .gitattributes ├── icon.png ├── assets ├── vizzu_logo.png └── readme.txt ├── docs ├── vizzu_logo.png ├── PyScript-datasum.json ├── bitcoin-datasum.json ├── prysm-datasum.json ├── solana-datasum.json ├── Go_Ethereum-datasum.json ├── vizzu-lib-datasum.json ├── scripts │ ├── nav-anim-record-filter.js │ ├── anim-1000-0100.js │ ├── nav-anim-10xx-01xx.js │ ├── anim-0100-1000.js │ ├── nav-anim-01xx-10xx.js │ ├── nav-anim-10xx-filter-bw.js │ ├── nav-anim-01xx-filter-bw.js │ ├── anim-1011-1001.js │ ├── anim-1001-1011.js │ ├── anim-1000-1001.js │ ├── anim-1011-1010.js │ ├── nav-anim-01xx-filter-fw.js │ ├── nav-anim-10xx-filter-fw.js │ ├── nav-anim-initial.js │ ├── anim-0110-1011.js │ ├── anim-1001-0100.js │ ├── anim-0100-1001.js │ ├── anim-1011-0110.js │ ├── anim-1010-1011.js │ ├── anim-1001-1000.js │ ├── anim-initial.js │ ├── anim-1010-0110.js │ ├── uiLogic-main.js │ ├── anim-0110-1010.js │ ├── anim-0100-0110.js │ ├── anim-0110-0100.js │ ├── anim-1010-1000.js │ ├── anim-1000-1010.js │ ├── uiLogic-controls.js │ └── uiLogic-animations.js ├── main.css ├── vscodeapi.js ├── index.html └── PyScript-data.json ├── images ├── guide_5_use.gif ├── guide_1_start.gif ├── guide_4_navig.gif ├── guide_2_checkbox.gif └── guide_3_dropdown.gif ├── .gitignore ├── .vscode ├── extensions.json ├── tasks.json ├── settings.json └── launch.json ├── media ├── scripts │ ├── nav-anim-record-filter.js │ ├── anim-1000-0100.js │ ├── nav-anim-10xx-01xx.js │ ├── anim-0100-1000.js │ ├── nav-anim-01xx-10xx.js │ ├── nav-anim-10xx-filter-bw.js │ ├── nav-anim-01xx-filter-bw.js │ ├── anim-1011-1001.js │ ├── anim-1001-1011.js │ ├── anim-1000-1001.js │ ├── anim-1011-1010.js │ ├── nav-anim-01xx-filter-fw.js │ ├── nav-anim-10xx-filter-fw.js │ ├── nav-anim-initial.js │ ├── anim-0110-1011.js │ ├── anim-1001-0100.js │ ├── anim-0100-1001.js │ ├── anim-1011-0110.js │ ├── anim-1010-1011.js │ ├── anim-1001-1000.js │ ├── anim-initial.js │ ├── anim-1010-0110.js │ ├── uiLogic-main.js │ ├── anim-0110-1010.js │ ├── anim-0100-0110.js │ ├── anim-0110-0100.js │ ├── anim-1010-1000.js │ ├── anim-1000-1010.js │ ├── uiLogic-controls.js │ └── uiLogic-animations.js ├── main.css └── main.html ├── src ├── utilities │ └── geturi.ts ├── data │ ├── vscc_result.ts │ ├── vscc_datasource.ts │ └── vscc_dataprep.ts ├── panels │ ├── pagegen.ts │ └── ccvizzupanel.ts └── extension.ts ├── tsconfig.json ├── LICENSE.txt ├── README.md └── package.json /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/icon.png -------------------------------------------------------------------------------- /assets/vizzu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/assets/vizzu_logo.png -------------------------------------------------------------------------------- /docs/vizzu_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/docs/vizzu_logo.png -------------------------------------------------------------------------------- /images/guide_5_use.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/images/guide_5_use.gif -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | .vscode-test/ 4 | .VSCodeCounter/ 5 | *.vsix 6 | package-lock* 7 | -------------------------------------------------------------------------------- /images/guide_1_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/images/guide_1_start.gif -------------------------------------------------------------------------------- /images/guide_4_navig.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/images/guide_4_navig.gif -------------------------------------------------------------------------------- /images/guide_2_checkbox.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/images/guide_2_checkbox.gif -------------------------------------------------------------------------------- /images/guide_3_dropdown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vizzuhq/codeviz/HEAD/images/guide_3_dropdown.gif -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "undefined_publisher.codeviz" 4 | ] 5 | } -------------------------------------------------------------------------------- /docs/PyScript-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"/vizzu/PyScript","date":"2022-06-22_10-00-48","files":139,"lines":14090,"commentCount":442,"blankCount":1879,"codeCount":11769,"depth":5} 2 | -------------------------------------------------------------------------------- /docs/bitcoin-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"/vizzu/bitcoin/bitcoin","date":"2022-06-22_10-22-05","files":2054,"lines":632307,"commentCount":52343,"blankCount":54538,"codeCount":525426,"depth":7} -------------------------------------------------------------------------------- /docs/prysm-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"/vizzu/prysmaticlabs/prysm","date":"2022-06-22_10-29-25","files":2178,"lines":415658,"commentCount":27197,"blankCount":44628,"codeCount":343833,"depth":7} -------------------------------------------------------------------------------- /docs/solana-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"/vizzu/solana-labs/solana","date":"2022-06-22_10-25-59","files":2520,"lines":705648,"commentCount":48153,"blankCount":56451,"codeCount":601044,"depth":6} -------------------------------------------------------------------------------- /docs/Go_Ethereum-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"/vizzu/ethereum/go-ethereum","date":"2022-06-22_10-17-33","files":1492,"lines":649434,"commentCount":63768,"blankCount":37461,"codeCount":548205,"depth":7} -------------------------------------------------------------------------------- /docs/vizzu-lib-datasum.json: -------------------------------------------------------------------------------- 1 | {"rootDir":"Source: vizzu/vizzu-lib","date":"Date: 2022-04-14 15:41:14","files":825,"lines":"69 938","commentCount":925,"blankCount":8312,"codeCount":60701,"depth":8} -------------------------------------------------------------------------------- /docs/scripts/nav-anim-record-filter.js: -------------------------------------------------------------------------------- 1 | function nav_anim_record_filter(chart, filterFn) { 2 | return chart.animate({ 3 | data: { 4 | filter: record => filterFn(record) 5 | } 6 | }, 7 | { duration: 1 }); 8 | } 9 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-record-filter.js: -------------------------------------------------------------------------------- 1 | function nav_anim_record_filter(chart, filterFn) { 2 | return chart.animate({ 3 | data: { 4 | filter: record => filterFn(record) 5 | } 6 | }, 7 | { duration: 1 }); 8 | } 9 | -------------------------------------------------------------------------------- /src/utilities/geturi.ts: -------------------------------------------------------------------------------- 1 | import { Uri, Webview } from "vscode"; 2 | 3 | export function getUri(webview: Webview, extensionUri: Uri, pathList: string[]) { 4 | return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList)); 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | { 5 | "type": "npm", 6 | "script": "watch", 7 | "problemMatcher": "$tsc-watch", 8 | "isBackground": true, 9 | "presentation": { 10 | "reveal": "never" 11 | }, 12 | "group": { 13 | "kind": "build", 14 | "isDefault": true 15 | } 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "out": false 4 | }, 5 | "search.exclude": { 6 | "out": true 7 | }, 8 | "typescript.tsc.autoDetect": "off", 9 | "editor.defaultFormatter": "esbenp.prettier-vscode", 10 | "[typescript]": { 11 | "editor.defaultFormatter": "esbenp.prettier-vscode" 12 | } 13 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6", 8 | "dom" 9 | ], 10 | "sourceMap": true, 11 | "rootDir": "src", 12 | "strict": true /* enable all strict type-checking options */ 13 | /* Additional Checks */ 14 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 15 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 16 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 17 | }, 18 | "exclude": [ 19 | "node_modules", 20 | ".vscode-test" 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /docs/scripts/anim-1000-0100.js: -------------------------------------------------------------------------------- 1 | function anim_1000_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: null }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | xAxis: { label: { angle: 0 } } 19 | } 20 | } 21 | }, 22 | { duration: 2 } 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /media/scripts/anim-1000-0100.js: -------------------------------------------------------------------------------- 1 | function anim_1000_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: null }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | xAxis: { label: { angle: 0 } } 19 | } 20 | } 21 | }, 22 | { duration: 2 } 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Run Extension", 6 | "type": "extensionHost", 7 | "request": "launch", 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}" 10 | ], 11 | "outFiles": [ 12 | "${workspaceFolder}/out/**/*.js" 13 | ], 14 | "preLaunchTask": "${defaultBuildTask}" 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceFolder}", 22 | "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" 23 | ], 24 | "outFiles": [ 25 | "${workspaceFolder}/out/test/**/*.js" 26 | ], 27 | "preLaunchTask": "${defaultBuildTask}" 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-10xx-01xx.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_01xx(chart, dirLevel) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Folder level ' + dirLevel] }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | title: null, 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | marker: { label: { position: 'top' } }, 17 | xAxis: { label: { angle: -0.7 } } 18 | }, 19 | title: { 20 | paddingTop: null, 21 | paddingBottom: null 22 | } 23 | } 24 | }, 25 | { duration: 2 } 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /docs/scripts/anim-0100-1000.js: -------------------------------------------------------------------------------- 1 | function anim_0100_1000(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: null }, 7 | x: { set: ['Line count'] }, 8 | color: { set: null }, 9 | label: { set: ['Line count'] }, 10 | }, 11 | //1 code 1 12 | }, 13 | style: { 14 | legend: { paddingLeft: '5.789473684' }, 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | yAxis: { label: { paddingRight: '1.2em' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 2 } 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-10xx-01xx.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_01xx(chart, dirLevel) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Folder level ' + dirLevel] }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | title: null, 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | marker: { label: { position: 'top' } }, 17 | xAxis: { label: { angle: -0.7 } } 18 | }, 19 | title: { 20 | paddingTop: null, 21 | paddingBottom: null 22 | } 23 | } 24 | }, 25 | { duration: 2 } 26 | ); 27 | } 28 | -------------------------------------------------------------------------------- /media/scripts/anim-0100-1000.js: -------------------------------------------------------------------------------- 1 | function anim_0100_1000(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: null }, 7 | x: { set: ['Line count'] }, 8 | color: { set: null }, 9 | label: { set: ['Line count'] }, 10 | }, 11 | //1 code 1 12 | }, 13 | style: { 14 | legend: { paddingLeft: '5.789473684' }, 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | yAxis: { label: { paddingRight: '1.2em' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 2 } 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-01xx-10xx.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_10xx(chart, dirLevel) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Folder level ' + dirLevel] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: null }, 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null, 13 | title: null 14 | }, 15 | style: { 16 | plot: { 17 | marker: { label: { position: 'right' } }, 18 | xAxis: { label: { angle: 0 } } 19 | }, 20 | title: { 21 | paddingTop: null, 22 | paddingBottom: null 23 | } 24 | } 25 | }, 26 | { duration: 2 } 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-01xx-10xx.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_10xx(chart, dirLevel) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Folder level ' + dirLevel] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: null }, 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null, 13 | title: null 14 | }, 15 | style: { 16 | plot: { 17 | marker: { label: { position: 'right' } }, 18 | xAxis: { label: { angle: 0 } } 19 | }, 20 | title: { 21 | paddingTop: null, 22 | paddingBottom: null 23 | } 24 | } 25 | }, 26 | { duration: 2 } 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /media/main.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-family: roboto; 3 | text-align: center; 4 | padding-top: 10px; 5 | color: rgb(120, 120, 120); 6 | font-size: 200% 7 | } 8 | 9 | .info { 10 | font-family: roboto; 11 | text-align: center; 12 | color: rgb(130, 130, 130); 13 | font-size: 100% 14 | } 15 | 16 | .info-item { 17 | font-family: roboto; 18 | font-size: 100%; 19 | } 20 | 21 | .info-value { 22 | font-family: roboto; 23 | font-size: 130%; 24 | color: var(--vscode-focusBorder); 25 | } 26 | 27 | .vizzu-div { 28 | display: grid; 29 | grid-template-columns: 45.0000% 55.0000%; 30 | grid-template-rows: auto; 31 | width: 100%; 32 | } 33 | 34 | .control-div { 35 | display: flex; 36 | justify-content: center; 37 | width: 100%; 38 | grid-template-rows: auto auto; 39 | } 40 | 41 | .click-label { 42 | border: none; 43 | background-color: transparent; 44 | color: inherit; 45 | } 46 | 47 | .click-label:disabled { 48 | border: none; 49 | background-color: transparent; 50 | color: rgb(97, 97, 97); 51 | } 52 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2023 Vizzu Inc. 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. 22 | -------------------------------------------------------------------------------- /src/data/vscc_result.ts: -------------------------------------------------------------------------------- 1 | import { Uri } from "vscode"; 2 | import { VSCCDataSource } from "./vscc_datasource"; 3 | import { VSCCDataPrep } from "./vscc_dataprep"; 4 | 5 | export class Result { 6 | public code: number = 0; 7 | public comment: number = 0; 8 | public blank: number = 0; 9 | public uri: Uri = Uri.file(''); 10 | public filename: string = ''; 11 | public language: string = ''; 12 | }; 13 | 14 | export class Summary { 15 | public rootDir: String = ''; 16 | public date: String = ''; 17 | public files: number = 0; 18 | public lines: number = 0; 19 | public commentCount: number = 0; 20 | public blankCount: number = 0; 21 | public codeCount: number = 0; 22 | public depth: number = 0; 23 | 24 | public constructor(source: VSCCDataSource, data: VSCCDataPrep) { 25 | this.rootDir = source.folder; 26 | this.date = source.date; 27 | this.files = data.fileCount; 28 | this.lines = data.codeLinesCount + data.commentLinesCount + data.blankLinesCount; 29 | this.codeCount = data.codeLinesCount; 30 | this.commentCount = data.commentLinesCount; 31 | this.blankCount = data.blankLinesCount; 32 | this.depth = data.dirStructureDepth; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /docs/main.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-family: roboto; 3 | text-align: center; 4 | padding-top: 10px; 5 | color: rgb(120, 120, 120); 6 | font-size: 200% 7 | } 8 | 9 | .info { 10 | font-family: roboto; 11 | text-align: center; 12 | color: rgb(130, 130, 130); 13 | font-size: 100% 14 | } 15 | 16 | .info-item { 17 | font-family: roboto; 18 | font-size: 100%; 19 | } 20 | 21 | .info-value { 22 | font-family: roboto; 23 | font-size: 130%; 24 | color: var(--vscode-focusBorder); 25 | } 26 | 27 | .vizzu-div { 28 | display: grid; 29 | grid-template-columns: 45.0000% 55.0000%; 30 | grid-template-rows: auto; 31 | width: 100%; 32 | } 33 | 34 | .control-div { 35 | display: flex; 36 | justify-content: center; 37 | width: 100%; 38 | grid-template-rows: auto auto; 39 | } 40 | 41 | .click-label { 42 | border: none; 43 | background-color: transparent; 44 | color: inherit; 45 | } 46 | 47 | .click-label:disabled { 48 | border: none; 49 | background-color: transparent; 50 | color: rgb(97, 97, 97); 51 | } 52 | 53 | .link-button { 54 | background: none!important; 55 | border: none; 56 | padding: 0!important; 57 | color: #069; 58 | text-decoration: underline; 59 | cursor: pointer; 60 | } -------------------------------------------------------------------------------- /docs/scripts/nav-anim-10xx-filter-bw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_filter_bw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel + 1); 4 | let prevDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: [crDir] }, 10 | x: { set: ['Line count'] }, 11 | label: { set: ['Line count'] } 12 | } 13 | }}, 14 | { duration: 0.3 } 15 | ) 16 | 17 | .then(chart => chart.animate({ 18 | config: { 19 | channels: { 20 | y: { set: null }, 21 | x: { set: ['Line count', crDir] } 22 | } 23 | } 24 | }, 25 | { duration: 1 } 26 | )) 27 | 28 | .then(chart => chart.animate({ 29 | config: { 30 | channels: { 31 | y: { set: [prevDir] }, 32 | x: { set: ['Line count'] } 33 | } 34 | } 35 | }, 36 | { duration: 0.3 } 37 | )) 38 | 39 | .then(chart => chart.animate({ 40 | config: { 41 | channels: { 42 | y: { set: [prevDir] }, 43 | x: { set: ['Line count'] }, 44 | label: { set: ['Line count'] } 45 | }, 46 | title: null 47 | } 48 | }, 49 | { duration: 0.3 } 50 | )); 51 | } 52 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-10xx-filter-bw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_filter_bw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel + 1); 4 | let prevDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: [crDir] }, 10 | x: { set: ['Line count'] }, 11 | label: { set: ['Line count'] } 12 | } 13 | }}, 14 | { duration: 0.3 } 15 | ) 16 | 17 | .then(chart => chart.animate({ 18 | config: { 19 | channels: { 20 | y: { set: null }, 21 | x: { set: ['Line count', crDir] } 22 | } 23 | } 24 | }, 25 | { duration: 1 } 26 | )) 27 | 28 | .then(chart => chart.animate({ 29 | config: { 30 | channels: { 31 | y: { set: [prevDir] }, 32 | x: { set: ['Line count'] } 33 | } 34 | } 35 | }, 36 | { duration: 0.3 } 37 | )) 38 | 39 | .then(chart => chart.animate({ 40 | config: { 41 | channels: { 42 | y: { set: [prevDir] }, 43 | x: { set: ['Line count'] }, 44 | label: { set: ['Line count'] } 45 | }, 46 | title: null 47 | } 48 | }, 49 | { duration: 0.3 } 50 | )); 51 | } 52 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-01xx-filter-bw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_filter_bw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel + 1); 4 | let prevDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: ['$count'] }, 10 | x: { set: [crDir] }, 11 | label: { set: ['$count'] } 12 | }, 13 | legend: null 14 | }}, 15 | { duration: 0.3 } 16 | ) 17 | 18 | .then(chart => chart.animate({ 19 | config: { 20 | channels: { 21 | y: { set: ['$count', crDir ] }, 22 | x: { set: null } 23 | } 24 | } 25 | }, 26 | { duration: 1 } 27 | )) 28 | 29 | .then(chart => chart.animate({ 30 | config: { 31 | channels: { 32 | y: { set: ['$count'] }, 33 | x: { set: prevDir } 34 | } 35 | } 36 | }, 37 | { duration: 0.3 } 38 | )) 39 | 40 | .then(chart => chart.animate({ 41 | config: { 42 | channels: { 43 | y: { set: ['$count'] }, 44 | x: { set: [prevDir] }, 45 | label: { set: ['$count'] } 46 | }, 47 | title: null 48 | } 49 | }, 50 | { duration: 0.3 } 51 | )); 52 | } 53 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-01xx-filter-bw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_filter_bw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel + 1); 4 | let prevDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: ['$count'] }, 10 | x: { set: [crDir] }, 11 | label: { set: ['$count'] } 12 | }, 13 | legend: null 14 | }}, 15 | { duration: 0.3 } 16 | ) 17 | 18 | .then(chart => chart.animate({ 19 | config: { 20 | channels: { 21 | y: { set: ['$count', crDir ] }, 22 | x: { set: null } 23 | } 24 | } 25 | }, 26 | { duration: 1 } 27 | )) 28 | 29 | .then(chart => chart.animate({ 30 | config: { 31 | channels: { 32 | y: { set: ['$count'] }, 33 | x: { set: prevDir } 34 | } 35 | } 36 | }, 37 | { duration: 0.3 } 38 | )) 39 | 40 | .then(chart => chart.animate({ 41 | config: { 42 | channels: { 43 | y: { set: ['$count'] }, 44 | x: { set: [prevDir] }, 45 | label: { set: ['$count'] } 46 | }, 47 | title: null 48 | } 49 | }, 50 | { duration: 0.3 } 51 | )); 52 | } 53 | -------------------------------------------------------------------------------- /src/data/vscc_datasource.ts: -------------------------------------------------------------------------------- 1 | import { Uri } from "vscode"; 2 | 3 | export class VSCCDataSource { 4 | public data: object = Object; 5 | public folder: String = ''; 6 | public date: String = ''; 7 | private _dataFolderUri: Uri; 8 | 9 | public constructor(wsUri: Uri, targetDir: Uri) { 10 | this._dataFolderUri = Uri.joinPath(wsUri, '.VSCodeCounter');; 11 | this._selectDataSourceFolder(wsUri); 12 | this._readDataSource(); 13 | } 14 | 15 | private _selectDataSourceFolder(wsUri: Uri) { 16 | let result: {date: String, path: String}[] = []; 17 | const fs = require('fs'); 18 | const dirPath = fs.readdirSync(this._dataFolderUri.fsPath); 19 | dirPath.map((item: String) => { 20 | let path = Uri.joinPath(this._dataFolderUri, item.valueOf()); 21 | result.push({date: item, path: path.fsPath}); 22 | }); 23 | if (result.length) { 24 | result.sort(); 25 | this.folder = wsUri.path; 26 | this.date = result[result.length - 1].date; 27 | let path = result[result.length - 1].path.valueOf(); 28 | this._dataFolderUri = Uri.file(path.valueOf()); 29 | } 30 | } 31 | 32 | private _readDataSource() { 33 | if (this._dataFolderUri == undefined) 34 | return; 35 | const fs = require('fs'); 36 | let path = Uri.joinPath(this._dataFolderUri, "results.json").fsPath; 37 | const text = fs.readFileSync(path, {encoding:'utf8', flag:'r'}); 38 | this.data = JSON.parse(text); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /docs/scripts/anim-1011-1001.js: -------------------------------------------------------------------------------- 1 | function anim_1011_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: ['Language'] } 9 | }, 10 | // '8 code + types + Files 2', 11 | sort: 'none', 12 | legend: 'color', 13 | reverse: true, 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '0em', 18 | yAxis: { label: { color:'#12345600' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.1 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['Language', 'File name'] }, 30 | x: { set: ['Line count'] }, 31 | color: { detach: ['Language'] }, 32 | label: { set: null } 33 | }, 34 | // '7 code + Files 1', 35 | sort: 'byValue', 36 | legend: null, 37 | reverse: false, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | yAxis: { label: { color:'#12345600' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 2 } 48 | )); 49 | } 50 | -------------------------------------------------------------------------------- /media/scripts/anim-1011-1001.js: -------------------------------------------------------------------------------- 1 | function anim_1011_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: ['Language'] } 9 | }, 10 | // '8 code + types + Files 2', 11 | sort: 'none', 12 | legend: 'color', 13 | reverse: true, 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '0em', 18 | yAxis: { label: { color:'#12345600' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.1 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['Language', 'File name'] }, 30 | x: { set: ['Line count'] }, 31 | color: { detach: ['Language'] }, 32 | label: { set: null } 33 | }, 34 | // '7 code + Files 1', 35 | sort: 'byValue', 36 | legend: null, 37 | reverse: false, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | yAxis: { label: { color:'#12345600' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 2 } 48 | )); 49 | } 50 | -------------------------------------------------------------------------------- /docs/scripts/anim-1001-1011.js: -------------------------------------------------------------------------------- 1 | function anim_1001_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { detach: ['Language'] }, 9 | label: { set: null } 10 | }, 11 | // '7 code + Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['Language', 'File name'] }, 31 | x: { set: ['Line count'] }, 32 | color: { set: ['Language'] } 33 | }, 34 | // '8 code + types + Files 2', 35 | sort: 'none', 36 | legend: 'color', 37 | reverse: true, 38 | }, 39 | style: { 40 | legend: { paddingRight: '0' }, 41 | plot: { 42 | paddingLeft: '0em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )); 50 | } 51 | -------------------------------------------------------------------------------- /media/scripts/anim-1001-1011.js: -------------------------------------------------------------------------------- 1 | function anim_1001_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { detach: ['Language'] }, 9 | label: { set: null } 10 | }, 11 | // '7 code + Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['Language', 'File name'] }, 31 | x: { set: ['Line count'] }, 32 | color: { set: ['Language'] } 33 | }, 34 | // '8 code + types + Files 2', 35 | sort: 'none', 36 | legend: 'color', 37 | reverse: true, 38 | }, 39 | style: { 40 | legend: { paddingRight: '0' }, 41 | plot: { 42 | paddingLeft: '0em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )); 50 | } 51 | -------------------------------------------------------------------------------- /docs/scripts/anim-1000-1001.js: -------------------------------------------------------------------------------- 1 | function anim_1000_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: null }, 7 | x: { set: ['Line count', 'File name'] }, 8 | color: { set: null }, 9 | label: { set: null }, 10 | }, 11 | title: null, //1 code1 12 | sort: 'byValue' 13 | }, 14 | style: { 15 | legend: { paddingLeft: '5.789473684' }, 16 | plot: { 17 | paddingLeft: '9em', 18 | marker: { label: { position: 'center' } }, 19 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.5 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['File name'] }, 31 | x: { set: ['Line count'] }, 32 | label: { set: null }, 33 | color: { detach: ['Language'] } 34 | }, 35 | // '7 code+ Files 1', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: false, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )); 50 | } 51 | -------------------------------------------------------------------------------- /media/scripts/anim-1000-1001.js: -------------------------------------------------------------------------------- 1 | function anim_1000_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: null }, 7 | x: { set: ['Line count', 'File name'] }, 8 | color: { set: null }, 9 | label: { set: null }, 10 | }, 11 | title: null, //1 code1 12 | sort: 'byValue' 13 | }, 14 | style: { 15 | legend: { paddingLeft: '5.789473684' }, 16 | plot: { 17 | paddingLeft: '9em', 18 | marker: { label: { position: 'center' } }, 19 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.5 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['File name'] }, 31 | x: { set: ['Line count'] }, 32 | label: { set: null }, 33 | color: { detach: ['Language'] } 34 | }, 35 | // '7 code+ Files 1', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: false, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )); 50 | } 51 | -------------------------------------------------------------------------------- /docs/scripts/anim-1011-1010.js: -------------------------------------------------------------------------------- 1 | function anim_1011_1010(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count', 'File name'] }, 8 | color: 'Language', 9 | label: null 10 | }, 11 | // '5 code + types 3' 12 | legend: null, 13 | reverse: false, 14 | sort: 'byValue' 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color: '#12345600', paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['Language'] }, 31 | x: { set: ['Line count'] }, 32 | color: 'Language', 33 | label: { set: ['Line count'] }, 34 | }, 35 | // '4 code + types 2', 36 | legend: null, 37 | reverse: false, 38 | sort: 'byValue' 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | marker: { label: { position: 'right' } }, 44 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 45 | xAxis: { label: { angle: 0 } } 46 | } 47 | } 48 | }, 49 | { duration: 0.5 } 50 | )); 51 | } 52 | -------------------------------------------------------------------------------- /media/scripts/anim-1011-1010.js: -------------------------------------------------------------------------------- 1 | function anim_1011_1010(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count', 'File name'] }, 8 | color: 'Language', 9 | label: null 10 | }, 11 | // '5 code + types 3' 12 | legend: null, 13 | reverse: false, 14 | sort: 'byValue' 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color: '#12345600', paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['Language'] }, 31 | x: { set: ['Line count'] }, 32 | color: 'Language', 33 | label: { set: ['Line count'] }, 34 | }, 35 | // '4 code + types 2', 36 | legend: null, 37 | reverse: false, 38 | sort: 'byValue' 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | marker: { label: { position: 'right' } }, 44 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 45 | xAxis: { label: { angle: 0 } } 46 | } 47 | } 48 | }, 49 | { duration: 0.5 } 50 | )); 51 | } 52 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-01xx-filter-fw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_filter_fw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel - 1); 4 | let nextDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: ['$count', nextDir] }, 10 | x: { set: null }, 11 | color: { set: null }, 12 | label: { set: ['$count'] } 13 | }, 14 | legend: null 15 | }, 16 | style: { 17 | plot: { 18 | marker: { label: { position: 'top' } }, 19 | xAxis: { label: { angle: -0.7 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.3 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['$count'] }, 30 | x: { set: [nextDir] } 31 | } 32 | }, 33 | style: { 34 | plot: { 35 | marker: { label: { position: 'top' } }, 36 | xAxis: { label: { angle: -0.7 } } 37 | } 38 | } 39 | }, 40 | { duration: 0.6 } 41 | )) 42 | 43 | .then(chart => chart.animate({ 44 | config: { 45 | channels: { 46 | y: { set: ['$count'] }, 47 | x: { set: [nextDir] }, 48 | label: { set: ['$count'] } 49 | }, 50 | title: null 51 | }, 52 | style: { 53 | plot: { 54 | marker: { label: { position: 'top' } }, 55 | xAxis: { label: { angle: -0.7 } } 56 | } 57 | } 58 | }, 59 | { duration: 0.3 } 60 | )); 61 | } 62 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-01xx-filter-fw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_01xx_filter_fw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel - 1); 4 | let nextDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: ['$count', nextDir] }, 10 | x: { set: null }, 11 | color: { set: null }, 12 | label: { set: ['$count'] } 13 | }, 14 | legend: null 15 | }, 16 | style: { 17 | plot: { 18 | marker: { label: { position: 'top' } }, 19 | xAxis: { label: { angle: -0.7 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.3 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['$count'] }, 30 | x: { set: [nextDir] } 31 | } 32 | }, 33 | style: { 34 | plot: { 35 | marker: { label: { position: 'top' } }, 36 | xAxis: { label: { angle: -0.7 } } 37 | } 38 | } 39 | }, 40 | { duration: 0.6 } 41 | )) 42 | 43 | .then(chart => chart.animate({ 44 | config: { 45 | channels: { 46 | y: { set: ['$count'] }, 47 | x: { set: [nextDir] }, 48 | label: { set: ['$count'] } 49 | }, 50 | title: null 51 | }, 52 | style: { 53 | plot: { 54 | marker: { label: { position: 'top' } }, 55 | xAxis: { label: { angle: -0.7 } } 56 | } 57 | } 58 | }, 59 | { duration: 0.3 } 60 | )); 61 | } 62 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-10xx-filter-fw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_filter_fw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel - 1); 4 | let nextDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: null }, 10 | x: { set: ['Line count', nextDir] }, 11 | color: { set: null }, 12 | label: { set: ['Line count'] } 13 | }, 14 | legend: null 15 | }, 16 | style: { 17 | plot: { 18 | marker: { label: { position: 'right' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.3 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: [nextDir] }, 30 | x: { set: ['Line count'] } 31 | } 32 | }, 33 | style: { 34 | plot: { 35 | marker: { label: { position: 'right' } }, 36 | xAxis: { label: { angle: 0 } } 37 | } 38 | } 39 | }, 40 | { duration: 0.6 } 41 | )) 42 | 43 | .then(chart => chart.animate({ 44 | config: { 45 | channels: { 46 | y: { set: [nextDir] }, 47 | x: { set: ['Line count'] }, 48 | label: { set: ['Line count'] } 49 | }, 50 | title: null 51 | }, 52 | style: { 53 | plot: { 54 | marker: { label: { position: 'right' } }, 55 | xAxis: { label: { angle: 0 } } 56 | } 57 | } 58 | }, 59 | { duration: 0.3 } 60 | )); 61 | } 62 | -------------------------------------------------------------------------------- /media/scripts/nav-anim-10xx-filter-fw.js: -------------------------------------------------------------------------------- 1 | function nav_anim_10xx_filter_fw(chart, dirLevel) { 2 | 3 | let crDir = 'Folder level ' + (dirLevel - 1); 4 | let nextDir = 'Folder level ' + dirLevel; 5 | 6 | return chart.animate({ 7 | config: { 8 | channels: { 9 | y: { set: null }, 10 | x: { set: ['Line count', nextDir] }, 11 | color: { set: null }, 12 | label: { set: ['Line count'] } 13 | }, 14 | legend: null 15 | }, 16 | style: { 17 | plot: { 18 | marker: { label: { position: 'right' } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.3 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: [nextDir] }, 30 | x: { set: ['Line count'] } 31 | } 32 | }, 33 | style: { 34 | plot: { 35 | marker: { label: { position: 'right' } }, 36 | xAxis: { label: { angle: 0 } } 37 | } 38 | } 39 | }, 40 | { duration: 0.6 } 41 | )) 42 | 43 | .then(chart => chart.animate({ 44 | config: { 45 | channels: { 46 | y: { set: [nextDir] }, 47 | x: { set: ['Line count'] }, 48 | label: { set: ['Line count'] } 49 | }, 50 | title: null 51 | }, 52 | style: { 53 | plot: { 54 | marker: { label: { position: 'right' } }, 55 | xAxis: { label: { angle: 0 } } 56 | } 57 | } 58 | }, 59 | { duration: 0.3 } 60 | )); 61 | } 62 | -------------------------------------------------------------------------------- /docs/scripts/nav-anim-initial.js: -------------------------------------------------------------------------------- 1 | 2 | function nav_anim_init(chart) { 3 | 4 | return chart.animate({ 5 | config: { 6 | channels: { 7 | y: { set: ['Folder level 0'], range: { min: '0%', max: '105%'} }, 8 | x: { set: ['Line count'], range: { min: '0%', max: '110%' } }, 9 | color: { set: null }, 10 | label: { set: ['Line count'] }, 11 | }, 12 | title: null, 13 | legend: null 14 | }, 15 | style: { 16 | // fontSize:'0.9em', 17 | paddingTop: 0, 18 | paddingBottom: 0, 19 | backgroundColor: '#00000000', 20 | logo: { filter: 'opacity(0)' }, 21 | plot: { 22 | paddingTop: 1, 23 | paddingLeft: '6em', 24 | paddingRight: '2em', 25 | marker: { 26 | label: { fontWeight: 'bold', maxFractionDigits: '0', fontSize:'0.9em' } 27 | }, 28 | yAxis: { 29 | color: 'rgba(130,130,130,0.2)', 30 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 31 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingRight: '1.2em' }, 32 | title: { color: 'rgba(130,130,130,0)' } 33 | }, 34 | xAxis: { 35 | color: 'rgba(130,130,130,0.2)', 36 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 37 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingTop: '0.9em', angle: 0 }, 38 | title: { paddingTop: '2.2em', color: 'rgba(130,130,130,0)' } 39 | } 40 | } 41 | } 42 | }, 43 | { 44 | duration: 0.1 45 | }) 46 | 47 | .then(chart => { 48 | chart.feature('tooltip', true); 49 | return chart; 50 | }) 51 | 52 | ; 53 | } -------------------------------------------------------------------------------- /media/scripts/nav-anim-initial.js: -------------------------------------------------------------------------------- 1 | 2 | function nav_anim_init(chart) { 3 | 4 | return chart.animate({ 5 | config: { 6 | channels: { 7 | y: { set: ['Folder level 0'], range: { min: '0%', max: '105%'} }, 8 | x: { set: ['Line count'], range: { min: '0%', max: '110%' } }, 9 | color: { set: null }, 10 | label: { set: ['Line count'] }, 11 | }, 12 | title: null, 13 | legend: null 14 | }, 15 | style: { 16 | // fontSize:'0.9em', 17 | paddingTop: 0, 18 | paddingBottom: 0, 19 | backgroundColor: '#00000000', 20 | logo: { filter: 'opacity(0)' }, 21 | plot: { 22 | paddingTop: 1, 23 | paddingLeft: '6em', 24 | paddingRight: '2em', 25 | marker: { 26 | label: { fontWeight: 'bold', maxFractionDigits: '0', fontSize:'0.9em' } 27 | }, 28 | yAxis: { 29 | color: 'rgba(130,130,130,0.2)', 30 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 31 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingRight: '1.2em' }, 32 | title: { color: 'rgba(130,130,130,0)' } 33 | }, 34 | xAxis: { 35 | color: 'rgba(130,130,130,0.2)', 36 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 37 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingTop: '0.9em', angle: 0 }, 38 | title: { paddingTop: '2.2em', color: 'rgba(130,130,130,0)' } 39 | } 40 | } 41 | } 42 | }, 43 | { 44 | duration: 0.1 45 | }) 46 | 47 | .then(chart => { 48 | chart.feature('tooltip', true); 49 | return chart; 50 | }) 51 | 52 | ; 53 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeViz Stat 2 | 3 | One-click interactive source code stats using animated charts. 4 | 5 | - Online demos: [vizzu-lib](https://vizzuhq.github.io/codeviz/?project=vizzu-lib), [PyScript](https://vizzuhq.github.io/codeviz/?project=PyScript), [Bitcoin](https://vizzuhq.github.io/codeviz/?project=bitcoin), [Go Ethereum](https://vizzuhq.github.io/codeviz/?project=Go_Ethereum), [Prysm](https://vizzuhq.github.io/codeviz/?project=prysm), [Solana](https://vizzuhq.github.io/codeviz/?project=solana) 6 | - [GitHub](https://github.com/vizzuhq/codeviz/) 7 | - [VSCode Marketplace](https://marketplace.visualstudio.com/items?itemName=vizzuhq.code-viz-stat) 8 | 9 | Built using the open-source Javascript charting library [Vizzu](https://github.com/vizzuhq/vizzu-lib). 10 | 11 | Built on top of the great [VS Code Counter](https://marketplace.visualstudio.com/items?itemName=uctakeoff.vscode-counter) by Kentaro Usiyama. 12 | 13 | If you have a feature request, found a bug or just want to share your experience using CodeViz, come and join the conversation on our [GitHub Discussions page](https://github.com/vizzuhq/codeviz/discussions/). 14 | 15 | ## Features 16 | - Counts and visualizes the files and code lines of source code in the workspace. 17 | - Shows file count and line count in total and by programming languages. 18 | - Allows navigation within the project folders, filtering the visualized data accordingly. 19 | - Shows tooltip with details on mouseover. 20 | 21 | ## Usage 22 | ### Launching CodeViz 23 |  24 | 25 | ### Switch between the no. of lines and the no. of files 26 |  27 | 28 | ### Break down the data by languages and/or files 29 |  30 | 31 | When grouping and coloring by languages is switched off, the files are shown in the decreasing order of the line count. 32 | 33 | ### Navigate through your project by clicking on the folders on the left 34 |  35 | 36 | **Enjoy!** 37 | -------------------------------------------------------------------------------- /docs/vscodeapi.js: -------------------------------------------------------------------------------- 1 | var getJSON = function(url, callback) { 2 | var xhr = new XMLHttpRequest(); 3 | xhr.open('GET', url, true); 4 | xhr.responseType = 'json'; 5 | xhr.onload = function() { 6 | var status = xhr.status; 7 | if (status === 200) { 8 | callback(null, xhr.response); 9 | } else { 10 | callback(status, xhr.response); 11 | } 12 | }; 13 | xhr.send(); 14 | }; 15 | 16 | function getJSONSync(url) { 17 | return new Promise(function (resolve, reject) { 18 | getJSON(url, function(err, data) { 19 | if (err != null) 20 | reject({ 21 | status: "unable to load sample data" 22 | }); 23 | else 24 | resolve(data); 25 | }); 26 | }); 27 | } 28 | 29 | function acquireVsCodeApi(project) { 30 | return { 31 | postMessage: function(msgParam) { 32 | if (msgParam.command == 'vizzu-ready') { 33 | let data = null; 34 | let datasum = null; 35 | if (!project) project = 'vizzu-lib'; 36 | let jsonfile = project+'-data.json'; 37 | getJSONSync(jsonfile).then( 38 | (d1) => { 39 | data = d1; 40 | let jsonfile = project+'-datasum.json'; 41 | getJSONSync(jsonfile).then( 42 | (d2) => { 43 | datasum = d2; 44 | window.postMessage({ 45 | command: 'refresh-data-table', 46 | dataTable: data, 47 | dataSummary: datasum 48 | }); 49 | } 50 | ); 51 | } 52 | ); 53 | } 54 | else { 55 | console.log(msgParam); 56 | } 57 | } 58 | }; 59 | } 60 | -------------------------------------------------------------------------------- /docs/scripts/anim-0110-1011.js: -------------------------------------------------------------------------------- 1 | function anim_0110_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | color: { set: ['Language'] }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '10 File count + types 2', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: true, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'top' } }, 20 | xAxis: { label: { angle: -0.7 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'File name'] }, 31 | x: { set: ['Language'] }, 32 | label: { set: null }, 33 | }, 34 | // '11 File count + type 3', 35 | sort: 'byValue', 36 | legend: null, 37 | reverse: true, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'top' } }, 43 | xAxis: { label: { angle: -0.7 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.2 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: ['Language', 'File name'] }, 54 | x: { set: ['Line count'] }, 55 | color: { set: ['Language'] } 56 | }, 57 | // '6 code + types + Files 1', 58 | legend: 'color', 59 | sort: 'none', 60 | reverse: true, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '0em', 65 | yAxis: { label: { color:'#12345600' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 1.6 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /docs/scripts/anim-1001-0100.js: -------------------------------------------------------------------------------- 1 | function anim_1001_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { detach: ['Language'] }, 9 | label: { set: null } 10 | }, 11 | // '7 code + Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'Language', 'File name'] }, 31 | x: { set: null }, 32 | color: { detach: ['Language'] }, 33 | label: { set: null } 34 | }, 35 | // '7 code + Files 1', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: false, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 1.8 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: ['$count'] }, 55 | x: { set: null }, 56 | color: { set: null }, 57 | label: { set: ['$count'] }, 58 | }, 59 | // '13 File count 2', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 0.2 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /media/scripts/anim-0110-1011.js: -------------------------------------------------------------------------------- 1 | function anim_0110_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | color: { set: ['Language'] }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '10 File count + types 2', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: true, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'top' } }, 20 | xAxis: { label: { angle: -0.7 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'File name'] }, 31 | x: { set: ['Language'] }, 32 | label: { set: null }, 33 | }, 34 | // '11 File count + type 3', 35 | sort: 'byValue', 36 | legend: null, 37 | reverse: true, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'top' } }, 43 | xAxis: { label: { angle: -0.7 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.2 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: ['Language', 'File name'] }, 54 | x: { set: ['Line count'] }, 55 | color: { set: ['Language'] } 56 | }, 57 | // '6 code + types + Files 1', 58 | legend: 'color', 59 | sort: 'none', 60 | reverse: true, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '0em', 65 | yAxis: { label: { color:'#12345600' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 1.6 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /media/scripts/anim-1001-0100.js: -------------------------------------------------------------------------------- 1 | function anim_1001_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { detach: ['Language'] }, 9 | label: { set: null } 10 | }, 11 | // '7 code + Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.2 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'Language', 'File name'] }, 31 | x: { set: null }, 32 | color: { detach: ['Language'] }, 33 | label: { set: null } 34 | }, 35 | // '7 code + Files 1', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: false, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | yAxis: { label: { color:'#12345600' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 1.8 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: ['$count'] }, 55 | x: { set: null }, 56 | color: { set: null }, 57 | label: { set: ['$count'] }, 58 | }, 59 | // '13 File count 2', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 0.2 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /docs/scripts/anim-0100-1001.js: -------------------------------------------------------------------------------- 1 | function anim_0100_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: null }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | xAxis: { label: { angle: 0 } } 19 | } 20 | } 21 | }, 22 | { duration: 0.2 } 23 | ) 24 | 25 | .then(chart => chart.animate({ 26 | config: { 27 | channels: { 28 | y: { set: ['$count', 'Language', 'File name'] }, 29 | x: { set: null }, 30 | color: { detach: ['Language'] }, 31 | label: { set: null } 32 | }, 33 | // '7 code + Files 1', 34 | sort: 'byValue', 35 | legend: null, 36 | reverse: false, 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | yAxis: { label: { color:'#12345600' } }, 42 | xAxis: { label: { angle: 0 } } 43 | } 44 | } 45 | }, 46 | { duration: 0.2 } 47 | )) 48 | 49 | .then(chart => chart.animate({ 50 | config: { 51 | channels: { 52 | y: { set: ['Language', 'File name'] }, 53 | x: { set: ['Line count'] }, 54 | color: { detach: ['Language'] }, 55 | label: { set: null } 56 | }, 57 | // '7 code + Files 1', 58 | sort: 'byValue', 59 | legend: null, 60 | reverse: false, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | yAxis: { label: { color:'#12345600' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 1.8 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /media/scripts/anim-0100-1001.js: -------------------------------------------------------------------------------- 1 | function anim_0100_1001(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: null }, 8 | color: { set: null }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '13 File count 2', 12 | legend: null 13 | }, 14 | style: { 15 | plot: { 16 | paddingLeft: '9em', 17 | marker: { label: { position: 'center' } }, 18 | xAxis: { label: { angle: 0 } } 19 | } 20 | } 21 | }, 22 | { duration: 0.2 } 23 | ) 24 | 25 | .then(chart => chart.animate({ 26 | config: { 27 | channels: { 28 | y: { set: ['$count', 'Language', 'File name'] }, 29 | x: { set: null }, 30 | color: { detach: ['Language'] }, 31 | label: { set: null } 32 | }, 33 | // '7 code + Files 1', 34 | sort: 'byValue', 35 | legend: null, 36 | reverse: false, 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | yAxis: { label: { color:'#12345600' } }, 42 | xAxis: { label: { angle: 0 } } 43 | } 44 | } 45 | }, 46 | { duration: 0.2 } 47 | )) 48 | 49 | .then(chart => chart.animate({ 50 | config: { 51 | channels: { 52 | y: { set: ['Language', 'File name'] }, 53 | x: { set: ['Line count'] }, 54 | color: { detach: ['Language'] }, 55 | label: { set: null } 56 | }, 57 | // '7 code + Files 1', 58 | sort: 'byValue', 59 | legend: null, 60 | reverse: false, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | yAxis: { label: { color:'#12345600' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 1.8 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /src/panels/pagegen.ts: -------------------------------------------------------------------------------- 1 | import { Console } from "console"; 2 | import { Disposable, Webview, WebviewPanel, window, Uri, ViewColumn, workspace } from "vscode"; 3 | import { getUri } from "../utilities/geturi"; 4 | 5 | export class PageGenerator { 6 | private _view: Webview; 7 | private _panel: WebviewPanel; 8 | private _extensionUri: Uri; 9 | private _pathOnDisk: Uri; 10 | private _content: String = ''; 11 | 12 | public constructor(panel: WebviewPanel, extensionUri: Uri) { 13 | this._panel = panel; 14 | this._view = panel.webview; 15 | this._extensionUri = extensionUri; 16 | this._pathOnDisk = Uri.joinPath(this._extensionUri, 'media'); 17 | } 18 | 19 | public async generatePage() { 20 | const toolkitUri = getUri(this._view, this._extensionUri, 21 | [ "node_modules", "@vscode", "webview-ui-toolkit", "dist", "toolkit.js"]); 22 | const htmlPathOnDisk = Uri.joinPath(this._extensionUri, 'media', 'main.html'); 23 | let doc = await workspace.openTextDocument(htmlPathOnDisk); 24 | this._content = doc.getText(); 25 | const scripts = this._collectScripts(Uri.joinPath(this._pathOnDisk, 'scripts').fsPath); 26 | const stylesControlPath = Uri.joinPath(this._extensionUri, 'media', 'main.css'); 27 | const styleMain = this._view.asWebviewUri(stylesControlPath); 28 | const logoPath = Uri.joinPath(this._extensionUri, 'assets', 'vizzu_logo.png'); 29 | const logo = this._view.asWebviewUri(logoPath); 30 | this._content = this._content.replace('${styleMain}', styleMain.toString()); 31 | this._content = this._content.replace('${scriptToolkit}', toolkitUri.toString()); 32 | this._content = this._content.replace('${scripts}', scripts.toString()); 33 | this._content = this._content.replace('${logo}', logo.toString()); 34 | } 35 | 36 | public getHtmlContent() { 37 | return this._content.valueOf(); 38 | } 39 | 40 | private _collectScripts(root: String) { 41 | let result: String = ''; 42 | const fs = require('fs'); 43 | const directories = fs.readdirSync(root); 44 | directories.map((item: String) => { 45 | let path = Uri.joinPath(this._pathOnDisk, 'scripts'); 46 | path = Uri.joinPath(path, item.toString()); 47 | const scriptUri = path.with({ 'scheme': 'vscode-resource' }); 48 | result += '\n'; 49 | }); 50 | return result; 51 | } 52 | } -------------------------------------------------------------------------------- /docs/scripts/anim-1011-0110.js: -------------------------------------------------------------------------------- 1 | function anim_1011_0110(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: ['Language'] } 9 | }, 10 | // '6 code + types + Files 1', 11 | legend: 'color', 12 | sort: 'none', 13 | reverse: true, 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '0em', 18 | // yAxis: { label: { color:null } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.2 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['$count', 'File name'] }, 30 | x: { set: ['Language'] }, 31 | color: { set: ['Language'] } 32 | }, 33 | // '9 File count + types 1', 34 | sort: 'byValue', 35 | legend: null, 36 | reverse: true, 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | marker: { label: { position: 'top' } }, 42 | xAxis: { label: { angle: -0.7 } } 43 | } 44 | } 45 | }, 46 | { duration: 1.8 } 47 | )) 48 | 49 | .then(chart => chart.animate({ 50 | config: { 51 | channels: { 52 | y: { set: ['$count'] }, 53 | x: { set: ['Language'] }, 54 | color: { set: ['Language'] }, 55 | label: { set: ['$count'] }, 56 | }, 57 | // '10 File count + types 2', 58 | sort: 'byValue', 59 | legend: null, 60 | reverse: true, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'top' } }, 66 | xAxis: { label: { angle: -0.7 } }, 67 | yAxis: { label: { color:null } } 68 | } 69 | } 70 | }, 71 | { duration: 0.2 } 72 | )); 73 | } 74 | -------------------------------------------------------------------------------- /media/scripts/anim-1011-0110.js: -------------------------------------------------------------------------------- 1 | function anim_1011_0110(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language', 'File name'] }, 7 | x: { set: ['Line count'] }, 8 | color: { set: ['Language'] } 9 | }, 10 | // '6 code + types + Files 1', 11 | legend: 'color', 12 | sort: 'none', 13 | reverse: true, 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '0em', 18 | // yAxis: { label: { color:null } }, 19 | xAxis: { label: { angle: 0 } } 20 | } 21 | } 22 | }, 23 | { duration: 0.2 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: ['$count', 'File name'] }, 30 | x: { set: ['Language'] }, 31 | color: { set: ['Language'] } 32 | }, 33 | // '9 File count + types 1', 34 | sort: 'byValue', 35 | legend: null, 36 | reverse: true, 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | marker: { label: { position: 'top' } }, 42 | xAxis: { label: { angle: -0.7 } } 43 | } 44 | } 45 | }, 46 | { duration: 1.8 } 47 | )) 48 | 49 | .then(chart => chart.animate({ 50 | config: { 51 | channels: { 52 | y: { set: ['$count'] }, 53 | x: { set: ['Language'] }, 54 | color: { set: ['Language'] }, 55 | label: { set: ['$count'] }, 56 | }, 57 | // '10 File count + types 2', 58 | sort: 'byValue', 59 | legend: null, 60 | reverse: true, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'top' } }, 66 | xAxis: { label: { angle: -0.7 } }, 67 | yAxis: { label: { color:null } } 68 | } 69 | } 70 | }, 71 | { duration: 0.2 } 72 | )); 73 | } 74 | -------------------------------------------------------------------------------- /docs/scripts/anim-1010-1011.js: -------------------------------------------------------------------------------- 1 | function anim_1010_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count'] }, 8 | color: 'Language', 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '4 code + types 2', 12 | legend: null, 13 | reverse: false, 14 | sort: 'byValue' 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'right' } }, 20 | yAxis: { label: { paddingRight: '1.2em' } }, 21 | xAxis: { label: { angle: 0 } } 22 | } 23 | } 24 | }, 25 | { duration: 0.5 } 26 | ) 27 | 28 | .then(chart => chart.animate({ 29 | config: { 30 | channels: { 31 | y: { set: ['Language'] }, 32 | x: { set: ['Line count', 'File name'] }, 33 | color: 'Language', 34 | label: null 35 | }, 36 | // '5 code + types 3' 37 | legend: null, 38 | reverse: false, 39 | sort: 'byValue' 40 | }, 41 | style: { 42 | plot: { 43 | paddingLeft: '9em', 44 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 45 | xAxis: { label: { angle: 0 } } 46 | } 47 | } 48 | }, 49 | { duration: 0.5 } 50 | )) 51 | 52 | .then(chart => chart.animate({ 53 | config: { 54 | channels: { 55 | y: { set: ['Language', 'File name'] }, 56 | x: { set: ['Line count'] }, 57 | color: { set: ['Language'] } 58 | }, 59 | // '6 code + types + Files 1', 60 | legend: 'color', 61 | sort: 'none', 62 | reverse: true, 63 | }, 64 | style: { 65 | plot: { 66 | paddingLeft: '0em', 67 | yAxis: { label: { color:'#12345600' } }, 68 | xAxis: { label: { angle: 0 } } 69 | } 70 | } 71 | }, 72 | { duration: 2 } 73 | )); 74 | } 75 | -------------------------------------------------------------------------------- /media/scripts/anim-1010-1011.js: -------------------------------------------------------------------------------- 1 | function anim_1010_1011(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count'] }, 8 | color: 'Language', 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '4 code + types 2', 12 | legend: null, 13 | reverse: false, 14 | sort: 'byValue' 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'right' } }, 20 | yAxis: { label: { paddingRight: '1.2em' } }, 21 | xAxis: { label: { angle: 0 } } 22 | } 23 | } 24 | }, 25 | { duration: 0.5 } 26 | ) 27 | 28 | .then(chart => chart.animate({ 29 | config: { 30 | channels: { 31 | y: { set: ['Language'] }, 32 | x: { set: ['Line count', 'File name'] }, 33 | color: 'Language', 34 | label: null 35 | }, 36 | // '5 code + types 3' 37 | legend: null, 38 | reverse: false, 39 | sort: 'byValue' 40 | }, 41 | style: { 42 | plot: { 43 | paddingLeft: '9em', 44 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 45 | xAxis: { label: { angle: 0 } } 46 | } 47 | } 48 | }, 49 | { duration: 0.5 } 50 | )) 51 | 52 | .then(chart => chart.animate({ 53 | config: { 54 | channels: { 55 | y: { set: ['Language', 'File name'] }, 56 | x: { set: ['Line count'] }, 57 | color: { set: ['Language'] } 58 | }, 59 | // '6 code + types + Files 1', 60 | legend: 'color', 61 | sort: 'none', 62 | reverse: true, 63 | }, 64 | style: { 65 | plot: { 66 | paddingLeft: '0em', 67 | yAxis: { label: { color:'#12345600' } }, 68 | xAxis: { label: { angle: 0 } } 69 | } 70 | } 71 | }, 72 | { duration: 2 } 73 | )); 74 | } 75 | -------------------------------------------------------------------------------- /docs/scripts/anim-1001-1000.js: -------------------------------------------------------------------------------- 1 | function anim_1001_1000(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['File name'] }, 7 | x: { set: ['Line count'] }, 8 | label: { set: null }, 9 | color: { detach: ['Language'] } 10 | }, 11 | // '7 code+ Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: null }, 31 | x: { set: ['Line count', 'File name'] }, 32 | color: { set: null }, 33 | label: { set: null }, 34 | }, 35 | //1 code1 36 | sort: 'byValue' 37 | }, 38 | style: { 39 | legend: { paddingLeft: '5.789473684' }, 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'center' } }, 43 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: null }, 55 | x: { set: ['Line count'] }, 56 | color: { set: null }, 57 | label: { set: ['Line count'] }, 58 | }, 59 | }, 60 | style: { 61 | legend: { paddingLeft: '5.789473684' }, 62 | plot: { 63 | paddingLeft: '9em', 64 | marker: { label: { position: 'center' } }, 65 | yAxis: { label: { fontSize: null, paddingRight: '1.2em' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 0.5 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /media/scripts/anim-1001-1000.js: -------------------------------------------------------------------------------- 1 | function anim_1001_1000(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['File name'] }, 7 | x: { set: ['Line count'] }, 8 | label: { set: null }, 9 | color: { detach: ['Language'] } 10 | }, 11 | // '7 code+ Files 1', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: false, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | yAxis: { label: { color:'#12345600' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: null }, 31 | x: { set: ['Line count', 'File name'] }, 32 | color: { set: null }, 33 | label: { set: null }, 34 | }, 35 | //1 code1 36 | sort: 'byValue' 37 | }, 38 | style: { 39 | legend: { paddingLeft: '5.789473684' }, 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'center' } }, 43 | yAxis: { label: { color:'#12345600', paddingRight: '1.2em' } }, 44 | xAxis: { label: { angle: 0 } } 45 | } 46 | } 47 | }, 48 | { duration: 2 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: null }, 55 | x: { set: ['Line count'] }, 56 | color: { set: null }, 57 | label: { set: ['Line count'] }, 58 | }, 59 | }, 60 | style: { 61 | legend: { paddingLeft: '5.789473684' }, 62 | plot: { 63 | paddingLeft: '9em', 64 | marker: { label: { position: 'center' } }, 65 | yAxis: { label: { fontSize: null, paddingRight: '1.2em' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 0.5 } 71 | )); 72 | } 73 | -------------------------------------------------------------------------------- /assets/readme.txt: -------------------------------------------------------------------------------- 1 | Data series names: 2 | Old New 3 | --------------------- 4 | Line count code 5 | Languages type 6 | File name file 7 | 8 | 9 | 10xx = Line count 10 | 01xx = File count 11 | 12 | 10xx-01xx = Line count 2 File count 13 | 14 | File tetején= chart, dirLevel 15 | 16 | Control state transitions: 17 | 1000-1001 Line count + Files (Final 6) 18 | 1001-1000 Line count - Files (Final 6) 19 | 20 | 1001-1011 Line count, Files + Languages (Final 5) 21 | 1011-1001 Line count, Files - Languages (Final 5) 22 | 23 | 1011-1010 Line count, Files, Languages - Files (Final 4) 24 | 1010-1011 Line count, Languages + Files (Final 4) 25 | 26 | 1010-1000 Line count, Languages - Languages (Final 3) 27 | 1000-1010 Line count + Languages (Final 3) 28 | 29 | 1000-0100 Line count <-> File count (Final 1) 30 | 0100-1000 File count <-> Line count (Final 1) 31 | 32 | 0100-0110 File count + Languages (Final 2) 33 | 0110-0100 File count, Languages - Languages (Final 2) 34 | 35 | 0110-1010 File count, Languages <-> Line count (Final 7) 36 | 1010-0110 Line count, Languages <-> File count (Final 7) 37 | 38 | 0100-1001 File count <-> Line count + Files (Final 9) 39 | 1001-0100 Line count, Files <-> File count - Files (Final 9) 40 | 41 | 1011-0110 Line count, Languages, Files <-> File count - Files (Final 8) 42 | 0110-1011 File count, Languages <-> Line count + Files (Final8) 43 | 44 | Animation with one step: 45 | chart.animate({ 46 | config: { 47 | ... 48 | }, 49 | style: { 50 | ... 51 | }}, 52 | { duration: 1 } 53 | ); 54 | 55 | Animation with two steps: 56 | chart.animate({ 57 | config: { 58 | ... 59 | }, 60 | style: { 61 | ... 62 | }}, 63 | { duration: 1 } 64 | ) 65 | .then(chart => chart.animate({ 66 | config: { 67 | ... 68 | }, 69 | style: { 70 | ... 71 | }}, 72 | { duration: 1 } 73 | )) 74 | .then(chart => chart.animate({ 75 | config: { 76 | ... 77 | }, 78 | style: { 79 | ... 80 | }}, 81 | { duration: 1 } 82 | )) 83 | .then(chart => chart.animate({ 84 | config: { 85 | ... 86 | }, 87 | style: { 88 | ... 89 | }}, 90 | { duration: 1 } 91 | )) 92 | ; 93 | } 94 | -------------------------------------------------------------------------------- /docs/scripts/anim-initial.js: -------------------------------------------------------------------------------- 1 | 2 | function anim_init(chart) { 3 | 4 | return chart.animate({ 5 | config: { 6 | channels: { 7 | y: { set: ['Language'], range: { min: '0%', max: '105%' } }, 8 | x: { set: ['Line count'], range: { min: '0%', max: '110%' } }, 9 | color: { set: 'Language' }, 10 | label: { set: ['Line count'] } 11 | }, 12 | legend: null, 13 | sort: 'byValue', 14 | reverse: false, 15 | title: null 16 | }, 17 | style: { 18 | // fontSize:'0.9em', 19 | paddingTop: 0, 20 | paddingBottom: 0, 21 | backgroundColor: '#00000000', 22 | logo: { filter: 'opacity(0)' }, 23 | legend: { width: '9em', label: { fontWeight: 'bold', fontSize:'0.9em' }, marker: { size: '11' }, paddingLeft: '0', paddingRight: '0' }, 24 | plot: { 25 | paddingTop: 1, 26 | paddingLeft: '9em', 27 | marker: { 28 | // colorPalette: '#03ae71 #f4941b #f4c204 #d49664 #f25456 #9e67ab rgb(188,166,4) rgb(132,110,28) rgb(252,118,60) rgb(180,98,172) rgb(244,146,252) rgb(188,74,148) rgb(156,126,244) rgb(156,82,180) rgb(108,162,252) rgb(92,110,188) rgb(124,134,140) rgb(172,150,140) rgb(76,116,80) rgb(172,122,76) rgb(124,174,84) rgb(76,116,80) rgb(156,26,108) rgb(172,62,148) rgb(180,18,4)', 29 | label: { fontWeight: 'bold', maxFractionDigits: '0', fontSize:'0.9em', position: 'right' } 30 | }, 31 | yAxis: { 32 | color: 'rgba(130,130,130,0.2)', 33 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 34 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingRight: '1.2em' }, 35 | title: { color: 'rgba(130,130,130,0)' } 36 | }, 37 | xAxis: { 38 | color: 'rgba(130,130,130,0.2)', 39 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 40 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingTop: '0.9em', angle: 0 }, 41 | title: { paddingTop: '2.2em', color: 'rgba(130,130,130,0)' } 42 | } 43 | } 44 | } 45 | }, 46 | { 47 | duration: 1 48 | }) 49 | 50 | .then(chart => { 51 | chart.feature('tooltip', true); 52 | return chart; 53 | }) 54 | 55 | ; 56 | } -------------------------------------------------------------------------------- /media/scripts/anim-initial.js: -------------------------------------------------------------------------------- 1 | 2 | function anim_init(chart) { 3 | 4 | return chart.animate({ 5 | config: { 6 | channels: { 7 | y: { set: ['Language'], range: { min: '0%', max: '105%' } }, 8 | x: { set: ['Line count'], range: { min: '0%', max: '110%' } }, 9 | color: { set: 'Language' }, 10 | label: { set: ['Line count'] } 11 | }, 12 | legend: null, 13 | sort: 'byValue', 14 | reverse: false, 15 | title: null 16 | }, 17 | style: { 18 | // fontSize:'0.9em', 19 | paddingTop: 0, 20 | paddingBottom: 0, 21 | backgroundColor: '#00000000', 22 | logo: { filter: 'opacity(0)' }, 23 | legend: { width: '9em', label: { fontWeight: 'bold', fontSize:'0.9em' }, marker: { size: '11' }, paddingLeft: '0', paddingRight: '0' }, 24 | plot: { 25 | paddingTop: 1, 26 | paddingLeft: '9em', 27 | marker: { 28 | // colorPalette: '#03ae71 #f4941b #f4c204 #d49664 #f25456 #9e67ab rgb(188,166,4) rgb(132,110,28) rgb(252,118,60) rgb(180,98,172) rgb(244,146,252) rgb(188,74,148) rgb(156,126,244) rgb(156,82,180) rgb(108,162,252) rgb(92,110,188) rgb(124,134,140) rgb(172,150,140) rgb(76,116,80) rgb(172,122,76) rgb(124,174,84) rgb(76,116,80) rgb(156,26,108) rgb(172,62,148) rgb(180,18,4)', 29 | label: { fontWeight: 'bold', maxFractionDigits: '0', fontSize:'0.9em', position: 'right' } 30 | }, 31 | yAxis: { 32 | color: 'rgba(130,130,130,0.2)', 33 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 34 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingRight: '1.2em' }, 35 | title: { color: 'rgba(130,130,130,0)' } 36 | }, 37 | xAxis: { 38 | color: 'rgba(130,130,130,0.2)', 39 | interlacing: { color: 'rgba(126,126,126,0.08)' }, 40 | label: { fontWeight: 'bold', fontSize:'0.9em', paddingTop: '0.9em', angle: 0 }, 41 | title: { paddingTop: '2.2em', color: 'rgba(130,130,130,0)' } 42 | } 43 | } 44 | } 45 | }, 46 | { 47 | duration: 1 48 | }) 49 | 50 | .then(chart => { 51 | chart.feature('tooltip', true); 52 | return chart; 53 | }) 54 | 55 | ; 56 | } -------------------------------------------------------------------------------- /docs/scripts/anim-1010-0110.js: -------------------------------------------------------------------------------- 1 | function anim_1010_0110(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count'] }, 8 | color: 'Language', 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '4 code + types 2', 12 | legend: null, 13 | sort: 'byValue', 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '9em', 18 | marker: { label: { position: 'right' } }, 19 | yAxis: { label: { paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | x: { set: ['Line count', 'File name'] }, 31 | label: null 32 | }, 33 | // '5 code + types 3' 34 | }, 35 | style: { 36 | plot: { 37 | paddingLeft: '9em', 38 | yAxis: { label: { paddingRight: '1.2em' } }, 39 | xAxis: { label: { angle: 0 } } 40 | } 41 | } 42 | }, 43 | { duration: 0.1 } 44 | )) 45 | 46 | .then(chart => chart.animate({ 47 | config: { 48 | channels: { 49 | y: { set: ['$count', 'File name'] }, 50 | x: { set: ['Language'] } 51 | }, 52 | // '9 File count + types 1', 53 | reverse: true, 54 | }, 55 | style: { 56 | plot: { 57 | paddingLeft: '9em', 58 | marker: { label: { position: 'top' } }, 59 | xAxis: { label: { angle: -0.7 } } 60 | } 61 | } 62 | }, 63 | { duration: 1.6 } 64 | )) 65 | 66 | .then(chart => chart.animate({ 67 | config: { 68 | channels: { 69 | y: { set: ['$count'] }, 70 | label: { set: ['$count'] }, 71 | }, 72 | // '10 File count + types 2', 73 | }, 74 | style: { 75 | plot: { 76 | paddingLeft: '9em', 77 | marker: { label: { position: 'top' } }, 78 | xAxis: { label: { angle: -0.7 } } 79 | } 80 | } 81 | }, 82 | { duration: 0.5 } 83 | )); 84 | } 85 | -------------------------------------------------------------------------------- /media/scripts/anim-1010-0110.js: -------------------------------------------------------------------------------- 1 | function anim_1010_0110(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['Language'] }, 7 | x: { set: ['Line count'] }, 8 | color: 'Language', 9 | label: { set: ['Line count'] }, 10 | }, 11 | // '4 code + types 2', 12 | legend: null, 13 | sort: 'byValue', 14 | }, 15 | style: { 16 | plot: { 17 | paddingLeft: '9em', 18 | marker: { label: { position: 'right' } }, 19 | yAxis: { label: { paddingRight: '1.2em' } }, 20 | xAxis: { label: { angle: 0 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | x: { set: ['Line count', 'File name'] }, 31 | label: null 32 | }, 33 | // '5 code + types 3' 34 | }, 35 | style: { 36 | plot: { 37 | paddingLeft: '9em', 38 | yAxis: { label: { paddingRight: '1.2em' } }, 39 | xAxis: { label: { angle: 0 } } 40 | } 41 | } 42 | }, 43 | { duration: 0.1 } 44 | )) 45 | 46 | .then(chart => chart.animate({ 47 | config: { 48 | channels: { 49 | y: { set: ['$count', 'File name'] }, 50 | x: { set: ['Language'] } 51 | }, 52 | // '9 File count + types 1', 53 | reverse: true, 54 | }, 55 | style: { 56 | plot: { 57 | paddingLeft: '9em', 58 | marker: { label: { position: 'top' } }, 59 | xAxis: { label: { angle: -0.7 } } 60 | } 61 | } 62 | }, 63 | { duration: 1.6 } 64 | )) 65 | 66 | .then(chart => chart.animate({ 67 | config: { 68 | channels: { 69 | y: { set: ['$count'] }, 70 | label: { set: ['$count'] }, 71 | }, 72 | // '10 File count + types 2', 73 | }, 74 | style: { 75 | plot: { 76 | paddingLeft: '9em', 77 | marker: { label: { position: 'top' } }, 78 | xAxis: { label: { angle: -0.7 } } 79 | } 80 | } 81 | }, 82 | { duration: 0.5 } 83 | )); 84 | } 85 | -------------------------------------------------------------------------------- /media/scripts/uiLogic-main.js: -------------------------------------------------------------------------------- 1 | const vscode = acquireVsCodeApi(); 2 | let navChart = undefined; 3 | let infoChart = undefined; 4 | let Vizzu = undefined; 5 | 6 | (function () { 7 | window.addEventListener('message', async event => { 8 | const message = event.data; 9 | switch (message.command) { 10 | case 'clear-data-table': 11 | await resetVizzuCharts(); 12 | break; 13 | case 'refresh-data-table': 14 | await initializingVizzuCharts(message.dataTable); 15 | performInitAnimation(message.dataSummary); 16 | updateInfoLabelsContent(message.dataSummary); 17 | dirMaxDepth = message.dataSummary.depth; 18 | break; 19 | } 20 | }); 21 | importVizzuLibAndCreateCharts(); 22 | }()); 23 | 24 | function importVizzuLibAndCreateCharts() { 25 | if (navChart == undefined || infoChart == undefined) { 26 | navChart = undefined; 27 | infoChart = undefined; 28 | let promise = import('https://cdn.jsdelivr.net/npm/vizzu@~0.4.0/dist/vizzu.min.js'); 29 | promise.then( (lib) => { 30 | try { 31 | Vizzu = lib; 32 | vscode.postMessage({ command: 'vizzu-ready' }); 33 | } 34 | catch (e) { 35 | vscode.postMessage({ command: 'showerror', text: 'Vizzu initialization failure: ' + e }); 36 | } 37 | }).catch( (e) => { 38 | vscode.postMessage({ command: 'showerror', text: 'Vizzu library import failure: ' + e }); 39 | }); 40 | } 41 | setBackLabelState(false); 42 | setBackLabelState(true); 43 | } 44 | 45 | async function initializingVizzuCharts(data) { 46 | navChart = new Vizzu.default('navVizzu'); 47 | infoChart = new Vizzu.default('infoVizzu'); 48 | await infoChart 49 | .initializing 50 | .then(infoChart => infoChart.animate({data: data})); 51 | await navChart 52 | .initializing 53 | .then(navChart => navChart.animate({data: data})); 54 | navChart.on('click', performFilteringAnimationFw); 55 | navChart.on('plot-axis-label-draw', navLabelDrawHandler); 56 | } 57 | 58 | async function resetVizzuCharts() { 59 | await infoChart.animate({data: {}}); 60 | await navChart.animate({data: {}}); 61 | navChart.off('click'); 62 | navChart.off('plot-axis-label-draw'); 63 | let element1 = document.getElementById("navVizzu"); 64 | while (element1.firstChild) { 65 | element1.removeChild(element1.firstChild); 66 | } 67 | let element2 = document.getElementById("infoVizzu"); 68 | while (element2.firstChild) { 69 | element2.removeChild(element2.firstChild); 70 | } 71 | vscode.postMessage({ command: 'vizzu-ready' }); 72 | } 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code-viz-stat", 3 | "displayName": "CodeViz Stat", 4 | "description": "Explore source code statistics with animated vizualizations.", 5 | "version": "0.1.4", 6 | "publisher": "vizzuhq", 7 | "author": { 8 | "name": "Tamás Czagány", 9 | "email": "hello@vizzuhq.com" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/vizzuhq/codeviz" 14 | }, 15 | "homepage": "https://vizzuhq.com/", 16 | "engines": { 17 | "vscode": "^1.46.0" 18 | }, 19 | "galleryBanner": { 20 | "color": "#1C1C1C", 21 | "theme": "dark" 22 | }, 23 | "license": "SEE LICENSE IN LICENSE.txt", 24 | "icon": "icon.png", 25 | "categories": [ 26 | "Other", 27 | "Programming Languages", 28 | "Visualization" 29 | ], 30 | "keywords": [ 31 | "count", 32 | "loc", 33 | "code", 34 | "stat", 35 | "stats", 36 | "vizzu", 37 | "counter", 38 | "animation", 39 | "explorer", 40 | "statistics", 41 | "line", 42 | "chart", 43 | "linecount", 44 | "report" 45 | ], 46 | "activationEvents": [ 47 | "onCommand:CodeViz.show", 48 | "onCommand:CodeViz.import" 49 | ], 50 | "extensionDependencies": [ 51 | "uctakeoff.vscode-counter" 52 | ], 53 | "main": "./out/extension.js", 54 | "contributes": { 55 | "menus": { 56 | "explorer/context": [ 57 | { 58 | "command": "CodeViz.show", 59 | "when": "explorerResourceIsFolder", 60 | "group": "2_workspace" 61 | } 62 | ] 63 | }, 64 | "commands": [ 65 | { 66 | "command": "CodeViz.show", 67 | "title": "CodeViz: Show statistics" 68 | }, 69 | { 70 | "command": "CodeViz.import", 71 | "title": "CodeViz: Import statistics" 72 | }, 73 | { 74 | "command": "CodeViz.export", 75 | "title": "CodeViz: Export statistics" 76 | } 77 | ] 78 | }, 79 | "scripts": { 80 | "vscode:prepublish": "npm run compile", 81 | "compile": "tsc -p ./", 82 | "watch": "tsc -watch -p ./", 83 | "pretest": "npm run compile && npm run lint", 84 | "lint": "eslint src --ext ts" 85 | }, 86 | "devDependencies": { 87 | "@types/glob": "^7.1.3", 88 | "@types/node": "^12.11.7", 89 | "@types/vscode": "^1.46.0", 90 | "@typescript-eslint/eslint-plugin": "^4.14.1", 91 | "@typescript-eslint/parser": "^4.14.1", 92 | "eslint": "^7.19.0", 93 | "glob": "^7.1.6", 94 | "prettier": "^2.2.1", 95 | "typescript": "^4.1.3", 96 | "vscode-test": "^1.5.0" 97 | }, 98 | "dependencies": { 99 | "@vscode/webview-ui-toolkit": "^0.9.1", 100 | "react": "^18.2.0", 101 | "vizzu": "^0.4.8" 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /docs/scripts/uiLogic-main.js: -------------------------------------------------------------------------------- 1 | const params = new URLSearchParams(window.location.search); 2 | const project = params.get('project'); 3 | const vscode = acquireVsCodeApi(project); 4 | let navChart = undefined; 5 | let infoChart = undefined; 6 | 7 | function setTitle(project) { 8 | const title = project 9 | ? `CodeViz Stat Demo: ${project[0].toUpperCase()}${project.substring(1).replace("_"," ")}` 10 | : 'CodeViz Stat Demo'; 11 | 12 | document.title = title; 13 | document.getElementById('label_title').innerText = title; 14 | } 15 | 16 | setTitle(project); 17 | 18 | (function () { 19 | window.addEventListener('message', async event => { 20 | const message = event.data; 21 | switch (message.command) { 22 | case 'clear-data-table': 23 | await resetVizzuCharts(); 24 | break; 25 | case 'refresh-data-table': 26 | await initializingVizzuCharts(message.dataTable); 27 | performInitAnimation(message.dataSummary); 28 | updateInfoLabelsContent(message.dataSummary); 29 | dirMaxDepth = message.dataSummary.depth; 30 | break; 31 | } 32 | }); 33 | importVizzuLibAndCreateCharts(); 34 | }()); 35 | 36 | function importVizzuLibAndCreateCharts() { 37 | if (navChart == undefined || infoChart == undefined) { 38 | navChart = undefined; 39 | infoChart = undefined; 40 | let promise = import('https://cdn.jsdelivr.net/npm/vizzu@~0.4.0/dist/vizzu.min.js'); 41 | promise.then( (Vizzu) => { 42 | try { 43 | navChart = new Vizzu.default('navVizzu'); 44 | infoChart = new Vizzu.default('infoVizzu'); 45 | vscode.postMessage({ command: 'vizzu-ready' }); 46 | } 47 | catch (e) { 48 | vscode.postMessage({ command: 'showerror', text: 'Vizzu initialization failure: ' + e }); 49 | } 50 | }).catch( (e) => { 51 | vscode.postMessage({ command: 'showerror', text: 'Vizzu library import failure: ' + e }); 52 | }); 53 | } 54 | setBackLabelState(false); 55 | setBackLabelState(true); 56 | } 57 | 58 | async function initializingVizzuCharts(data) { 59 | await infoChart 60 | .initializing 61 | .then(infoChart => infoChart.animate({data: data})); 62 | await navChart 63 | .initializing 64 | .then(navChart => navChart.animate({data: data})); 65 | navChart.on('click', performFilteringAnimationFw); 66 | navChart.on('plot-axis-label-draw', navLabelDrawHandler); 67 | } 68 | 69 | async function resetVizzuCharts() { 70 | await infoChart.animate({data: {}}); 71 | await navChart.animate({data: {}}); 72 | navChart.off('click'); 73 | navChart.off('plot-axis-label-draw'); 74 | } 75 | -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | import { commands, window, ExtensionContext, workspace, Uri } from "vscode"; 2 | 3 | import { CCVizzuPanel } from "./panels/ccvizzupanel"; 4 | import { VSCCDataSource } from "./data/vscc_datasource"; 5 | import { VSCCDataPrep } from "./data/vscc_dataprep"; 6 | import { Summary } from "./data/vscc_result"; 7 | 8 | export function activate(context: ExtensionContext) { 9 | const importCommand = commands.registerCommand("CodeViz.import", async () => { 10 | let wsPath: Uri; 11 | workspace.workspaceFolders?.map((folder) => { 12 | if (wsPath == undefined) 13 | wsPath = folder.uri; 14 | }); 15 | const folderPath = await window.showInputBox({ 16 | placeHolder: "import path", 17 | prompt: "Enter import data path", 18 | value: "" 19 | }); 20 | if (folderPath) { 21 | CCVizzuPanel.render(context.extensionUri).then(() => { 22 | CCVizzuPanel.import(folderPath); 23 | }); 24 | } 25 | }); 26 | const exportCommand = commands.registerCommand("CodeViz.export", async () => { 27 | const folderPath = await window.showInputBox({ 28 | placeHolder: "export path", 29 | prompt: "Enter export data path", 30 | value: "" 31 | }); 32 | if (folderPath) { 33 | CCVizzuPanel.export(folderPath); 34 | } 35 | }); 36 | const showCommand = commands.registerCommand("CodeViz.show", (targetDir: Uri | undefined) => { 37 | let wsPath: Uri; 38 | workspace.workspaceFolders?.map((folder) => { 39 | if (wsPath == undefined) 40 | wsPath = folder.uri; 41 | }); 42 | commands.executeCommand('extension.vscode-counter.countInDirectory', targetDir).then(() => { 43 | setTimeout(() => { 44 | CCVizzuPanel.render(context.extensionUri).then(() => { 45 | let source: VSCCDataSource; 46 | if (targetDir == undefined) 47 | targetDir = wsPath; 48 | source = new VSCCDataSource(wsPath, targetDir); 49 | if (source.data != undefined) { 50 | let data = new VSCCDataPrep(); 51 | data.makeDataTable(source.data); 52 | CCVizzuPanel.refresh(data.getDataTable(), new Summary(source, data)); 53 | } 54 | else 55 | window.showErrorMessage('\'Code Counter\' data is not awailable!'); 56 | }); 57 | }, 1000); 58 | }); 59 | }); 60 | context.subscriptions.push(showCommand); 61 | context.subscriptions.push(importCommand); 62 | context.subscriptions.push(exportCommand); 63 | } 64 | -------------------------------------------------------------------------------- /docs/scripts/anim-0110-1010.js: -------------------------------------------------------------------------------- 1 | function anim_0110_1010(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | color: { set: ['Language'] }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '10 File count + types 2', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: true, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'top' } }, 20 | xAxis: { label: { angle: -0.7 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'File name'] }, 31 | label: { set: null }, 32 | }, 33 | // '11 File count + type 3', 34 | }, 35 | style: { 36 | plot: { 37 | paddingLeft: '9em', 38 | marker: { label: { position: 'top' } }, 39 | xAxis: { label: { angle: -0.7 } } 40 | } 41 | } 42 | }, 43 | { duration: 0.1 } 44 | )) 45 | 46 | .then(chart => chart.animate({ 47 | config: { 48 | channels: { 49 | y: { set: ['Language'] }, 50 | x: { set: ['Line count', 'File name'] } 51 | }, 52 | // '5 code + types 3' 53 | reverse: false 54 | }, 55 | style: { 56 | plot: { 57 | paddingLeft: '9em', 58 | marker: { label: { position: 'right' } }, 59 | yAxis: { label: { paddingRight: '1.2em' } }, 60 | xAxis: { label: { angle: 0 } } 61 | } 62 | } 63 | }, 64 | { duration: 1.6 } 65 | )) 66 | 67 | .then(chart => chart.animate({ 68 | config: { 69 | channels: { 70 | x: { set: ['Line count'] }, 71 | label: { set: ['Line count'] }, 72 | }, 73 | // '4 code + types 2', 74 | }, 75 | style: { 76 | plot: { 77 | paddingLeft: '9em', 78 | marker: { label: { position: 'right' } }, 79 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 80 | xAxis: { label: { angle: 0 } } 81 | } 82 | } 83 | }, 84 | { duration: 0.5 } 85 | )); 86 | } 87 | -------------------------------------------------------------------------------- /media/scripts/anim-0110-1010.js: -------------------------------------------------------------------------------- 1 | function anim_0110_1010(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | color: { set: ['Language'] }, 9 | label: { set: ['$count'] }, 10 | }, 11 | // '10 File count + types 2', 12 | sort: 'byValue', 13 | legend: null, 14 | reverse: true, 15 | }, 16 | style: { 17 | plot: { 18 | paddingLeft: '9em', 19 | marker: { label: { position: 'top' } }, 20 | xAxis: { label: { angle: -0.7 } } 21 | } 22 | } 23 | }, 24 | { duration: 0.1 } 25 | ) 26 | 27 | .then(chart => chart.animate({ 28 | config: { 29 | channels: { 30 | y: { set: ['$count', 'File name'] }, 31 | label: { set: null }, 32 | }, 33 | // '11 File count + type 3', 34 | }, 35 | style: { 36 | plot: { 37 | paddingLeft: '9em', 38 | marker: { label: { position: 'top' } }, 39 | xAxis: { label: { angle: -0.7 } } 40 | } 41 | } 42 | }, 43 | { duration: 0.1 } 44 | )) 45 | 46 | .then(chart => chart.animate({ 47 | config: { 48 | channels: { 49 | y: { set: ['Language'] }, 50 | x: { set: ['Line count', 'File name'] } 51 | }, 52 | // '5 code + types 3' 53 | reverse: false 54 | }, 55 | style: { 56 | plot: { 57 | paddingLeft: '9em', 58 | marker: { label: { position: 'right' } }, 59 | yAxis: { label: { paddingRight: '1.2em' } }, 60 | xAxis: { label: { angle: 0 } } 61 | } 62 | } 63 | }, 64 | { duration: 1.6 } 65 | )) 66 | 67 | .then(chart => chart.animate({ 68 | config: { 69 | channels: { 70 | x: { set: ['Line count'] }, 71 | label: { set: ['Line count'] }, 72 | }, 73 | // '4 code + types 2', 74 | }, 75 | style: { 76 | plot: { 77 | paddingLeft: '9em', 78 | marker: { label: { position: 'right' } }, 79 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 80 | xAxis: { label: { angle: 0 } } 81 | } 82 | } 83 | }, 84 | { duration: 0.5 } 85 | )); 86 | } 87 | -------------------------------------------------------------------------------- /media/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |16 | date placeholder 17 | - 18 | dir placeholder 19 |
20 |21 | files: 22 | lines: 23 | code: 24 | comment: 25 | blank: 26 |
27 |15 | date placeholder 16 | - 17 | dir placeholder 18 |
19 |20 | files: 21 | lines: 22 | code: 23 | comment: 24 | blank: 25 |
26 |