├── .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 | ![Launching CodeViz](images/guide_1_start.gif) 24 | 25 | ### Switch between the no. of lines and the no. of files 26 | ![lines_or_files](images/guide_3_dropdown.gif) 27 | 28 | ### Break down the data by languages and/or files 29 | ![Languages_Files_Checkboxes](images/guide_2_checkbox.gif) 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 | ![Languages_Files_Checkboxes](images/guide_4_navig.gif) 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 | Code Counter Vizzu 12 | 13 | 14 |

CodeViz

15 |

16 | date placeholder 17 |   -   18 | dir placeholder 19 |

20 |

21 | files:     22 | lines:     23 | code:     24 | comment:     25 | blank: 26 |

27 |
28 |
29 | 30 | Line count 31 | File count 32 | 33 |
34 |
35 |
36 | Languages 37 | Files 38 |
39 |
40 |
41 |

42 |
43 | 44 |
45 |
46 |
47 | 48 |
49 | ${scripts} 50 | 51 | -------------------------------------------------------------------------------- /docs/scripts/anim-0100-0110.js: -------------------------------------------------------------------------------- 1 | function anim_0100_0110(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 | },// '13 File count 2', 11 | legend: null 12 | }, 13 | style: { 14 | plot: { 15 | paddingLeft: '9em', 16 | marker: { label: { position: 'center' } }, 17 | xAxis: { label: { angle: -0.7 } } 18 | } 19 | } 20 | }, 21 | { duration: 0.1 } 22 | ) 23 | 24 | .then(chart => chart.animate({ 25 | config: { 26 | channels: { 27 | y: { set: ['$count', 'Language', 'File name'] }, 28 | x: { set: null }, 29 | label: { set: null }, 30 | color: { set: ['Language'] } 31 | },// '12 File count 1', 32 | legend: null 33 | }, 34 | style: { 35 | plot: { 36 | paddingLeft: '9em', 37 | marker: { label: { position: 'center' } }, 38 | xAxis: { label: { angle: -0.7 } } 39 | } 40 | } 41 | }, 42 | { duration: 0.5 } 43 | )) 44 | 45 | .then(chart => chart.animate({ 46 | config: { 47 | channels: { 48 | y: { set: ['$count', 'File name'] }, 49 | x: { set: ['Language'] }, 50 | color: { set: ['Language'] } 51 | },// '9 File count + types 1', 52 | sort: 'byValue', 53 | legend: null, 54 | reverse: true, 55 | }, 56 | style: { 57 | plot: { 58 | paddingLeft: '9em', 59 | marker: { label: { position: 'top' } }, 60 | xAxis: { label: { angle: -0.7 } } 61 | } 62 | } 63 | }, 64 | { duration: 2 } 65 | )) 66 | 67 | .then(chart => chart.animate({ 68 | config: { 69 | channels: { 70 | y: { set: ['$count'] }, 71 | x: { set: ['Language'] }, 72 | label: { set: ['$count'] }, 73 | color: { set: ['Language'] } 74 | }, 75 | // '10 File count + types 2', 76 | sort: 'byValue', 77 | legend: null, 78 | reverse: true, 79 | }, 80 | style: { 81 | plot: { 82 | paddingLeft: '9em', 83 | marker: { label: { position: 'top' } }, 84 | xAxis: { label: { angle: -0.7 } } 85 | } 86 | } 87 | }, 88 | { duration: 0.5 } 89 | )); 90 | } 91 | -------------------------------------------------------------------------------- /media/scripts/anim-0100-0110.js: -------------------------------------------------------------------------------- 1 | function anim_0100_0110(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 | },// '13 File count 2', 11 | legend: null 12 | }, 13 | style: { 14 | plot: { 15 | paddingLeft: '9em', 16 | marker: { label: { position: 'center' } }, 17 | xAxis: { label: { angle: -0.7 } } 18 | } 19 | } 20 | }, 21 | { duration: 0.1 } 22 | ) 23 | 24 | .then(chart => chart.animate({ 25 | config: { 26 | channels: { 27 | y: { set: ['$count', 'Language', 'File name'] }, 28 | x: { set: null }, 29 | label: { set: null }, 30 | color: { set: ['Language'] } 31 | },// '12 File count 1', 32 | legend: null 33 | }, 34 | style: { 35 | plot: { 36 | paddingLeft: '9em', 37 | marker: { label: { position: 'center' } }, 38 | xAxis: { label: { angle: -0.7 } } 39 | } 40 | } 41 | }, 42 | { duration: 0.5 } 43 | )) 44 | 45 | .then(chart => chart.animate({ 46 | config: { 47 | channels: { 48 | y: { set: ['$count', 'File name'] }, 49 | x: { set: ['Language'] }, 50 | color: { set: ['Language'] } 51 | },// '9 File count + types 1', 52 | sort: 'byValue', 53 | legend: null, 54 | reverse: true, 55 | }, 56 | style: { 57 | plot: { 58 | paddingLeft: '9em', 59 | marker: { label: { position: 'top' } }, 60 | xAxis: { label: { angle: -0.7 } } 61 | } 62 | } 63 | }, 64 | { duration: 2 } 65 | )) 66 | 67 | .then(chart => chart.animate({ 68 | config: { 69 | channels: { 70 | y: { set: ['$count'] }, 71 | x: { set: ['Language'] }, 72 | label: { set: ['$count'] }, 73 | color: { set: ['Language'] } 74 | }, 75 | // '10 File count + types 2', 76 | sort: 'byValue', 77 | legend: null, 78 | reverse: true, 79 | }, 80 | style: { 81 | plot: { 82 | paddingLeft: '9em', 83 | marker: { label: { position: 'top' } }, 84 | xAxis: { label: { angle: -0.7 } } 85 | } 86 | } 87 | }, 88 | { duration: 0.5 } 89 | )); 90 | } 91 | -------------------------------------------------------------------------------- /docs/scripts/anim-0110-0100.js: -------------------------------------------------------------------------------- 1 | function anim_0110_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | label: { set: ['$count'] }, 9 | color: { set: ['Language'] } 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 | x: { set: ['Language'] }, 32 | color: { set: ['Language'] }, 33 | label: { set: null }, 34 | }, 35 | // '11 File count + type 3', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: true, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | marker: { label: { position: 'top' } }, 44 | xAxis: { label: { angle: -0.7 } } 45 | } 46 | } 47 | }, 48 | { duration: 0.5 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: ['$count', 'Language', 'File name'] }, 55 | x: { set: null }, 56 | label: { set: null }, 57 | color: { set: ['Language'] } 58 | }, 59 | // '12 File count 1', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | xAxis: { label: { angle: -0.7 } } 67 | } 68 | } 69 | }, 70 | { duration: 2 } 71 | )) 72 | 73 | .then(chart => chart.animate({ 74 | config: { 75 | channels: { 76 | y: { set: ['$count'] }, 77 | x: { set: null }, 78 | color: { set: null }, 79 | label: { set: ['$count'] }, 80 | }, 81 | // '13 File count 2', 82 | legend: null 83 | }, 84 | style: { 85 | plot: { 86 | paddingLeft: '9em', 87 | marker: { label: { position: 'center' } }, 88 | xAxis: { label: { angle: -0.7 } } 89 | } 90 | } 91 | }, 92 | { duration: 0.5 } 93 | )); 94 | } 95 | -------------------------------------------------------------------------------- /media/scripts/anim-0110-0100.js: -------------------------------------------------------------------------------- 1 | function anim_0110_0100(chart) { 2 | 3 | return chart.animate({ 4 | config: { 5 | channels: { 6 | y: { set: ['$count'] }, 7 | x: { set: ['Language'] }, 8 | label: { set: ['$count'] }, 9 | color: { set: ['Language'] } 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 | x: { set: ['Language'] }, 32 | color: { set: ['Language'] }, 33 | label: { set: null }, 34 | }, 35 | // '11 File count + type 3', 36 | sort: 'byValue', 37 | legend: null, 38 | reverse: true, 39 | }, 40 | style: { 41 | plot: { 42 | paddingLeft: '9em', 43 | marker: { label: { position: 'top' } }, 44 | xAxis: { label: { angle: -0.7 } } 45 | } 46 | } 47 | }, 48 | { duration: 0.5 } 49 | )) 50 | 51 | .then(chart => chart.animate({ 52 | config: { 53 | channels: { 54 | y: { set: ['$count', 'Language', 'File name'] }, 55 | x: { set: null }, 56 | label: { set: null }, 57 | color: { set: ['Language'] } 58 | }, 59 | // '12 File count 1', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | xAxis: { label: { angle: -0.7 } } 67 | } 68 | } 69 | }, 70 | { duration: 2 } 71 | )) 72 | 73 | .then(chart => chart.animate({ 74 | config: { 75 | channels: { 76 | y: { set: ['$count'] }, 77 | x: { set: null }, 78 | color: { set: null }, 79 | label: { set: ['$count'] }, 80 | }, 81 | // '13 File count 2', 82 | legend: null 83 | }, 84 | style: { 85 | plot: { 86 | paddingLeft: '9em', 87 | marker: { label: { position: 'center' } }, 88 | xAxis: { label: { angle: -0.7 } } 89 | } 90 | } 91 | }, 92 | { duration: 0.5 } 93 | )); 94 | } 95 | -------------------------------------------------------------------------------- /docs/scripts/anim-1010-1000.js: -------------------------------------------------------------------------------- 1 | function anim_1010_1000(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 | sort: 'byValue', 13 | reverse: false, 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 | y: { set: ['Language'] }, 31 | x: { set: ['Line count'] }, 32 | color: 'Language', 33 | label: { set: null }, 34 | }, 35 | // 3 code + types 1 36 | sort: 'byValue', 37 | reverse: false, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'right' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.5 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: null }, 54 | x: { set: ['Language', 'Line count'] }, 55 | color: 'Language', 56 | label: null 57 | }, 58 | // 2 code 2 59 | sort: 'byValue', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | yAxis: { label: { paddingRight: '1.2em' } }, 67 | xAxis: { label: { angle: 0 } } 68 | } 69 | } 70 | }, 71 | { duration: 2 } 72 | )) 73 | 74 | .then(chart => chart.animate({ 75 | config: { 76 | channels: { 77 | y: { set: null }, 78 | x: { set: ['Line count'] }, 79 | color: { set: null }, 80 | label: { set: ['Line count'] }, 81 | }, 82 | //1 code 1 83 | }, 84 | style: { 85 | legend: { paddingLeft: '5.789473684' }, 86 | plot: { 87 | paddingLeft: '9em', 88 | marker: { label: { position: 'center' } }, 89 | yAxis: { label: { paddingRight: '1.2em' } }, 90 | xAxis: { label: { angle: 0 } } 91 | } 92 | } 93 | }, 94 | { duration: 0.5 } 95 | )); 96 | } 97 | -------------------------------------------------------------------------------- /media/scripts/anim-1010-1000.js: -------------------------------------------------------------------------------- 1 | function anim_1010_1000(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 | sort: 'byValue', 13 | reverse: false, 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 | y: { set: ['Language'] }, 31 | x: { set: ['Line count'] }, 32 | color: 'Language', 33 | label: { set: null }, 34 | }, 35 | // 3 code + types 1 36 | sort: 'byValue', 37 | reverse: false, 38 | }, 39 | style: { 40 | plot: { 41 | paddingLeft: '9em', 42 | marker: { label: { position: 'right' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.5 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: null }, 54 | x: { set: ['Language', 'Line count'] }, 55 | color: 'Language', 56 | label: null 57 | }, 58 | // 2 code 2 59 | sort: 'byValue', 60 | legend: null 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'center' } }, 66 | yAxis: { label: { paddingRight: '1.2em' } }, 67 | xAxis: { label: { angle: 0 } } 68 | } 69 | } 70 | }, 71 | { duration: 2 } 72 | )) 73 | 74 | .then(chart => chart.animate({ 75 | config: { 76 | channels: { 77 | y: { set: null }, 78 | x: { set: ['Line count'] }, 79 | color: { set: null }, 80 | label: { set: ['Line count'] }, 81 | }, 82 | //1 code 1 83 | }, 84 | style: { 85 | legend: { paddingLeft: '5.789473684' }, 86 | plot: { 87 | paddingLeft: '9em', 88 | marker: { label: { position: 'center' } }, 89 | yAxis: { label: { paddingRight: '1.2em' } }, 90 | xAxis: { label: { angle: 0 } } 91 | } 92 | } 93 | }, 94 | { duration: 0.5 } 95 | )); 96 | } 97 | -------------------------------------------------------------------------------- /docs/scripts/anim-1000-1010.js: -------------------------------------------------------------------------------- 1 | function anim_1000_1010(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: 0.1 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: null }, 30 | x: { set: ['Language', 'Line count'] }, 31 | color: 'Language', 32 | label: null 33 | }, 34 | // 2 code 2 35 | sort: 'byValue', 36 | legend: null 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | marker: { label: { position: 'center' } }, 42 | yAxis: { label: { paddingRight: '1.2em' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.5 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: ['Language'] }, 54 | x: { set: ['Line count'] }, 55 | color: 'Language', 56 | label: { set: null }, 57 | }, 58 | // 3 code + types 1 59 | sort: 'byValue', 60 | reverse: false, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'right' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 2 } 71 | )) 72 | 73 | .then(chart => chart.animate({ 74 | config: { 75 | channels: { 76 | y: { set: ['Language'] }, 77 | x: { set: ['Line count'] }, 78 | color: 'Language', 79 | label: { set: ['Line count'] }, 80 | }, 81 | // '4 code + types 2', 82 | sort: 'byValue', 83 | reverse: false, 84 | }, 85 | style: { 86 | plot: { 87 | paddingLeft: '9em', 88 | marker: { label: { position: 'right' } }, 89 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 90 | xAxis: { label: { angle: 0 } } 91 | } 92 | } 93 | }, 94 | { duration: 0.5 } 95 | )); 96 | } 97 | -------------------------------------------------------------------------------- /media/scripts/anim-1000-1010.js: -------------------------------------------------------------------------------- 1 | function anim_1000_1010(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: 0.1 } 24 | ) 25 | 26 | .then(chart => chart.animate({ 27 | config: { 28 | channels: { 29 | y: { set: null }, 30 | x: { set: ['Language', 'Line count'] }, 31 | color: 'Language', 32 | label: null 33 | }, 34 | // 2 code 2 35 | sort: 'byValue', 36 | legend: null 37 | }, 38 | style: { 39 | plot: { 40 | paddingLeft: '9em', 41 | marker: { label: { position: 'center' } }, 42 | yAxis: { label: { paddingRight: '1.2em' } }, 43 | xAxis: { label: { angle: 0 } } 44 | } 45 | } 46 | }, 47 | { duration: 0.5 } 48 | )) 49 | 50 | .then(chart => chart.animate({ 51 | config: { 52 | channels: { 53 | y: { set: ['Language'] }, 54 | x: { set: ['Line count'] }, 55 | color: 'Language', 56 | label: { set: null }, 57 | }, 58 | // 3 code + types 1 59 | sort: 'byValue', 60 | reverse: false, 61 | }, 62 | style: { 63 | plot: { 64 | paddingLeft: '9em', 65 | marker: { label: { position: 'right' } }, 66 | xAxis: { label: { angle: 0 } } 67 | } 68 | } 69 | }, 70 | { duration: 2 } 71 | )) 72 | 73 | .then(chart => chart.animate({ 74 | config: { 75 | channels: { 76 | y: { set: ['Language'] }, 77 | x: { set: ['Line count'] }, 78 | color: 'Language', 79 | label: { set: ['Line count'] }, 80 | }, 81 | // '4 code + types 2', 82 | sort: 'byValue', 83 | reverse: false, 84 | }, 85 | style: { 86 | plot: { 87 | paddingLeft: '9em', 88 | marker: { label: { position: 'right' } }, 89 | yAxis: { label: { color: null, paddingRight: '1.2em' } }, 90 | xAxis: { label: { angle: 0 } } 91 | } 92 | } 93 | }, 94 | { duration: 0.5 } 95 | )); 96 | } 97 | -------------------------------------------------------------------------------- /media/scripts/uiLogic-controls.js: -------------------------------------------------------------------------------- 1 | function allDescendants(node, fn) { 2 | if (node == undefined || fn == undefined) 3 | return; 4 | for (var i = 0; i < node.childNodes.length; i++) { 5 | var child = node.childNodes[i]; 6 | allDescendants(child, fn); 7 | fn(child); 8 | } 9 | } 10 | 11 | function disableControls() { 12 | let ctrlDiv = document.getElementById("idControlDiv"); 13 | allDescendants(ctrlDiv, function(child) { 14 | child.disabled = true; 15 | }); 16 | const container = (document.getElementById('idBackLabel')); 17 | if (container != null) 18 | container.onclick = undefined; 19 | } 20 | 21 | function enableControls() { 22 | let ctrlDiv = document.getElementById("idControlDiv"); 23 | allDescendants(ctrlDiv, function(child) { 24 | child.disabled = false; 25 | }); 26 | const container = (document.getElementById('idBackLabel')); 27 | if (container != null) 28 | container.onclick = onLabelBack; 29 | } 30 | 31 | function onDisplayTypeChanged() { 32 | readAnimationVariables(); 33 | performAnimation(); 34 | } 35 | 36 | function onLabelBack() { 37 | performFilteringAnimationBw(); 38 | } 39 | 40 | function onCheckboxLanguages() { 41 | readAnimationVariables(); 42 | performAnimation(); 43 | } 44 | 45 | function onCheckboxFiles() { 46 | readAnimationVariables(); 47 | performAnimation(); 48 | } 49 | 50 | function onVizzuLogo() { 51 | vscode.postMessage({ command: 'openlink', text: 'https://github.com/vizzuhq/vizzu-lib' }); 52 | } 53 | 54 | function updateInfoLabelsContent(info) { 55 | let lines = info.codeCount + info.blankCount + info.commentCount; 56 | const date_label = (document.getElementById('label_date')); 57 | const dir_label = (document.getElementById('label_dir')); 58 | const files_label = (document.getElementById('label_files')); 59 | const lines_label = (document.getElementById('label_lines')); 60 | const code_label = (document.getElementById('label_code')); 61 | const comment_label = (document.getElementById('label_comment')); 62 | const blank_label = (document.getElementById('label_blank')); 63 | date_label.textContent = info.date; 64 | dir_label.textContent = info.rootDir; 65 | files_label.textContent = info.files.toString(); 66 | lines_label.textContent = lines.toString(); 67 | code_label.textContent = info.codeCount.toString(); 68 | comment_label.textContent = info.commentCount.toString(); 69 | blank_label.textContent = info.blankCount.toString(); 70 | } 71 | 72 | function readAnimationVariables() { 73 | const ctrl1 = document.getElementById('idLineCount'); 74 | state_lc = ctrl1.selected; 75 | const ctrl2 = document.getElementById('idFileCount'); 76 | state_fc = ctrl2.selected; 77 | const ctrl3 = (document.getElementById('idChkBoxFiles')); 78 | state_f = ctrl3.checked; 79 | const ctrl4 = (document.getElementById('idChkBoxLang')); 80 | state_l = ctrl4.checked; 81 | } 82 | 83 | function setFilesChekboxState(disabled, checked) { 84 | const ctrl = (document.getElementById('idChkBoxFiles')); 85 | ctrl.disabled = disabled; 86 | ctrl.checked = checked; 87 | } 88 | 89 | function setBackLabelState(disabled) { 90 | const container = (document.getElementById('idBackLabelContainer')); 91 | if (disabled) { 92 | container.innerHTML = ` 93 | Click on a folder below!    `; 94 | } 95 | else { 96 | container.innerHTML = ` 97 | 98 | Go back! 99 | 100 |     Folder: ${currentDirectory}`; 101 | } 102 | } -------------------------------------------------------------------------------- /docs/scripts/uiLogic-controls.js: -------------------------------------------------------------------------------- 1 | function allDescendants(node, fn) { 2 | if (node == undefined || fn == undefined) 3 | return; 4 | for (var i = 0; i < node.childNodes.length; i++) { 5 | var child = node.childNodes[i]; 6 | allDescendants(child, fn); 7 | fn(child); 8 | } 9 | } 10 | 11 | function disableControls() { 12 | let ctrlDiv = document.getElementById("idControlDiv"); 13 | allDescendants(ctrlDiv, function(child) { 14 | child.disabled = true; 15 | }); 16 | const container = (document.getElementById('idBackLabel')); 17 | if (container != null) 18 | container.onclick = undefined; 19 | } 20 | 21 | function enableControls() { 22 | let ctrlDiv = document.getElementById("idControlDiv"); 23 | allDescendants(ctrlDiv, function(child) { 24 | child.disabled = false; 25 | }); 26 | const container = (document.getElementById('idBackLabel')); 27 | if (container != null) 28 | container.onclick = onLabelBack; 29 | } 30 | 31 | function onDisplayTypeChanged() { 32 | readAnimationVariables(); 33 | performAnimation(); 34 | } 35 | 36 | function onLabelBack() { 37 | performFilteringAnimationBw(); 38 | } 39 | 40 | function onCheckboxLanguages() { 41 | readAnimationVariables(); 42 | performAnimation(); 43 | } 44 | 45 | function onCheckboxFiles() { 46 | readAnimationVariables(); 47 | performAnimation(); 48 | } 49 | 50 | function onVizzuLogo() { 51 | vscode.postMessage({ command: 'openlink', text: 'https://github.com/vizzuhq/vizzu-lib' }); 52 | } 53 | 54 | function updateInfoLabelsContent(info) { 55 | let lines = info.codeCount + info.blankCount + info.commentCount; 56 | const date_label = (document.getElementById('label_date')); 57 | const dir_label = (document.getElementById('label_dir')); 58 | const files_label = (document.getElementById('label_files')); 59 | const lines_label = (document.getElementById('label_lines')); 60 | const code_label = (document.getElementById('label_code')); 61 | const comment_label = (document.getElementById('label_comment')); 62 | const blank_label = (document.getElementById('label_blank')); 63 | date_label.textContent = info.date; 64 | dir_label.textContent = info.rootDir; 65 | files_label.textContent = info.files.toString(); 66 | lines_label.textContent = lines.toString(); 67 | code_label.textContent = info.codeCount.toString(); 68 | comment_label.textContent = info.commentCount.toString(); 69 | blank_label.textContent = info.blankCount.toString(); 70 | } 71 | 72 | function readAnimationVariables() { 73 | const ctrl1 = document.getElementById('idLineCount'); 74 | state_lc = ctrl1.selected; 75 | const ctrl2 = document.getElementById('idFileCount'); 76 | state_fc = ctrl2.selected; 77 | const ctrl3 = (document.getElementById('idChkBoxFiles')); 78 | state_f = ctrl3.checked; 79 | const ctrl4 = (document.getElementById('idChkBoxLang')); 80 | state_l = ctrl4.checked; 81 | } 82 | 83 | function setFilesChekboxState(disabled, checked) { 84 | const ctrl = (document.getElementById('idChkBoxFiles')); 85 | ctrl.disabled = disabled; 86 | ctrl.checked = checked; 87 | } 88 | 89 | function setBackLabelState(disabled) { 90 | const container = (document.getElementById('idBackLabelContainer')); 91 | if (disabled) { 92 | container.innerHTML = ` 93 | Click on a folder to zoom in    `; 94 | } 95 | else { 96 | container.innerHTML = ` 97 | 98 | Go back! 99 | 100 |     Folder: ${currentDirectory}`; 101 | } 102 | } -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | CodeViz Stat Demo 11 | 12 | 13 |

CodeViz Stat Demo

14 |

15 | date placeholder 16 |   -   17 | dir placeholder 18 |

19 |

20 | files:     21 | lines:     22 | code:     23 | comment:     24 | blank: 25 |

26 |
27 |
28 | 32 |
33 |
34 |
35 | Languages 36 | Files 37 |
38 |
39 |
40 |

41 |
42 | 43 |
44 |
45 |
46 | 47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/panels/ccvizzupanel.ts: -------------------------------------------------------------------------------- 1 | import { commands, Disposable, Webview, WebviewPanel, window, Uri, ViewColumn, env } from "vscode"; 2 | import { PageGenerator } from "./pagegen"; 3 | import { Summary } from "../data/vscc_result"; 4 | import { Console } from "console"; 5 | 6 | export class CCVizzuPanel { 7 | public static currentPanel: CCVizzuPanel | undefined; 8 | private _pageGen: PageGenerator; 9 | private readonly _panel: WebviewPanel; 10 | private _disposables: Disposable[] = []; 11 | private _dataTable: any; 12 | private _dataSummary: any; 13 | 14 | private constructor(panel: WebviewPanel, extensionUri: Uri) { 15 | this._panel = panel; 16 | this._panel.onDidDispose(this.dispose, null, this._disposables); 17 | this._setWebviewMessageListener(this._panel.webview); 18 | this._pageGen = new PageGenerator(panel, extensionUri); 19 | } 20 | 21 | public static export(folderPath: string) { 22 | if (CCVizzuPanel.currentPanel && this.currentPanel) { 23 | if (this.currentPanel._dataTable != undefined) 24 | CCVizzuPanel.currentPanel._jsonDataExport(folderPath); 25 | else 26 | window.showErrorMessage("No data to export"); 27 | } 28 | } 29 | 30 | public static import(folderPath: string) { 31 | if (CCVizzuPanel.currentPanel) { 32 | CCVizzuPanel.currentPanel._jsonDataImport(folderPath); 33 | if (this.currentPanel != undefined) { 34 | let panel = this.currentPanel._panel; 35 | panel.webview.postMessage({ 36 | command: 'clear-data-table' 37 | }); 38 | } 39 | } 40 | } 41 | 42 | public static refresh(data: Object, summ: Summary) { 43 | if (this.currentPanel != undefined) { 44 | this.currentPanel._dataTable = data; 45 | this.currentPanel._dataSummary = summ; 46 | let panel = this.currentPanel._panel; 47 | panel.reveal(ViewColumn.One); 48 | } 49 | } 50 | 51 | public static async render(extensionUri: Uri) { 52 | if (CCVizzuPanel.currentPanel) { 53 | CCVizzuPanel.currentPanel._panel.reveal(ViewColumn.One); 54 | } 55 | else { 56 | const panel = window.createWebviewPanel( 57 | "CodeViz", "CodeViz", 58 | ViewColumn.One, { 59 | enableScripts: true, 60 | }); 61 | let vizzu = new CCVizzuPanel(panel, extensionUri); 62 | CCVizzuPanel.currentPanel = vizzu; 63 | await vizzu._pageGen.generatePage(); 64 | vizzu._panel.webview.html = vizzu._pageGen.getHtmlContent(); 65 | } 66 | } 67 | 68 | public dispose() { 69 | CCVizzuPanel.currentPanel = undefined; 70 | this._panel.dispose(); 71 | while (this._disposables.length) { 72 | const disposable = this._disposables.pop(); 73 | if (disposable) { 74 | disposable.dispose(); 75 | } 76 | } 77 | } 78 | 79 | private _setWebviewMessageListener(webview: Webview) { 80 | webview.onDidReceiveMessage( 81 | (message: any) => { 82 | const command = message.command; 83 | const text = message.text; 84 | switch (command) { 85 | case "vizzu-ready": 86 | this._panel.webview.postMessage({ 87 | command: 'refresh-data-table', 88 | dataTable: this._dataTable, 89 | dataSummary: this._dataSummary 90 | }); 91 | return; 92 | case "showinexplorer": 93 | let uri = Uri.parse(this._dataSummary.rootDir); 94 | uri = Uri.joinPath(uri, text); 95 | commands.executeCommand('revealInExplorer', uri); 96 | return; 97 | case "openlink": 98 | env.openExternal(Uri.parse(text)); 99 | return; 100 | case "showinfo": 101 | window.showInformationMessage(text); 102 | return; 103 | case "showerror": 104 | window.showErrorMessage(text); 105 | return; 106 | case "statusbarmsg": 107 | window.setStatusBarMessage(text, 108 | new Promise((resolve, reject) => { 109 | setTimeout(() => { resolve(true); }, message.timeout); 110 | })); 111 | } 112 | }, 113 | undefined, 114 | this._disposables 115 | ); 116 | } 117 | 118 | private _jsonDataImport(rootDir: string) { 119 | if (rootDir.endsWith('/')) 120 | rootDir = rootDir.substring(0, rootDir.length - 1); 121 | this._dataTable = {}; 122 | this._dataSummary = {}; 123 | const fs = require('fs'); 124 | const text1 = fs.readFileSync(rootDir + '/data.json', {encoding:'utf8', flag:'r'}); 125 | this._dataTable = JSON.parse(text1); 126 | const text2 = fs.readFileSync(rootDir + '/datasum.json', {encoding:'utf8', flag:'r'}); 127 | this._dataSummary = JSON.parse(text2); 128 | } 129 | 130 | private _jsonDataExport(rootDir: string) { 131 | if (rootDir.endsWith('/')) 132 | rootDir = rootDir.substring(0, rootDir.length - 1); 133 | var fs = require('fs'); 134 | fs.writeFile(rootDir + '/data.json', 135 | JSON.stringify(this._dataTable), function(err: Object) { 136 | if (err) 137 | console.log(err); 138 | } 139 | ); 140 | var fs = require('fs'); 141 | fs.writeFile(rootDir + '/datasum.json', 142 | JSON.stringify(this._dataSummary), function(err: Object) { 143 | if (err) 144 | console.log(err); 145 | } 146 | ); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /src/data/vscc_dataprep.ts: -------------------------------------------------------------------------------- 1 | import { Uri } from "vscode"; 2 | import { Result } from "./vscc_result"; 3 | 4 | interface IStringIndex { 5 | [key: string]: any 6 | } 7 | 8 | export class VSCCDataPrep { 9 | public fileCount: number = 0; 10 | public codeLinesCount: number = 0; 11 | public blankLinesCount: number = 0; 12 | public commentLinesCount: number = 0; 13 | public dirStructureDepth: number = 0; 14 | private _vizzuDataTable: any = {}; 15 | private _pathFragments: Array> = []; 16 | 17 | public constructor() { 18 | this._vizzuDataTable = { series: [], records: [] }; 19 | } 20 | 21 | makeDataTable(rawData: Object) { 22 | let data = rawData as IStringIndex; 23 | let codeCounterData: Result[] = []; 24 | for(var propertyName in rawData) { 25 | let item: Result = new Result; 26 | item.uri = Uri.parse(propertyName); 27 | item.language = data[propertyName]['language']; 28 | item.code = data[propertyName]['code']; 29 | item.blank = data[propertyName]['blank']; 30 | item.comment = data[propertyName]['comment']; 31 | item.filename = item.uri.path; 32 | codeCounterData.push(item); 33 | } 34 | codeCounterData.sort((a: Result, b: Result) => { 35 | return a.uri < b.uri ? 1 : ( a.uri > b.uri ? -1 : 0); 36 | }); 37 | this.preparePathFragments(codeCounterData); 38 | this.removeRedundantPathFragments(); 39 | this.dirStructureDepth = this.getDirStructureDepth(); 40 | this.generatePathSequences(); 41 | this.generateTableStructure(); 42 | this.generateRecords(codeCounterData); 43 | } 44 | 45 | sortByLanguagesAndLinesCount(codeCounterData: Result[]) { 46 | let sorted: Array = []; 47 | let temp: Array> = []; 48 | for(let i = 0; i < codeCounterData.length; i++) { 49 | let inserted: boolean = false; 50 | let record = codeCounterData[i]; 51 | for(let j = 0; j < temp.length; j++) { 52 | if (temp[j][0].language == record.language) { 53 | for(let k = 0; k < temp[j].length; k++) { 54 | if (record.code > temp[j][k].code) { 55 | temp[j].splice(k, 0, record); 56 | inserted = true; 57 | break; 58 | } 59 | } 60 | if (!inserted) { 61 | temp[j].push(record); 62 | inserted = true; 63 | break; 64 | } 65 | } 66 | } 67 | if (!inserted) { 68 | let empty = []; 69 | empty.push(record); 70 | temp.push(empty); 71 | } 72 | } 73 | for(let i = 0; i < temp.length; i++) 74 | for(let j = 0; j < temp[i].length; j++) 75 | sorted.push(temp[i][j]); 76 | return sorted; 77 | } 78 | 79 | generateRecords(codeCounterData: Result[]) { 80 | for(let i = 0; i < codeCounterData.length; i++) { 81 | let vizzuRecord = new Array(); 82 | let ccRecord = codeCounterData[i]; 83 | let file = new String(ccRecord.uri.toString().split('/').pop()); 84 | vizzuRecord.push(new String(file)); 85 | vizzuRecord.push(new String(ccRecord.language)); 86 | vizzuRecord.push(new String(ccRecord.code.toString())); 87 | vizzuRecord.push(new String(ccRecord.comment.toString())); 88 | vizzuRecord.push(new String(ccRecord.blank.toString())); 89 | let frags = this._pathFragments[i]; 90 | let depth = frags.length; 91 | for(let j = 0; j < depth; j++) 92 | vizzuRecord.push(frags[j]); 93 | vizzuRecord[0] = new String(frags[depth - 1].valueOf() + vizzuRecord[0]); 94 | this._vizzuDataTable.records.push(vizzuRecord); 95 | this.fileCount++; 96 | this.codeLinesCount += ccRecord.code; 97 | this.blankLinesCount += ccRecord.blank; 98 | this.commentLinesCount += ccRecord.comment; 99 | } 100 | } 101 | 102 | generateTableStructure() { 103 | this._vizzuDataTable.series.push({ name: 'File name', type: 'dimension' }); 104 | this._vizzuDataTable.series.push({ name: 'Language', type: 'dimension' }); 105 | this._vizzuDataTable.series.push({ name: 'Line count', type: 'measure' }); 106 | this._vizzuDataTable.series.push({ name: 'blank', type: 'measure' }); 107 | this._vizzuDataTable.series.push({ name: 'comment', type: 'measure' }); 108 | for(let i = 0; i < this.dirStructureDepth; i++) { 109 | this._vizzuDataTable.series.push({ name: 'Folder level ' + i, type: 'dimension' }); 110 | } 111 | } 112 | 113 | preparePathFragments(codeCounterData: Result[]) { 114 | this._pathFragments = []; 115 | codeCounterData.forEach( 116 | ({ uri }) => { 117 | let path = uri.toString(); 118 | let frags = path.split('/'); 119 | let storage = new Array(); 120 | frags.pop(); 121 | frags.splice(0, 3); 122 | frags.forEach((str) => storage.push(new String(str))); 123 | this._pathFragments.push(storage); 124 | } 125 | ); 126 | } 127 | 128 | removeRedundantPathFragments() { 129 | let ref = this._pathFragments[0]; 130 | for(let same = this._pathFragments.length > 1; same;) { 131 | this._pathFragments.forEach( 132 | (comp) => { 133 | if (comp[0] == undefined) 134 | same = false; 135 | if (same && ref[0].valueOf() != comp[0].valueOf()) 136 | same = false; 137 | } 138 | ); 139 | if (same) 140 | this._pathFragments.forEach( 141 | (item) => item.splice(0, 1) 142 | ); 143 | } 144 | } 145 | 146 | getDirStructureDepth() { 147 | let depth = 0; 148 | this._pathFragments.forEach( 149 | (frags) => { 150 | if (frags.length > depth) 151 | depth = frags.length; 152 | } 153 | ); 154 | return depth; 155 | } 156 | 157 | generatePathSequences() { 158 | for(let i = 0; i < this._pathFragments.length; i++) { 159 | let prefix = './'; 160 | let currentDepth = 0; 161 | var frags = this._pathFragments[i]; 162 | for(let j = 0; j < frags.length; j++) { 163 | currentDepth++; 164 | let temp = frags[j]; 165 | frags[j] = new String(prefix + frags[j] + '/'); 166 | if (prefix.length != 0) 167 | prefix = prefix + temp + '/'; 168 | else 169 | prefix = temp.valueOf() + '/'; 170 | } 171 | for(let i = this.dirStructureDepth - currentDepth; i > 0; i--) 172 | frags.push(new String(prefix)); 173 | } 174 | } 175 | 176 | getDataTable() { 177 | return this._vizzuDataTable; 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /docs/scripts/uiLogic-animations.js: -------------------------------------------------------------------------------- 1 | let inTransientState = false; 2 | let navAnimationType = 'initial'; 3 | let state_f_disabled = false; 4 | let state_f_restore = false; 5 | 6 | let state_l = true; 7 | let state_f = false; 8 | let state_lc = true; 9 | let state_fc = false; 10 | 11 | let last_state_l = true; 12 | let last_state_f = false; 13 | let last_state_lc = true; 14 | let last_state_fc = false; 15 | 16 | let dirFilter = []; 17 | let dirMaxDepth = 0; 18 | let databaseFileCount = 0; 19 | let paralellAnimLimit = 1500; 20 | let currentDirectory = 'workspace'; 21 | let statusBarTimer = null; 22 | let progressTimer = null; 23 | let progressState = 0; 24 | let delayBeforeProgress = 4000; 25 | 26 | function busyPromise(fn) { 27 | let _resolve; 28 | let timeout; 29 | let promise = new Promise((resolve, reject) => { 30 | _resolve = resolve; 31 | timeout = setTimeout(() => {}, 10000); 32 | }); 33 | return { 34 | promise, 35 | exec(ready) { 36 | fn().then(() => { 37 | if (ready != undefined) 38 | ready(); 39 | clearTimeout(timeout); 40 | timeout = null; 41 | _resolve(); 42 | }); 43 | } 44 | }; 45 | }; 46 | 47 | function performInitAnimation(info) { 48 | if (!enterTransientState()) 49 | return; 50 | let promise1 = anim_init(infoChart); 51 | let promise2 = nav_anim_init(navChart); 52 | databaseFileCount = info.files; 53 | Promise.all([promise1, promise2]).then( () => leaveTransientState() ); 54 | } 55 | 56 | function performAnimation() { 57 | if (!enterTransientState()) 58 | return; 59 | navAnimationType = selectNavAnimationType(); 60 | if (databaseFileCount < paralellAnimLimit) 61 | paralellAnim(); 62 | else 63 | serialAnim(); 64 | updateAnimationVariables(); 65 | } 66 | 67 | function performFilteringAnimationFw(event) { 68 | navAnimationType = 'navFw'; 69 | if (event.data.marker != undefined) { 70 | if (dirMaxDepth > dirFilter.length) { 71 | let level = dirFilter.length; 72 | let levelStr = 'Folder level ' + level.toString(); 73 | let filterStr = event.data.marker.categories[levelStr]; 74 | currentDirectory = 'workspace' + filterStr.substring(1); 75 | setBackLabelState(false); 76 | if (dirFilter[dirFilter.length - 1] == filterStr) { 77 | vscode.postMessage({ command: 'showinfo', text: 'No more folder under this level!' }); 78 | enableControls(); 79 | } 80 | else { 81 | dirFilter.push(filterStr); 82 | applyFilterFw(); 83 | vscode.postMessage({ command: 'showinexplorer', text: filterStr }); 84 | } 85 | } 86 | else 87 | vscode.postMessage({ command: 'showinfo', text: 'No more folder under this level!' }); 88 | } 89 | } 90 | 91 | function performFilteringAnimationBw() { 92 | navAnimationType = 'navBw'; 93 | if (dirFilter.length > 0) { 94 | enterTransientState(); 95 | if (dirMaxDepth > dirFilter.length) { 96 | if (state_lc) 97 | nav_anim_10xx_filter_bw(navChart, dirFilter.length - 1).then(() => { 98 | applyFilterBw(); 99 | }); 100 | else 101 | nav_anim_01xx_filter_bw(navChart, dirFilter.length - 1).then(() => { 102 | applyFilterBw(); 103 | }); 104 | } 105 | else { 106 | applyFilterBw(); 107 | } 108 | } 109 | } 110 | 111 | function startProgressIndication() { 112 | statusBarTimer = setTimeout(() => { 113 | statusBarTimer = null; 114 | progressTimer = setInterval(() => { 115 | let msg = { 116 | command: 'statusbarmsg', 117 | text: 'CodeViz animation is in progress', 118 | timeout: 310 119 | }; 120 | if (progressState == 0) 121 | msg.text += '.' 122 | if (progressState == 1) 123 | msg.text += '..' 124 | if (progressState == 2) 125 | msg.text += '...' 126 | vscode.postMessage(msg); 127 | progressState++; 128 | if (progressState == 3) 129 | progressState = 0; 130 | }, 300); 131 | }, delayBeforeProgress); 132 | } 133 | 134 | function stopProgressIndication() { 135 | if (progressTimer != null) 136 | clearTimeout(progressTimer); 137 | progressTimer = null; 138 | if (statusBarTimer != null) { 139 | clearTimeout(statusBarTimer); 140 | } 141 | else { 142 | vscode.postMessage({ 143 | command: 'statusbarmsg', 144 | text: 'CodeViz is ready.', 145 | timeout: 2000 }); 146 | } 147 | } 148 | 149 | function enterTransientState() { 150 | if (inTransientState) 151 | return false; 152 | disableControls(); 153 | inTransientState = true; 154 | startProgressIndication(); 155 | return true; 156 | } 157 | 158 | function leaveTransientState() { 159 | if (!inTransientState) 160 | return false; 161 | enableControls(); 162 | if (navAnimationType == 'switchToLineCount') 163 | setFilesChekboxState(false, state_f_restore); 164 | if (state_f_disabled) 165 | setFilesChekboxState(true, false); 166 | inTransientState = false; 167 | stopProgressIndication(); 168 | return true; 169 | } 170 | 171 | function encodeAnimFunctionName() { 172 | let state = ''; 173 | let lastState = ''; 174 | state += state_lc ? '1' : '0'; 175 | state += state_fc ? '1' : '0'; 176 | state += state_l ? '1' : '0'; 177 | state += state_f ? '1' : '0'; 178 | lastState += last_state_lc ? '1' : '0'; 179 | lastState += last_state_fc ? '1' : '0'; 180 | lastState += last_state_l ? '1' : '0'; 181 | lastState += last_state_f ? '1' : '0'; 182 | return 'anim_' + lastState + '_' + state; 183 | } 184 | 185 | function selectNavAnimationType() { 186 | let type = 'none'; 187 | if (state_fc == true && last_state_fc == false) { 188 | type = 'switchToFileCount'; 189 | state_f_disabled = true; 190 | state_f_restore = state_f; 191 | state_f = false; 192 | } 193 | if (state_fc == false && last_state_fc == true) { 194 | type = 'switchToLineCount'; 195 | state_f = state_f_restore; 196 | state_f_disabled = false; 197 | } 198 | return type; 199 | } 200 | 201 | function updateAnimationVariables() { 202 | last_state_l = state_l; 203 | last_state_f = state_f; 204 | last_state_lc = state_lc; 205 | last_state_fc = state_fc; 206 | } 207 | 208 | function applyFilter() { 209 | let filter1 = busyPromise(() => { 210 | return nav_anim_record_filter(infoChart, (record) => selectRecord(record)); 211 | }); 212 | let filter2 = busyPromise(() => { 213 | return nav_anim_record_filter(navChart, (record) => selectRecord(record)); 214 | }); 215 | // always paralell 216 | if (true || databaseFileCount < paralellAnimLimit) { 217 | filter1.exec(); 218 | filter2.exec(); 219 | } 220 | else { 221 | filter1.exec(() => { 222 | filter2.exec(); 223 | }); 224 | } 225 | return [ filter1, filter2 ]; 226 | } 227 | 228 | function applyFilterFw() { 229 | enterTransientState(); 230 | let promises = applyFilter(); 231 | Promise.all([promises[0].promise, promises[1].promise]).then(() => { 232 | if (dirMaxDepth > dirFilter.length) { 233 | if (state_lc) 234 | nav_anim_10xx_filter_fw(navChart, dirFilter.length).then(() => leaveTransientState()); 235 | else 236 | nav_anim_01xx_filter_fw(navChart, dirFilter.length).then(() => leaveTransientState()); 237 | } 238 | else 239 | leaveTransientState(); 240 | }); 241 | } 242 | 243 | function applyFilterBw() { 244 | let filterStr = ''; 245 | dirFilter.pop(); 246 | if (dirFilter == 0) 247 | setBackLabelState(true); 248 | else { 249 | filterStr = dirFilter[dirFilter.length - 1]; 250 | currentDirectory = 'workspace' + filterStr.substring(1); 251 | setBackLabelState(false); 252 | } 253 | let promises = applyFilter(); 254 | Promise.all([promises[0].promise, promises[1].promise]).then(() => { 255 | leaveTransientState(); 256 | if (filterStr != '') { 257 | vscode.postMessage({ command: 'showinexplorer', text: filterStr }); 258 | } 259 | }); 260 | } 261 | 262 | function selectRecord(record) { 263 | for(let i = 0; i < dirFilter.length; i++) { 264 | let name = 'Folder level ' + i; 265 | let value = dirFilter[i]; 266 | if (record[name] != value) 267 | return false; 268 | } 269 | return true; 270 | } 271 | 272 | function navLabelDrawHandler(event) { 273 | let tmp = []; 274 | let label = event.data.text; 275 | if (label == dirFilter[dirFilter.length - 1]) 276 | label = './'; 277 | else 278 | tmp = label.split('/'); 279 | if (tmp.length >= 2) 280 | label = tmp[tmp.length - 2]; 281 | if (label == '.') 282 | label = './'; 283 | let textRect = event.renderingContext.measureText(label); 284 | let height = textRect.actualBoundingBoxAscent; 285 | event.renderingContext.fillText(label, 286 | event.data.rect.pos.x + event.data.rect.size.x - textRect.width, 287 | event.data.rect.pos.y + event.data.rect.size.y - height / 2); 288 | event.preventDefault(); 289 | } 290 | 291 | function paralellAnim() { 292 | let promise1 = Promise.resolve(); 293 | if (navAnimationType == 'switchToLineCount') { 294 | promise1 = nav_anim_01xx_10xx(navChart, dirFilter.length); 295 | } 296 | else if (navAnimationType == 'switchToFileCount') { 297 | promise1 = nav_anim_10xx_01xx(navChart, dirFilter.length); 298 | } 299 | let promise2 = window[encodeAnimFunctionName()](infoChart); 300 | Promise.all([promise1, promise2]).then(() => { 301 | leaveTransientState(); 302 | if (navAnimationType == 'switchToLineCount') 303 | state_f_restore = false; 304 | }); 305 | } 306 | 307 | function serialAnim() { 308 | let fnName = encodeAnimFunctionName(); 309 | if (navAnimationType == 'switchToLineCount') { 310 | nav_anim_01xx_10xx(navChart, dirFilter.length).then(() => { 311 | window[fnName](infoChart).then(() => { 312 | leaveTransientState(); 313 | state_f_restore = false; 314 | }); 315 | }); 316 | } 317 | else if (navAnimationType == 'switchToFileCount') { 318 | nav_anim_10xx_01xx(navChart, dirFilter.length).then(() => { 319 | window[fnName](infoChart).then(() => { 320 | leaveTransientState(); 321 | }); 322 | }); 323 | } 324 | else { 325 | window[fnName](infoChart).then(() => { 326 | leaveTransientState(); 327 | }); 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /media/scripts/uiLogic-animations.js: -------------------------------------------------------------------------------- 1 | let inTransientState = false; 2 | let navAnimationType = 'initial'; 3 | let state_f_disabled = false; 4 | let state_f_restore = false; 5 | 6 | let state_l = true; 7 | let state_f = false; 8 | let state_lc = true; 9 | let state_fc = false; 10 | 11 | let last_state_l = true; 12 | let last_state_f = false; 13 | let last_state_lc = true; 14 | let last_state_fc = false; 15 | 16 | let dirFilter = []; 17 | let dirMaxDepth = 0; 18 | let databaseFileCount = 0; 19 | let paralellAnimLimit = 1500; 20 | let currentDirectory = 'workspace'; 21 | let statusBarTimer = null; 22 | let progressTimer = null; 23 | let progressState = 0; 24 | let delayBeforeProgress = 4000; 25 | 26 | function busyPromise(fn) { 27 | let _resolve; 28 | let timeout; 29 | let promise = new Promise((resolve, reject) => { 30 | _resolve = resolve; 31 | timeout = setTimeout(() => {}, 10000); 32 | }); 33 | return { 34 | promise, 35 | exec(ready) { 36 | fn().then(() => { 37 | if (ready != undefined) 38 | ready(); 39 | clearTimeout(timeout); 40 | timeout = null; 41 | _resolve(); 42 | }); 43 | } 44 | }; 45 | }; 46 | 47 | function performInitAnimation(info) { 48 | if (!enterTransientState()) 49 | return; 50 | let promise1 = anim_init(infoChart); 51 | let promise2 = nav_anim_init(navChart); 52 | databaseFileCount = info.files; 53 | Promise.all([promise1, promise2]).then( () => leaveTransientState() ); 54 | } 55 | 56 | function performAnimation() { 57 | if (!enterTransientState()) 58 | return; 59 | navAnimationType = selectNavAnimationType(); 60 | if (databaseFileCount < paralellAnimLimit) 61 | paralellAnim(); 62 | else 63 | serialAnim(); 64 | updateAnimationVariables(); 65 | } 66 | 67 | function performFilteringAnimationFw(event) { 68 | navAnimationType = 'navFw'; 69 | if (event.data.marker != undefined) { 70 | if (dirMaxDepth > dirFilter.length) { 71 | let level = dirFilter.length; 72 | let levelStr = 'Folder level ' + level.toString(); 73 | let filterStr = event.data.marker.categories[levelStr]; 74 | currentDirectory = 'workspace' + filterStr.substring(1); 75 | setBackLabelState(false); 76 | if (dirFilter[dirFilter.length - 1] == filterStr) { 77 | vscode.postMessage({ command: 'showinfo', text: 'No more folder under this level!' }); 78 | enableControls(); 79 | } 80 | else { 81 | dirFilter.push(filterStr); 82 | applyFilterFw(); 83 | vscode.postMessage({ command: 'showinexplorer', text: filterStr }); 84 | } 85 | } 86 | else 87 | vscode.postMessage({ command: 'showinfo', text: 'No more folder under this level!' }); 88 | } 89 | } 90 | 91 | function performFilteringAnimationBw() { 92 | navAnimationType = 'navBw'; 93 | if (dirFilter.length > 0) { 94 | enterTransientState(); 95 | if (dirMaxDepth > dirFilter.length) { 96 | if (state_lc) 97 | nav_anim_10xx_filter_bw(navChart, dirFilter.length - 1).then(() => { 98 | applyFilterBw(); 99 | }); 100 | else 101 | nav_anim_01xx_filter_bw(navChart, dirFilter.length - 1).then(() => { 102 | applyFilterBw(); 103 | }); 104 | } 105 | else { 106 | applyFilterBw(); 107 | } 108 | } 109 | } 110 | 111 | function startProgressIndication() { 112 | statusBarTimer = setTimeout(() => { 113 | statusBarTimer = null; 114 | progressTimer = setInterval(() => { 115 | let msg = { 116 | command: 'statusbarmsg', 117 | text: 'CodeViz animation is in progress', 118 | timeout: 310 119 | }; 120 | if (progressState == 0) 121 | msg.text += '.' 122 | if (progressState == 1) 123 | msg.text += '..' 124 | if (progressState == 2) 125 | msg.text += '...' 126 | vscode.postMessage(msg); 127 | progressState++; 128 | if (progressState == 3) 129 | progressState = 0; 130 | }, 300); 131 | }, delayBeforeProgress); 132 | } 133 | 134 | function stopProgressIndication() { 135 | if (progressTimer != null) 136 | clearTimeout(progressTimer); 137 | progressTimer = null; 138 | if (statusBarTimer != null) { 139 | clearTimeout(statusBarTimer); 140 | } 141 | else { 142 | vscode.postMessage({ 143 | command: 'statusbarmsg', 144 | text: 'CodeViz is ready.', 145 | timeout: 2000 }); 146 | } 147 | } 148 | 149 | function enterTransientState() { 150 | if (inTransientState) 151 | return false; 152 | disableControls(); 153 | inTransientState = true; 154 | startProgressIndication(); 155 | return true; 156 | } 157 | 158 | function leaveTransientState() { 159 | if (!inTransientState) 160 | return false; 161 | enableControls(); 162 | if (navAnimationType == 'switchToLineCount') 163 | setFilesChekboxState(false, state_f_restore); 164 | if (state_f_disabled) 165 | setFilesChekboxState(true, false); 166 | inTransientState = false; 167 | stopProgressIndication(); 168 | return true; 169 | } 170 | 171 | function encodeAnimFunctionName() { 172 | let state = ''; 173 | let lastState = ''; 174 | state += state_lc ? '1' : '0'; 175 | state += state_fc ? '1' : '0'; 176 | state += state_l ? '1' : '0'; 177 | state += state_f ? '1' : '0'; 178 | lastState += last_state_lc ? '1' : '0'; 179 | lastState += last_state_fc ? '1' : '0'; 180 | lastState += last_state_l ? '1' : '0'; 181 | lastState += last_state_f ? '1' : '0'; 182 | return 'anim_' + lastState + '_' + state; 183 | } 184 | 185 | function selectNavAnimationType() { 186 | let type = 'none'; 187 | if (state_fc == true && last_state_fc == false) { 188 | type = 'switchToFileCount'; 189 | state_f_disabled = true; 190 | state_f_restore = state_f; 191 | state_f = false; 192 | } 193 | if (state_fc == false && last_state_fc == true) { 194 | type = 'switchToLineCount'; 195 | state_f = state_f_restore; 196 | state_f_disabled = false; 197 | } 198 | return type; 199 | } 200 | 201 | function updateAnimationVariables() { 202 | last_state_l = state_l; 203 | last_state_f = state_f; 204 | last_state_lc = state_lc; 205 | last_state_fc = state_fc; 206 | } 207 | 208 | function applyFilter() { 209 | let filter1 = busyPromise(() => { 210 | return nav_anim_record_filter(infoChart, (record) => selectRecord(record)); 211 | }); 212 | let filter2 = busyPromise(() => { 213 | return nav_anim_record_filter(navChart, (record) => selectRecord(record)); 214 | }); 215 | // always paralell 216 | if (true || databaseFileCount < paralellAnimLimit) { 217 | filter1.exec(); 218 | filter2.exec(); 219 | } 220 | else { 221 | filter1.exec(() => { 222 | filter2.exec(); 223 | }); 224 | } 225 | return [ filter1, filter2 ]; 226 | } 227 | 228 | function applyFilterFw() { 229 | enterTransientState(); 230 | let promises = applyFilter(); 231 | Promise.all([promises[0].promise, promises[1].promise]).then(() => { 232 | if (dirMaxDepth > dirFilter.length) { 233 | if (state_lc) 234 | nav_anim_10xx_filter_fw(navChart, dirFilter.length).then(() => leaveTransientState()); 235 | else 236 | nav_anim_01xx_filter_fw(navChart, dirFilter.length).then(() => leaveTransientState()); 237 | } 238 | else 239 | leaveTransientState(); 240 | }); 241 | } 242 | 243 | function applyFilterBw() { 244 | let filterStr = ''; 245 | dirFilter.pop(); 246 | if (dirFilter == 0) 247 | setBackLabelState(true); 248 | else { 249 | filterStr = dirFilter[dirFilter.length - 1]; 250 | currentDirectory = 'workspace' + filterStr.substring(1); 251 | setBackLabelState(false); 252 | } 253 | let promises = applyFilter(); 254 | Promise.all([promises[0].promise, promises[1].promise]).then(() => { 255 | leaveTransientState(); 256 | if (filterStr != '') { 257 | vscode.postMessage({ command: 'showinexplorer', text: filterStr }); 258 | } 259 | }); 260 | } 261 | 262 | function selectRecord(record) { 263 | for(let i = 0; i < dirFilter.length; i++) { 264 | let name = 'Folder level ' + i; 265 | let value = dirFilter[i]; 266 | if (record[name] != value) 267 | return false; 268 | } 269 | return true; 270 | } 271 | 272 | function navLabelDrawHandler(event) { 273 | let tmp = []; 274 | let label = event.data.text; 275 | if (label == dirFilter[dirFilter.length - 1]) 276 | label = './'; 277 | else 278 | tmp = label.split('/'); 279 | if (tmp.length >= 2) 280 | label = tmp[tmp.length - 2]; 281 | if (label == '.') 282 | label = './'; 283 | let textRect = event.renderingContext.measureText(label); 284 | let height = textRect.actualBoundingBoxAscent; 285 | event.renderingContext.fillText(label, 286 | event.data.rect.pos.x + event.data.rect.size.x - textRect.width, 287 | event.data.rect.pos.y + event.data.rect.size.y - height / 2); 288 | event.preventDefault(); 289 | } 290 | 291 | function paralellAnim() { 292 | let promise1 = Promise.resolve(); 293 | if (navAnimationType == 'switchToLineCount') { 294 | promise1 = nav_anim_01xx_10xx(navChart, dirFilter.length); 295 | } 296 | else if (navAnimationType == 'switchToFileCount') { 297 | promise1 = nav_anim_10xx_01xx(navChart, dirFilter.length); 298 | } 299 | let promise2 = window[encodeAnimFunctionName()](infoChart); 300 | Promise.all([promise1, promise2]).then(() => { 301 | leaveTransientState(); 302 | if (navAnimationType == 'switchToLineCount') 303 | state_f_restore = false; 304 | }); 305 | } 306 | 307 | function serialAnim() { 308 | let fnName = encodeAnimFunctionName(); 309 | if (navAnimationType == 'switchToLineCount') { 310 | nav_anim_01xx_10xx(navChart, dirFilter.length).then(() => { 311 | window[fnName](infoChart).then(() => { 312 | leaveTransientState(); 313 | state_f_restore = false; 314 | }); 315 | }); 316 | } 317 | else if (navAnimationType == 'switchToFileCount') { 318 | nav_anim_10xx_01xx(navChart, dirFilter.length).then(() => { 319 | window[fnName](infoChart).then(() => { 320 | leaveTransientState(); 321 | }); 322 | }); 323 | } 324 | else { 325 | window[fnName](infoChart).then(() => { 326 | leaveTransientState(); 327 | }); 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /docs/PyScript-data.json: -------------------------------------------------------------------------------- 1 | {"series":[{"name":"File name","type":"dimension"},{"name":"Language","type":"dimension"},{"name":"Line count","type":"measure"},{"name":"blank","type":"measure"},{"name":"comment","type":"measure"},{"name":"Folder level 0","type":"dimension"},{"name":"Folder level 1","type":"dimension"},{"name":"Folder level 2","type":"dimension"},{"name":"Folder level 3","type":"dimension"},{"name":"Folder level 4","type":"dimension"}],"records":[["./setup.cfg","Properties","8","0","2","./","./","./","./","./"],["./pyscriptjs/tsconfig.json","JSON with Comments","16","13","2","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/tests/test_examples.py","Python","158","20","21","./pyscriptjs/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/"],["./pyscriptjs/tests/conftest.py","Python","26","8","11","./pyscriptjs/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/"],["./pyscriptjs/tests/__init__.py","Python","0","0","1","./pyscriptjs/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/","./pyscriptjs/tests/"],["./pyscriptjs/tailwind.config.js","JavaScript","28","0","2","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/src/utils.ts","TypeScript","66","6","12","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/"],["./pyscriptjs/src/stores.ts","TypeScript","46","0","12","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/"],["./pyscriptjs/src/pyscript.py","Python","325","18","95","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/"],["./pyscriptjs/src/main.ts","TypeScript","34","2","7","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/"],["./pyscriptjs/src/interpreter.ts","TypeScript","47","6","10","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/","./pyscriptjs/src/"],["./pyscriptjs/src/components/pytitle.ts","TypeScript","27","0","6","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyscript.ts","TypeScript","133","29","30","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyrepl.ts","TypeScript","174","12","46","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyloader.ts","TypeScript","34","0","5","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyinputbox.ts","TypeScript","41","4","8","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyenv.ts","TypeScript","64","2","15","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pyconfig.ts","TypeScript","164","7","29","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pybutton.ts","TypeScript","61","4","12","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/pybox.ts","TypeScript","46","8","10","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/src/components/base.ts","TypeScript","304","26","56","./pyscriptjs/","./pyscriptjs/src/","./pyscriptjs/src/components/","./pyscriptjs/src/components/","./pyscriptjs/src/components/"],["./pyscriptjs/rollup.config.js","JavaScript","62","3","3","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/package.json","JSON","56","0","1","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/package-lock.json","JSON","2884","0","1","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/environment.yml","YAML","16","0","2","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/README.md","Markdown","23","0","18","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/Makefile","Makefile","62","0","22","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/.prettierrc.js","JavaScript","13","0","1","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./pyscriptjs/.eslintrc.js","JavaScript","44","2","1","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/","./pyscriptjs/"],["./examples/webgl/raycaster/style.css","CSS","52","1","1","./examples/","./examples/webgl/","./examples/webgl/raycaster/","./examples/webgl/raycaster/","./examples/webgl/raycaster/"],["./examples/webgl/raycaster/index.html","HTML","158","0","40","./examples/","./examples/webgl/","./examples/webgl/raycaster/","./examples/webgl/raycaster/","./examples/webgl/raycaster/"],["./examples/utils.py","Python","9","0","9","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/toga/static/toga.css","CSS","8","0","2","./examples/","./examples/toga/","./examples/toga/static/","./examples/toga/static/","./examples/toga/static/"],["./examples/toga/server/demo.py","Python","7","0","5","./examples/","./examples/toga/","./examples/toga/server/","./examples/toga/server/","./examples/toga/server/"],["./examples/toga/freedom/src/freedom/app.py","Python","42","0","19","./examples/","./examples/toga/","./examples/toga/freedom/","./examples/toga/freedom/src/","./examples/toga/freedom/src/freedom/"],["./examples/toga/freedom/src/freedom/__main__.py","Python","4","0","3","./examples/","./examples/toga/","./examples/toga/freedom/","./examples/toga/freedom/src/","./examples/toga/freedom/src/freedom/"],["./examples/toga/freedom/src/freedom/__init__.py","Python","0","0","1","./examples/","./examples/toga/","./examples/toga/freedom/","./examples/toga/freedom/src/","./examples/toga/freedom/src/freedom/"],["./examples/toga/freedom/fake-briefcase.sh","Shell Script","5","1","2","./examples/","./examples/toga/","./examples/toga/freedom/","./examples/toga/freedom/","./examples/toga/freedom/"],["./examples/toga/freedom.html","HTML","42","2","7","./examples/","./examples/toga/","./examples/toga/","./examples/toga/","./examples/toga/"],["./examples/toga/README.md","Markdown","49","0","31","./examples/","./examples/toga/","./examples/toga/","./examples/toga/","./examples/toga/"],["./examples/todo.py","Python","34","5","15","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/todo.html","HTML","42","1","10","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/todo-pylist.html","HTML","41","0","10","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/simple_clock.html","HTML","43","0","9","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/simple_bioinformatics_tool.html","HTML","107","6","17","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/repl2.html","HTML","28","0","6","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/repl.html","HTML","23","0","5","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/repl.css","CSS","14","0","3","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/readme.md","Markdown","1","0","1","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/pylist.py","Python","12","0","8","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/panel_stream.html","HTML","95","0","23","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/panel_kmeans.html","HTML","146","0","27","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/panel_deckgl.html","HTML","189","0","33","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/panel.html","HTML","29","0","4","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/palettes.py","Python","262","0","2","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/numpy_canvas_fractals.html","HTML","254","0","65","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/micrograd_ai.py","Python","96","33","32","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/micrograd_ai.html","HTML","171","1","21","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/message_passing.html","HTML","50","0","5","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/matplotlib.html","HTML","43","0","8","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/mario/play_mario.html","HTML","122","0","23","./examples/","./examples/mario/","./examples/mario/","./examples/mario/","./examples/mario/"],["./examples/mario/js/util.js","JavaScript","11","0","4","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/star.js","JavaScript","95","3","19","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/sprite.js","JavaScript","39","0","9","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/rubble.js","JavaScript","47","3","6","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/resources.js","JavaScript","53","2","8","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/prop.js","JavaScript","11","2","3","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/player.js","JavaScript","391","9","47","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/pipe.js","JavaScript","122","21","18","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/mushroom.js","JavaScript","97","4","18","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/levels/level.js","JavaScript","187","4","28","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/levels/","./examples/mario/js/levels/"],["./examples/mario/js/levels/11tunnel.js","JavaScript","57","1","8","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/levels/","./examples/mario/js/levels/"],["./examples/mario/js/levels/11.js","JavaScript","198","8","14","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/levels/","./examples/mario/js/levels/"],["./examples/mario/js/koopa.js","JavaScript","182","8","22","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/input.js","JavaScript","47","0","8","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/goomba.js","JavaScript","110","3","17","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/game.js","JavaScript","185","21","36","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/floor.js","JavaScript","45","5","7","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/flag.js","JavaScript","40","1","7","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/fireflower.js","JavaScript","59","3","13","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/fireball.js","JavaScript","104","4","19","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/entity.js","JavaScript","28","2","5","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/coin.js","JavaScript","37","3","8","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/block.js","JavaScript","68","2","12","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/js/bcoin.js","JavaScript","33","4","9","./examples/","./examples/mario/","./examples/mario/js/","./examples/mario/js/","./examples/mario/js/"],["./examples/mario/css/game.css","CSS","27","0","6","./examples/","./examples/mario/","./examples/mario/css/","./examples/mario/css/","./examples/mario/css/"],["./examples/index.html","HTML","271","0","20","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/hello_world.html","HTML","20","0","5","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/handtrack/say_hello.html","HTML","102","0","21","./examples/","./examples/handtrack/","./examples/handtrack/","./examples/handtrack/","./examples/handtrack/"],["./examples/fractals.py","Python","85","25","30","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/folium.html","HTML","43","0","7","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/d3.html","HTML","143","0","28","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/bokeh_interactive.html","HTML","78","0","21","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/bokeh.html","HTML","38","0","11","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/assets/css/variables.css","CSS","4","0","1","./examples/","./examples/assets/","./examples/assets/css/","./examples/assets/css/","./examples/assets/css/"],["./examples/assets/css/reset.css","CSS","19","0","4","./examples/","./examples/assets/","./examples/assets/css/","./examples/assets/css/","./examples/assets/css/"],["./examples/assets/css/main.css","CSS","15","0","3","./examples/","./examples/assets/","./examples/assets/css/","./examples/assets/css/","./examples/assets/css/"],["./examples/assets/css/index.css","CSS","44","0","8","./examples/","./examples/assets/","./examples/assets/css/","./examples/assets/css/","./examples/assets/css/"],["./examples/antigravity.svg","XML","72","0","1","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/antigravity.py","Python","36","0","10","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/antigravity.html","HTML","20","0","1","./examples/","./examples/","./examples/","./examples/","./examples/"],["./examples/altair.html","HTML","54","0","7","./examples/","./examples/","./examples/","./examples/","./examples/"],["./docs/tutorials/setup.md","Markdown","2","0","2","./docs/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/"],["./docs/tutorials/index.md","Markdown","10","0","3","./docs/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/"],["./docs/tutorials/getting-started.md","Markdown","213","0","55","./docs/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/"],["./docs/tutorials/deployment.md","Markdown","2","0","2","./docs/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/","./docs/tutorials/"],["./docs/reference/index.md","Markdown","9","0","3","./docs/","./docs/reference/","./docs/reference/","./docs/reference/","./docs/reference/"],["./docs/reference/faq.md","Markdown","84","0","77","./docs/","./docs/reference/","./docs/reference/","./docs/reference/","./docs/reference/"],["./docs/make.bat","Batch","27","0","9","./docs/","./docs/","./docs/","./docs/","./docs/"],["./docs/index.md","Markdown","39","0","16","./docs/","./docs/","./docs/","./docs/","./docs/"],["./docs/howtos/index.md","Markdown","15","0","4","./docs/","./docs/howtos/","./docs/howtos/","./docs/howtos/","./docs/howtos/"],["./docs/environment.yml","YAML","17","0","2","./docs/","./docs/","./docs/","./docs/","./docs/"],["./docs/conf.py","Python","51","31","22","./docs/","./docs/","./docs/","./docs/","./docs/"],["./docs/concepts/what-is-pyscript.md","Markdown","22","0","13","./docs/","./docs/concepts/","./docs/concepts/","./docs/concepts/","./docs/concepts/"],["./docs/concepts/index.md","Markdown","10","0","3","./docs/","./docs/concepts/","./docs/concepts/","./docs/concepts/","./docs/concepts/"],["./docs/concepts/governance/policy.md","Markdown","24","0","22","./docs/","./docs/concepts/","./docs/concepts/governance/","./docs/concepts/governance/","./docs/concepts/governance/"],["./docs/concepts/governance/maintainers.md","Markdown","14","0","5","./docs/","./docs/concepts/","./docs/concepts/governance/","./docs/concepts/governance/","./docs/concepts/governance/"],["./docs/_static/redirect.html","HTML","1","0","1","./docs/","./docs/_static/","./docs/_static/","./docs/_static/","./docs/_static/"],["./docs/_static/examples/what-is-pyscript.html","HTML","40","0","5","./docs/","./docs/_static/","./docs/_static/examples/","./docs/_static/examples/","./docs/_static/examples/"],["./docs/README.md","Markdown","12","0","6","./docs/","./docs/","./docs/","./docs/","./docs/"],["./docs/Makefile","Makefile","26","7","13","./docs/","./docs/","./docs/","./docs/","./docs/"],["./README.md","Markdown","29","0","19","./","./","./","./","./"],["./MAINTAINERS.md","Markdown","14","0","5","./","./","./","./","./"],["./GOVERNANCE.md","Markdown","24","0","22","./","./","./","./","./"],["./CONTRIBUTING.md","Markdown","67","0","32","./","./","./","./","./"],["./CODE_OF_CONDUCT.md","Markdown","3","0","2","./","./","./","./","./"],["./.readthedocs.yml","YAML","12","10","7","./","./","./","./","./"],["./.pre-commit-config.yaml","YAML","67","12","11","./","./","./","./","./"],["./.github/workflows/sync-examples.yml","YAML","27","2","5","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/publish-release.yml","YAML","48","3","12","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/docs-review.yml","YAML","58","8","13","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/docs-release.yml","YAML","44","3","11","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/docs-latest.yml","YAML","47","3","11","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/build-release.yml","YAML","44","1","12","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/workflows/build-latest.yml","YAML","59","2","14","./.github/","./.github/workflows/","./.github/workflows/","./.github/workflows/","./.github/workflows/"],["./.github/ISSUE_TEMPLATE/misc.yml","YAML","32","0","6","./.github/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/"],["./.github/ISSUE_TEMPLATE/feature-request.yml","YAML","55","2","11","./.github/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/"],["./.github/ISSUE_TEMPLATE/config.yml","YAML","5","0","1","./.github/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/"],["./.github/ISSUE_TEMPLATE/bug-report.yml","YAML","59","0","5","./.github/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/","./.github/ISSUE_TEMPLATE/"]]} 2 | --------------------------------------------------------------------------------