tabsight 0.1.0a1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tabsight-0.1.0a1/.gitattributes +9 -0
- tabsight-0.1.0a1/.gitignore +36 -0
- tabsight-0.1.0a1/CHANGELOG.md +189 -0
- tabsight-0.1.0a1/CODE_OF_CONDUCT.md +12 -0
- tabsight-0.1.0a1/CONTRIBUTING.md +56 -0
- tabsight-0.1.0a1/LICENSE +21 -0
- tabsight-0.1.0a1/NOTICE +28 -0
- tabsight-0.1.0a1/PKG-INFO +358 -0
- tabsight-0.1.0a1/README.md +290 -0
- tabsight-0.1.0a1/SECURITY.md +18 -0
- tabsight-0.1.0a1/docs/README.md +37 -0
- tabsight-0.1.0a1/docs/SECURITY_CHECKLIST.md +31 -0
- tabsight-0.1.0a1/docs/assets/examples/category-mix.svg +64 -0
- tabsight-0.1.0a1/docs/assets/examples/region-panels.svg +137 -0
- tabsight-0.1.0a1/docs/assets/examples/sales-by-quarter.svg +161 -0
- tabsight-0.1.0a1/docs/assets/examples/sales-by-region.svg +40 -0
- tabsight-0.1.0a1/docs/assets/examples/sales-by-state-map.svg +298 -0
- tabsight-0.1.0a1/docs/assets/examples/sales-forecast.svg +91 -0
- tabsight-0.1.0a1/docs/assets/examples/sales-treemap.svg +89 -0
- tabsight-0.1.0a1/docs/assets/examples/sub-category-share.svg +67 -0
- tabsight-0.1.0a1/docs/assets/logo-wordmark-dark.svg +11 -0
- tabsight-0.1.0a1/docs/assets/logo-wordmark.svg +11 -0
- tabsight-0.1.0a1/docs/assets/logo.svg +9 -0
- tabsight-0.1.0a1/docs/decisions/0001-echarts-version.md +33 -0
- tabsight-0.1.0a1/docs/getting-started/concepts.md +59 -0
- tabsight-0.1.0a1/docs/getting-started/installation.md +49 -0
- tabsight-0.1.0a1/docs/getting-started/quickstart.md +126 -0
- tabsight-0.1.0a1/docs/guide/aggregating.md +139 -0
- tabsight-0.1.0a1/docs/guide/analytics.md +204 -0
- tabsight-0.1.0a1/docs/guide/auto-and-cli.md +83 -0
- tabsight-0.1.0a1/docs/guide/calculated-fields.md +136 -0
- tabsight-0.1.0a1/docs/guide/chart-specs.md +48 -0
- tabsight-0.1.0a1/docs/guide/charts.md +143 -0
- tabsight-0.1.0a1/docs/guide/checking.md +89 -0
- tabsight-0.1.0a1/docs/guide/choosing-charts.md +169 -0
- tabsight-0.1.0a1/docs/guide/cleaning.md +82 -0
- tabsight-0.1.0a1/docs/guide/colors-and-themes.md +62 -0
- tabsight-0.1.0a1/docs/guide/dashboards.md +180 -0
- tabsight-0.1.0a1/docs/guide/dates.md +97 -0
- tabsight-0.1.0a1/docs/guide/formatting.md +115 -0
- tabsight-0.1.0a1/docs/guide/loading-data.md +52 -0
- tabsight-0.1.0a1/docs/guide/maps.md +152 -0
- tabsight-0.1.0a1/docs/guide/more-charts.md +181 -0
- tabsight-0.1.0a1/docs/guide/notebooks.md +94 -0
- tabsight-0.1.0a1/docs/guide/profiling.md +104 -0
- tabsight-0.1.0a1/docs/guide/settings.md +95 -0
- tabsight-0.1.0a1/docs/guide/small-multiples.md +45 -0
- tabsight-0.1.0a1/docs/guide/table-calculations.md +73 -0
- tabsight-0.1.0a1/docs/guide/web-apps.md +78 -0
- tabsight-0.1.0a1/docs/index.md +85 -0
- tabsight-0.1.0a1/docs/project/changelog.md +3 -0
- tabsight-0.1.0a1/docs/project/contributing.md +24 -0
- tabsight-0.1.0a1/docs/project/security.md +38 -0
- tabsight-0.1.0a1/docs/reference/api.md +153 -0
- tabsight-0.1.0a1/docs/reference/chart-kinds.md +43 -0
- tabsight-0.1.0a1/docs/reference/formula-functions.md +83 -0
- tabsight-0.1.0a1/docs/reference/lint-rules.md +27 -0
- tabsight-0.1.0a1/docs/reference/locales.md +46 -0
- tabsight-0.1.0a1/docs/reference/map-coverage.md +288 -0
- tabsight-0.1.0a1/docs/reference/warnings-and-errors.md +38 -0
- tabsight-0.1.0a1/docs/stylesheets/tabsight.css +333 -0
- tabsight-0.1.0a1/examples/superstore_sample.csv +1201 -0
- tabsight-0.1.0a1/licenses/echarts-LICENSE.txt +222 -0
- tabsight-0.1.0a1/licenses/echarts-NOTICE.txt +5 -0
- tabsight-0.1.0a1/licenses/topojson-client-LICENSE.txt +13 -0
- tabsight-0.1.0a1/mkdocs.yml +131 -0
- tabsight-0.1.0a1/overrides/home.html +32 -0
- tabsight-0.1.0a1/pyproject.toml +131 -0
- tabsight-0.1.0a1/src/tabsight/__init__.py +89 -0
- tabsight-0.1.0a1/src/tabsight/__main__.py +3 -0
- tabsight-0.1.0a1/src/tabsight/_version.py +1 -0
- tabsight-0.1.0a1/src/tabsight/accessor.py +114 -0
- tabsight-0.1.0a1/src/tabsight/aggregate.py +759 -0
- tabsight-0.1.0a1/src/tabsight/analytics.py +275 -0
- tabsight-0.1.0a1/src/tabsight/auto.py +249 -0
- tabsight-0.1.0a1/src/tabsight/charts/__init__.py +737 -0
- tabsight-0.1.0a1/src/tabsight/charts/_build.py +359 -0
- tabsight-0.1.0a1/src/tabsight/charts/_common.py +124 -0
- tabsight-0.1.0a1/src/tabsight/charts/extra.py +236 -0
- tabsight-0.1.0a1/src/tabsight/charts/facets.py +369 -0
- tabsight-0.1.0a1/src/tabsight/charts/grids.py +202 -0
- tabsight-0.1.0a1/src/tabsight/charts/maps.py +669 -0
- tabsight-0.1.0a1/src/tabsight/charts/pane.py +336 -0
- tabsight-0.1.0a1/src/tabsight/charts/parts.py +319 -0
- tabsight-0.1.0a1/src/tabsight/charts/relation.py +530 -0
- tabsight-0.1.0a1/src/tabsight/check.py +318 -0
- tabsight-0.1.0a1/src/tabsight/clean.py +409 -0
- tabsight-0.1.0a1/src/tabsight/cli.py +295 -0
- tabsight-0.1.0a1/src/tabsight/colors.py +155 -0
- tabsight-0.1.0a1/src/tabsight/dashboard.py +1436 -0
- tabsight-0.1.0a1/src/tabsight/figure.py +241 -0
- tabsight-0.1.0a1/src/tabsight/formats.py +487 -0
- tabsight-0.1.0a1/src/tabsight/formulas.py +754 -0
- tabsight-0.1.0a1/src/tabsight/geo/__init__.py +109 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/__init__.py +1 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ABW.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AFG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AGO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AIA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ALB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ALD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AND.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ARE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ARG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ARM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ASM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ATA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ATC.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ATF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ATG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AUS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AUT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/AZE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BDI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BEL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BEN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BFA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BGD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BGR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BHR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BHS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BIH.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BLM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BLR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BLZ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BMU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BOL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BRA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BRB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BRN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BTN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/BWA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CAF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CAN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CHE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CHL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CHN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CIV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CLP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CMR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/COD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/COG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/COK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/COL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/COM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CPV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CRI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CSI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CUB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CUW.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CYM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CYN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CYP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/CZE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DEU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DJI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DMA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DNK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DOM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/DZA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ECU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/EGY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ERI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ESB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ESP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/EST.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ETH.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FIN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FJI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FLK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FRA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FRO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/FSM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GAB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GBR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GEO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GGY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GHA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GIB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GIN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GMB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GNB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GNQ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GRC.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GRD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GRL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GTM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GUM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/GUY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HKG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HMD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HND.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HRV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HTI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/HUN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IDN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IMN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IND.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IOA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IOT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IRL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IRN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/IRQ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ISL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ISR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ITA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/JAM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/JEY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/JOR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/JPN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KAB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KAS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KAZ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KEN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KGZ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KHM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KIR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KNA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KOR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KOS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/KWT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LAO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LBN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LBR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LBY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LCA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LIE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LKA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LSO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LTU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LUX.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/LVA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MAC.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MAF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MAR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MCO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MDA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MDG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MDV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MEX.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MHL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MKD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MLI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MLT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MMR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MNE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MNG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MNP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MOZ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MRT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MSR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MUS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MWI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/MYS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NAM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NCL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NER.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NFK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NGA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NIC.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NIU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NLD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NOR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NPL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NRU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/NZL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/OMN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PAK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PAN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PCN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PER.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PGA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PHL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PLW.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PNG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/POL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PRI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PRK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PRT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PRY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PSX.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/PYF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/QAT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ROU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/RUS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/RWA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SAH.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SAU.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SDN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SDS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SEN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SGP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SGS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SHN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SLB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SLE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SLV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SMR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SOL.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SOM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SPM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SRB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/STP.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SUR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SVK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SVN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SWE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SWZ.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SXM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SYC.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/SYR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TCA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TCD.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TGO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/THA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TJK.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TKM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TLS.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TON.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TTO.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TUN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TUR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TUV.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TWN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/TZA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/UGA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/UKR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/UMI.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/URY.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/USA.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/USG.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/UZB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VAT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VCT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VEN.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VGB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VIR.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VNM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/VUT.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/WLF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/WSB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/WSM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/YEM.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ZAF.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ZMB.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/admin1/ZWE.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/cities.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/names.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/version.json +6 -0
- tabsight-0.1.0a1/src/tabsight/geo/data/world.topo.json.gz +0 -0
- tabsight-0.1.0a1/src/tabsight/geo/detection.py +505 -0
- tabsight-0.1.0a1/src/tabsight/geo/names.py +198 -0
- tabsight-0.1.0a1/src/tabsight/i18n/__init__.py +55 -0
- tabsight-0.1.0a1/src/tabsight/i18n/de.json +50 -0
- tabsight-0.1.0a1/src/tabsight/i18n/en.json +90 -0
- tabsight-0.1.0a1/src/tabsight/i18n/es.json +50 -0
- tabsight-0.1.0a1/src/tabsight/i18n/fr.json +50 -0
- tabsight-0.1.0a1/src/tabsight/i18n/it.json +50 -0
- tabsight-0.1.0a1/src/tabsight/i18n/nl.json +50 -0
- tabsight-0.1.0a1/src/tabsight/i18n/pt.json +50 -0
- tabsight-0.1.0a1/src/tabsight/insight.py +490 -0
- tabsight-0.1.0a1/src/tabsight/io.py +279 -0
- tabsight-0.1.0a1/src/tabsight/lint.py +243 -0
- tabsight-0.1.0a1/src/tabsight/localserver.py +113 -0
- tabsight-0.1.0a1/src/tabsight/periods.py +237 -0
- tabsight-0.1.0a1/src/tabsight/plotting.py +173 -0
- tabsight-0.1.0a1/src/tabsight/profile.py +743 -0
- tabsight-0.1.0a1/src/tabsight/py.typed +0 -0
- tabsight-0.1.0a1/src/tabsight/read.py +271 -0
- tabsight-0.1.0a1/src/tabsight/recommend.py +595 -0
- tabsight-0.1.0a1/src/tabsight/render/__init__.py +1 -0
- tabsight-0.1.0a1/src/tabsight/render/assets.py +24 -0
- tabsight-0.1.0a1/src/tabsight/render/dashboard_html.py +164 -0
- tabsight-0.1.0a1/src/tabsight/render/html.py +160 -0
- tabsight-0.1.0a1/src/tabsight/render/picture.py +235 -0
- tabsight-0.1.0a1/src/tabsight/render/static/__init__.py +0 -0
- tabsight-0.1.0a1/src/tabsight/render/static/dashboard.js +2914 -0
- tabsight-0.1.0a1/src/tabsight/render/static/echarts.min.js +45 -0
- tabsight-0.1.0a1/src/tabsight/render/static/tabsight.js +588 -0
- tabsight-0.1.0a1/src/tabsight/render/static/topojson-client.min.js +2 -0
- tabsight-0.1.0a1/src/tabsight/server.py +272 -0
- tabsight-0.1.0a1/src/tabsight/settings.py +195 -0
- tabsight-0.1.0a1/src/tabsight/spec.py +350 -0
- tabsight-0.1.0a1/src/tabsight/tablecalc.py +122 -0
- tabsight-0.1.0a1/src/tabsight/theme.py +120 -0
- tabsight-0.1.0a1/src/tabsight/warnings.py +113 -0
- tabsight-0.1.0a1/src/tabsight/web.py +183 -0
- tabsight-0.1.0a1/tests/__init__.py +0 -0
- tabsight-0.1.0a1/tests/conftest.py +67 -0
- tabsight-0.1.0a1/tests/js/dashboard_extra.cjs +42 -0
- tabsight-0.1.0a1/tests/js/dashboard_parity.cjs +64 -0
- tabsight-0.1.0a1/tests/js/echarts_features.cjs +160 -0
- tabsight-0.1.0a1/tests/js/parity.cjs +27 -0
- tabsight-0.1.0a1/tests/js/projection.cjs +22 -0
- tabsight-0.1.0a1/tests/js/runtime_unit.cjs +64 -0
- tabsight-0.1.0a1/tests/recommend_cases.py +161 -0
- tabsight-0.1.0a1/tests/test_aggregate.py +342 -0
- tabsight-0.1.0a1/tests/test_analytics.py +442 -0
- tabsight-0.1.0a1/tests/test_auto_server_web.py +508 -0
- tabsight-0.1.0a1/tests/test_charts.py +153 -0
- tabsight-0.1.0a1/tests/test_check_clean.py +157 -0
- tabsight-0.1.0a1/tests/test_colors_theme_spec.py +166 -0
- tabsight-0.1.0a1/tests/test_dashboard.py +697 -0
- tabsight-0.1.0a1/tests/test_docs.py +189 -0
- tabsight-0.1.0a1/tests/test_echarts_features.py +24 -0
- tabsight-0.1.0a1/tests/test_formats.py +163 -0
- tabsight-0.1.0a1/tests/test_formulas.py +260 -0
- tabsight-0.1.0a1/tests/test_geo.py +270 -0
- tabsight-0.1.0a1/tests/test_html_security.py +157 -0
- tabsight-0.1.0a1/tests/test_io.py +166 -0
- tabsight-0.1.0a1/tests/test_js_parity.py +97 -0
- tabsight-0.1.0a1/tests/test_maps.py +233 -0
- tabsight-0.1.0a1/tests/test_more_charts.py +373 -0
- tabsight-0.1.0a1/tests/test_never_mutates.py +73 -0
- tabsight-0.1.0a1/tests/test_package.py +56 -0
- tabsight-0.1.0a1/tests/test_picture.py +204 -0
- tabsight-0.1.0a1/tests/test_profile.py +218 -0
- tabsight-0.1.0a1/tests/test_read.py +112 -0
- tabsight-0.1.0a1/tests/test_recommend.py +396 -0
- tabsight-0.1.0a1/tests/test_security_guards.py +151 -0
- tabsight-0.1.0a1/tests/test_settings.py +132 -0
- tabsight-0.1.0a1/tests/test_tablecalc.py +80 -0
- tabsight-0.1.0a1/tools/build_geo.py +413 -0
- tabsight-0.1.0a1/tools/fetch_vendor.py +108 -0
- tabsight-0.1.0a1/tools/figure_svg.cjs +31 -0
- tabsight-0.1.0a1/tools/make_gallery.py +148 -0
- tabsight-0.1.0a1/tools/make_map_coverage.py +74 -0
- tabsight-0.1.0a1/tools/make_readme_images.py +87 -0
- tabsight-0.1.0a1/tools/make_sample_data.py +80 -0
- tabsight-0.1.0a1/tools/package-lock.json +2997 -0
- tabsight-0.1.0a1/tools/package.json +10 -0
- tabsight-0.1.0a1/tools/render_doc_outputs.py +124 -0
- tabsight-0.1.0a1/tools/vendor.lock.json +47 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Normalise our own text files to LF in the repository.
|
|
2
|
+
* text=auto eol=lf
|
|
3
|
+
|
|
4
|
+
# Vendored files are hash-checked (tools/vendor.lock.json): store and check out byte-for-byte.
|
|
5
|
+
src/tabsight/render/static/*.min.js -text
|
|
6
|
+
licenses/* -text
|
|
7
|
+
|
|
8
|
+
# Bundled map data (tools/build_geo.py): compressed, store byte-for-byte.
|
|
9
|
+
*.gz binary
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
.mypy_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.pytest_cache/
|
|
12
|
+
.hypothesis/
|
|
13
|
+
.coverage
|
|
14
|
+
htmlcov/
|
|
15
|
+
|
|
16
|
+
# Raw downloaded map data (re-created by tools/fetch_vendor.py)
|
|
17
|
+
/data-raw/
|
|
18
|
+
|
|
19
|
+
# Node tooling
|
|
20
|
+
node_modules/
|
|
21
|
+
|
|
22
|
+
# Editors / OS
|
|
23
|
+
.vscode/
|
|
24
|
+
.idea/
|
|
25
|
+
.DS_Store
|
|
26
|
+
Thumbs.db
|
|
27
|
+
|
|
28
|
+
# Built documentation site (python -m mkdocs build)
|
|
29
|
+
/site/
|
|
30
|
+
|
|
31
|
+
# Generated output from examples
|
|
32
|
+
*.out.html
|
|
33
|
+
|
|
34
|
+
# Chart gallery (python tools/make_gallery.py)
|
|
35
|
+
/gallery/
|
|
36
|
+
.geo-build/
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes are listed here. The project follows [Semantic Versioning](https://semver.org/).
|
|
4
|
+
|
|
5
|
+
## 0.1.0a1 (28 Oct 2026, first pre-release)
|
|
6
|
+
|
|
7
|
+
### Added: auto, command line and web apps
|
|
8
|
+
- `ts.auto(df)`: a whole dashboard from fixed rules on the column profile: KPI cards (money first, compared with the previous year when the dates allow), a line over time at a grain that suits the span, a map when a column holds places, bars by the smallest categories, filters and insights. `dash.decisions` says what was chosen and why; tiles are tried before they are added and the result is fitted under the size limit. Tables without measures count rows.
|
|
9
|
+
- `tabsight` command line (also `python -m tabsight`): `auto`, `chart` (HTML, SVG or PNG), `build` (a saved spec on new data), `serve`, `profile`, `check`, `clean`, `recommend`. Never overwrites its input.
|
|
10
|
+
- Server mode: `dash.server(url)` keeps the data in Python. The page posts its filters and gets back, per tile, a small table from the filtered rows, drawn by the same runtime (parity-tested against the offline page), or for tiles the browser can't recompute, the chart redrawn in Python. No size limit for the page; medians, distinct counts and scatter plots follow every filter. Requests are size-capped, shape-checked and filtered against known values; the page's CSP allows `connect-src` to that one origin only.
|
|
11
|
+
- `ts.web.fastapi_router`, `ts.web.flask_blueprint`, `ts.streamlit`, `ts.web.dash_iframe` and `ts.serve_payload`; `tabsight serve` runs server mode with Python's own HTTP server on 127.0.0.1.
|
|
12
|
+
- `fig.to_png()`: the SVG picture rasterised by resvg-py, no browser needed (`tabsight[png]`, which no longer uses Playwright). New `web` extra.
|
|
13
|
+
- Dashboards over the size limit shrink themselves in steps instead of stopping: coarser dates on the tiles that use them, then tiles grouped by a field with many values are drawn from all the data. Each step is reported (`dash.size_steps`, and a warning).
|
|
14
|
+
- Touch screens: a tap on a dashboard chart shows the tooltip, and pressing and holding filters (the tile is outlined while held).
|
|
15
|
+
|
|
16
|
+
### Security
|
|
17
|
+
- `tabsight serve` answers only requests addressed to its own host names, so a hostile web page can't read the served data by DNS rebinding; `--allow-host` adds names. Server-mode data requests must be `application/json` (415 otherwise in the FastAPI and Flask helpers).
|
|
18
|
+
- Deeply nested JSON sent to server mode gets a 400 instead of an internal error.
|
|
19
|
+
- Data values named like JavaScript object properties (`hasOwnProperty`, `__proto__`, `constructor`) no longer break or blank dashboard filtering. A label that is exactly `__proto__` no longer lets ECharts' text cache write to `Object.prototype`, and tabsight's pages now lock `Object.prototype`.
|
|
20
|
+
- `ts.load` refuses Excel files that would unpack to more than 1 GB or at an extreme compression ratio (decompression bombs; `defusedxml` already stopped XML bombs), and JSON nested too deeply to be a table.
|
|
21
|
+
- `ts.load` refuses Windows network-share paths (`\\server\share`), keeping the promise that tabsight never contacts another computer.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- The documentation site is built with Zensical, the successor to Material for MkDocs (which reaches end of life on 5 May 2027), from the same `mkdocs.yml`.
|
|
25
|
+
- A dashboard spec file that isn't JSON now raises a clear `InvalidSpecError`.
|
|
26
|
+
|
|
27
|
+
### Added: dashboards completed
|
|
28
|
+
- Every aggregated chart kind is recomputed after filtering, each following its Python builder: lollipop, combo, gauge, bullet, funnel, Pareto, waterfall, heatmap, calendar heatmap, treemap, sunburst, Sankey, histogram (bins of all the data), box plot, scatter and bubble by category, lines over a number axis, and symbol, density and flow maps. Medians, distinct counts and box plots are exact from value lists; distinct counts store integer codes, never the values. Only single-row charts (scatter of rows, lat/lon maps) stay static.
|
|
29
|
+
- Trend lines, forecasts, reference lines, bands and outliers are refitted in the browser after filtering (JS ports of `analytics.py` and the analytics pane), and the insights panel is recomputed (change, peak and low, trend, contributor, concentration, losses), tagged "for current filters".
|
|
30
|
+
- Legend click highlights a series (Ctrl + click hides it); drag across a line chart's dates to filter a range; double-click drills down (year > quarter > month, and detected hierarchies) with breadcrumbs.
|
|
31
|
+
- Per tile: a chart-type menu (up to two other kinds the recommender finds fitting) and PNG export.
|
|
32
|
+
- Light/dark toggle that follows the computer's setting; `theme_toggle=False`, `switch=False`, `drill=False` turn features off.
|
|
33
|
+
- Tiles with their own data: `add(..., data=df, data_name="targets")`; filters apply where the field exists and other tiles say "Not affected by ..."; `bind(df, targets=new_df)`.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- Python: a missing funnel or Pareto stage was named "nan"; grouped scatter and number-axis lines silently dropped points whose colour value was missing; box plots of an ordered column were sorted by size; category insights named a missing value "nan"; a measure could be recorded twice in a chart's facts.
|
|
37
|
+
|
|
38
|
+
### Added: dashboards with cross-filtering
|
|
39
|
+
- `ts.Dashboard(title, data=df, filters=[...])` with `.add(kind, ..., w=)`, `.kpi(...)` and `.insights()`: tiles on a 12-column grid (one column on phones), in one offline HTML file or a notebook.
|
|
40
|
+
- Filters (value lists for categories, month ranges for dates), chips with remove buttons, "Reset all filters", and the view kept in the address (`#f=...`), checked against known values.
|
|
41
|
+
- Cross-filtering: clicking a bar, slice, map region, point or table row filters the other tiles; Ctrl/Shift + click adds values; clicking again removes; the "Other" bar filters to its members; the source tile highlights instead of filtering itself; `action="highlight"` and `"none"` per tile.
|
|
42
|
+
- Exact re-aggregation in the browser (`dashboard.js`) from one shared table of exact parts (sums, counts, minimums, maximums; never raw rows), with top N, Other, sorting, period gaps and `min_group_size` recomputed. Parity tests check the browser against `ts.chart` on the same filtered data.
|
|
43
|
+
- KPI comparisons follow date filters: the filtered months against the same months a period earlier.
|
|
44
|
+
- Tiles that can't be recomputed exactly say "Not affected by filters" and why. CSV download per tile (formula-safe), lazy drawing, every tile drawn before printing.
|
|
45
|
+
- `save()` / `load()` / `bind(new_df)` with strict validation of dashboard files.
|
|
46
|
+
- GitHub Sponsors button in the README, on the docs home page and in `.github/FUNDING.yml`.
|
|
47
|
+
|
|
48
|
+
### Added: analytics and insights
|
|
49
|
+
- `ts.insights(df)`: plain-English facts from fixed rules (no LLM): change on the previous period, peak and low, trend direction, seasonality, biggest contributor, concentration, negative segments and outliers. Facts only, never causes; rates change in points; every threshold configurable; each insight tagged with the data it describes. `insights=True` lists them under a chart.
|
|
50
|
+
- `ts.compare(df, y, date)`: year, quarter and month comparisons on the same window shifted back, fiscal-year aware, `as_of=` for "today" (otherwise the latest date in the data, never the clock), `previous_period` with `window=`. A sliver of a new period falls back to the last complete one; no previous data says so instead of +100%. KPI cards take `compare=` and `as_of=`.
|
|
51
|
+
- Analytics pane on charts: `trend=True` (least squares, R² in `explain()`), `forecast=N` (additive Holt-Winters in numpy, `season=`, dashed "Estimate" with a range, needs two full seasons), `ref=` reference lines (mean, median, percentiles, constants), `band=` shaded bands, `outliers=True` (circled, never removed).
|
|
52
|
+
- `ts.analytics`: `linear_trend`, `forecast`, `outliers`, `reference_value` for your own use.
|
|
53
|
+
- Lint rules `weak_trend` and `long_forecast`.
|
|
54
|
+
- Still pictures: `fig.to_svg()` draws a chart (title, chart, notes, insights) to SVG in Python, with ECharts running in dukpy (`pip install tabsight[static]`); no browser or Node.js.
|
|
55
|
+
- Notebooks: with the `static` extra, each chart also carries its picture under the live chart, so a reopened (untrusted) notebook or one viewed on GitHub shows the chart instead of a blank space. `picture=False` turns it off. Checked in JupyterLab 4.6.
|
|
56
|
+
- Docs: "Trends, forecasts and insights" guide.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
- Bar charts over dates stay vertical; they no longer switch to horizontal bars when there are many periods.
|
|
60
|
+
|
|
61
|
+
### Added: every chart kind, small multiples, notebooks
|
|
62
|
+
- All 33 chart kinds can now be drawn. New: scatter and bubble (one dot per row, or per category with exact aggregation), histogram (rounded bar widths; `bins=`, `bin_width=`), box plot (Tukey whiskers, outliers), treemap and sunburst (levels from `x`), waterfall (floating bars that can cross zero, total at the end), funnel (share of previous and first stage), Pareto (running share, 80% guide), lollipop, bullet and gauge (`goal=` a number or a column), combo (bars and lines, two axes when units differ), heatmap, calendar heatmap, Sankey (cycles broken safely), density map and flow map.
|
|
63
|
+
- Lines and areas over a number: a real value axis (a sine wave is a curve), thinned with LTTB above 2,000 points.
|
|
64
|
+
- Small multiples: `facet=` draws one panel per value (up to 12) sharing one value scale, one category order, one colour per series and one legend; maps and histograms included.
|
|
65
|
+
- pandas plotting backend: `pd.options.plotting.backend = "tabsight"` makes `df.plot(...)` draw tabsight charts (line, bar, barh, area, pie, scatter, hist, box; `by=`, `stacked=`); matplotlib styling is ignored with one warning.
|
|
66
|
+
- `df.ts` and `series.ts` accessors: one method per chart kind, plus `chart`, `recommend`, `profile`, `check`, `aggregate`.
|
|
67
|
+
- `cdn` setting and a one-time tip when a notebook session passes 10 MB of inlined charts.
|
|
68
|
+
- The recommender now picks scatter, treemap, heatmap, combo and the others directly; eight labelled cases updated to the chart they always named as ideal.
|
|
69
|
+
- Docs: "More chart types", "Small multiples" and "Notebooks and df.plot" guides; chart kinds reference lists what each kind needs. Gallery shows all 33 kinds and small multiples.
|
|
70
|
+
|
|
71
|
+
### Fixed (found by running a real JupyterLab 4.6)
|
|
72
|
+
- A chart drawn while its notebook cell was off screen stayed squashed: charts now follow their own box size (ResizeObserver), not only the window.
|
|
73
|
+
- `df.plot.hist()` (pandas sends bins=10) drew 6 coarse bars: `bins=` now picks the round width whose bar count is closest.
|
|
74
|
+
- Monthly date axes crowded every label at notebook width: date labels that would overlap are now left out (dates are in order, so this can't mislead; category labels are still never skipped).
|
|
75
|
+
- The notebook frame was too short for notes under a chart and scrolled inside: it now makes room for them.
|
|
76
|
+
- The mouse wheel over a map zoomed the map instead of scrolling the page: maps now pan by dragging and the wheel scrolls.
|
|
77
|
+
- Warnings now point at the line of your own code (the notebook cell), not at a line inside pandas or tabsight.
|
|
78
|
+
- A run of unique numbers (a step, a row number) is a valid number axis for lines and scatter.
|
|
79
|
+
- Shown names: "China" and "United States" instead of Natural Earth's formal names.
|
|
80
|
+
|
|
81
|
+
### Added: world maps
|
|
82
|
+
- Maps: `ts.chart(df, "map", geo="County", y="Sales")` (a filled map, `choropleth`) and `"symbol_map"` (circles sized by value, from places or `lat=`/`lon=`).
|
|
83
|
+
- Bundled, offline map data from Natural Earth 5.1.2 (public domain), 3.1 MB: about 240 countries, level-1 regions for every country, and about 7,300 cities, built by `tools/build_geo.py` (mapshaper, TopoJSON, deterministic).
|
|
84
|
+
- Extra layers people use: UK nations and regions, French, Italian, Spanish and Philippine regions, and Ireland's 26 official counties.
|
|
85
|
+
- `ts.geo`: `detect`, `match`, `layers`, `country_code`, `coverage`, `version`. Matching on English, local and about 25 other languages' names, everyday names (UK, Holland, Éire), ISO codes and US postal codes; ignores case, accents, punctuation and words like "County".
|
|
86
|
+
- Map detection: the world, a country's regions, or cities; names at two levels (Georgia, Luxembourg, Punjab) settled by the other values, then a country column, then a note. Words like North/East/Central never choose a map on their own.
|
|
87
|
+
- Unmatched places are listed with "did you mean", shown on the chart and raised as a `DataWarning`; `geo_map=` fixes spellings. Rows are tagged with their region and aggregated exactly, so "Cork" and "Co. Cork" make one county.
|
|
88
|
+
- Equal Earth projection for the world (Mercator and Natural Earth on request), auto zoom to the data, dots for tiny countries, Alaska and Hawaii insets, "No data" in grey, diverging colours for negative values, place names in other languages (`geo_names=`).
|
|
89
|
+
- Maps keep their true shape at any size; only the needed shapes go into the page.
|
|
90
|
+
- The recommender suggests a map when at least 80% of a field's values are places, and `kind="auto"` draws it.
|
|
91
|
+
- Docs: "Maps" guide and a generated map coverage page with the 30 most-used countries checked against official lists.
|
|
92
|
+
|
|
93
|
+
### Fixed
|
|
94
|
+
- `ts.aggregate` crashed when a grouping column's name started with `__`.
|
|
95
|
+
|
|
96
|
+
### Added: choosing and checking charts
|
|
97
|
+
- `ts.recommend(data, x, y, color)`: ranks the chart kinds that fit, each with a score and a reason, lists the kinds it ruled out with reasons, and `why_not(kind)`. `.best` is the top one. Rules look at dates and their span, category counts and label lengths, whether a measure adds up, negative totals, IDs, nesting and units.
|
|
98
|
+
- `ts.chart(..., kind="auto")` draws the best recommendation; anything you pass still wins.
|
|
99
|
+
- `fig.explain()`: every decision tabsight made for a chart, in plain English.
|
|
100
|
+
- `fig.lint(ignore=..., strict=...)`: 17 design rules (`tabsight.lint.RULES`) with fixes and the `ts.chart` arguments that apply them. Reads the figure itself, so `fig.update()` patches are checked too. `ChartLintError` for strict mode.
|
|
101
|
+
- 70 labelled recommender cases (`tests/recommend_cases.py`); every automatic chart for them passes its own linter.
|
|
102
|
+
- When two categories are picked and the colour field has many values, the one with fewer values goes in the colours. With more than 8 lines, `auto` keeps the biggest 6.
|
|
103
|
+
- Docs: "Choosing a chart" guide and the lint rules reference.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
- Grouping by an ordered categorical column crashed on pandas 2 while sorting (found by the recommender cases).
|
|
107
|
+
- Time-zone-aware dates crashed `ts.aggregate` with a month, quarter or year grain. They're now grouped by their own wall-clock date, or in the `tz` setting's zone when it's set (the setting existed but did nothing until now).
|
|
108
|
+
- pandas 2 printed FutureWarnings (`observed=False`, silent downcasting) from profiling, aggregation and charts.
|
|
109
|
+
- "Did you mean" hints in error messages are shortened like the rest of the message.
|
|
110
|
+
|
|
111
|
+
### Changed (after hands-on review)
|
|
112
|
+
- `ts.recommend` checks its fields: at least one column, each used once, names must be text.
|
|
113
|
+
- A number used as x (like Quantity) keeps numeric order and suggests a scatter plot; more than 15 distinct numbers leads to a table.
|
|
114
|
+
- More than 50 categories: horizontal bars of the top 20 plus Other; donuts are ruled out.
|
|
115
|
+
- Nested fields (Region and State): one bar per State, coloured by its Region, instead of a table. Grouped and 100% bars are ruled out for nested fields.
|
|
116
|
+
- A date with only one period gets a bar, not an invisible one-point line.
|
|
117
|
+
- An "Other" line in a multi-line chart starts hidden (one click in the legend shows it), because as a total it dwarfs the real lines.
|
|
118
|
+
- New lint rules: `mixed_units` (info) and `no_data` (warning). Stacking rules no longer fire when each bar has one segment. `ignore=None` is accepted.
|
|
119
|
+
- `explain()` wording: "multi-line chart", no repeated "averaged ... averaged"; a table without a measure says it's in natural order.
|
|
120
|
+
|
|
121
|
+
### Added: core charts
|
|
122
|
+
- `ts.chart`: bar, hbar, grouped, stacked and 100% stacked bars; line, multi-line, area, stacked area and sparkline; donut; KPI card; table. BI rules by default: all labels shown (switching to horizontal bars when labels are long), lines never smoothed, zero baseline for bars, one colour per series, the same colour for the same value across charts, top 7 + grey "Other" for donuts, grouped parents in tables.
|
|
123
|
+
- Notes on figures, including a warning when the last period is incomplete and would look low.
|
|
124
|
+
- `Figure`: `to_dict()` (plain JSON), `to_html()` (one offline file, or `cdn=True` with Subresource Integrity), `_repr_html_()` (sandboxed iframe in Jupyter), `update()` (safe deep merge).
|
|
125
|
+
- `tabsight.js` browser runtime and `ts.runtime_js()`. Number formatting is a line-by-line port of Python's, checked on 54,950 cases.
|
|
126
|
+
- Docs: "Making charts" guide.
|
|
127
|
+
|
|
128
|
+
### Security
|
|
129
|
+
- HTML pages carry a Content Security Policy: only tabsight's own inline scripts may run (SHA-256 pinned), no network access at all.
|
|
130
|
+
- Figure data in a non-executable JSON block with `<`, `>`, `&` and line separators escaped.
|
|
131
|
+
- Tooltips built from escaped text; colours re-validated in the browser; tables and KPI cards use `textContent`.
|
|
132
|
+
- `Figure.update` refuses `formatter` strings and `$` keys.
|
|
133
|
+
- Tests: hostile category names and titles in every chart kind, the page parsed for unexpected tags and event handlers, CSP hashes checked against every inline script, runtime checked for eval-like constructs; verified in a real browser.
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
### Changed (documentation redesign)
|
|
137
|
+
- Editorial redesign of the docs site: navy hero home page, logo colours throughout, wider reading column, code and its output shown as one unit, quieter tables (`overrides/home.html`, `docs/stylesheets/tabsight.css`).
|
|
138
|
+
- Guide pages rewritten to explain the problem first, with real examples and opinions, and tables only for reference lists.
|
|
139
|
+
- Every example's printed output is real: `tools/render_doc_outputs.py` runs each page and writes the output; `tests/test_docs.py` fails if any shown output is stale.
|
|
140
|
+
|
|
141
|
+
### Fixed (found by the real outputs)
|
|
142
|
+
- `print(profile["Sales"])` now prints one readable line instead of every internal field.
|
|
143
|
+
- % of total column name: `Sales (% of total, shown rows)` instead of `Sales (% of total (of shown rows))`.
|
|
144
|
+
- With a date first and `top=`, "Other" rows now stay inside each date instead of sinking below every date.
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
### Added (documentation and logo)
|
|
148
|
+
- Documentation in `docs/`: getting started, 12 user-guide pages, API reference generated from docstrings, formula functions, locales, chart kinds, warnings and errors, and security. Reads on GitHub and builds a MkDocs Material site.
|
|
149
|
+
- `tests/test_docs.py` runs every documentation example and checks the locale, formula, chart-kind, settings and check-code tables against the code.
|
|
150
|
+
- Synthetic sample dataset `examples/superstore_sample.csv` (generated by `tools/make_sample_data.py`).
|
|
151
|
+
- Logo and wordmark (`docs/assets/`), with a dark-mode wordmark for GitHub.
|
|
152
|
+
- Docs CI workflow, with GitHub Pages deployment once the repository is public.
|
|
153
|
+
|
|
154
|
+
### Fixed
|
|
155
|
+
- Report text (`Profile.show()`, `CheckReport.show()`, `CleanReport.show()`) used "→", which crashed `print()` on Windows consoles using cp1252; it now uses "->".
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
### Added: aggregation and correctness
|
|
159
|
+
- `ts.aggregate`: group-by through exact re-aggregation *parts* (sum/count for means, Σw·x and Σw for weighted averages, values for median and distinct count). A property test checks 150 random datasets: re-combining filtered parts always equals pandas on the filtered raw rows, for all 8 aggregations.
|
|
160
|
+
- Date buckets (`ts.bucket`): year, quarter, month, week, day, hour, minute, second; fiscal years and quarters; Monday/Sunday/Saturday weeks. Missing periods as gaps, zeros or left out.
|
|
161
|
+
- Top N + exact "Other" (with its member list), stable sorting (value, natural, ordered categories, custom lists, `by:<measure>`), automatic split by currency, `min_group_size` privacy suppression.
|
|
162
|
+
- `ts.table_calc`: running total, % of total (filtered or fixed), rank, difference, % difference, moving average; restarts per group.
|
|
163
|
+
- `ts.calc`: calculated fields with our own parser (no eval): arithmetic, comparisons, IF/ELSEIF/ELSE, AND/OR/NOT, 7 aggregates and 30 row functions, `$parameters`. Aggregate formulas stay exact after filtering.
|
|
164
|
+
|
|
165
|
+
### Fixed
|
|
166
|
+
- Date reader used the caller's success threshold for structural choices; with threshold 0 every column was read as year-first.
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
### Added: foundation
|
|
170
|
+
- `ts.load`: safe local file loading (CSV/TSV/TXT, Excel with defusedxml, Parquet with pyarrow >= 15, JSON). URLs are rejected; encodings detected (UTF-8, BOM, Windows-1252); delimiters sniffed; leading zeros kept.
|
|
171
|
+
- `ts.profile`: roles, units (including from column names), default aggregation by unit, IDs, years, coordinates, ordered text, currency-code columns, mixed-currency warnings, hierarchies, overrides, and schema save/load. Every guess records its reason.
|
|
172
|
+
- `ts.check`: data-quality report with a score; changes nothing.
|
|
173
|
+
- `ts.clean`: optional cleaning (`off` / `safe` / `auto`) with apply, undo and reusable saved decisions.
|
|
174
|
+
- `ts.format_number` / `ts.format_date`: compact, full and raw styles; 14 locales including Indian lakh/crore and German/French spacing; Excel-style patterns through a strict parser; fiscal years.
|
|
175
|
+
- Colour registry (stable, pinnable, hex-validated), palettes, WCAG contrast checks; light, dark and print themes.
|
|
176
|
+
- `ChartSpec`: 33 chart kinds, strict versioned JSON that never runs code.
|
|
177
|
+
- Settings: `ts.set_defaults(...)` and scoped `with ts.config(...)` (contextvars).
|
|
178
|
+
- Translations for month/day names in 7 languages; English UI words.
|
|
179
|
+
|
|
180
|
+
### Security
|
|
181
|
+
- `docs/SECURITY_CHECKLIST.md`, applied to every change.
|
|
182
|
+
- AST guard test forbidding `eval`/`exec`/`pickle`/`subprocess`, `.format()` on runtime strings, network modules, and file readers outside `io.py`.
|
|
183
|
+
- ruff bandit rules (`S`), pip-audit and npm audit CI job, Dependabot.
|
|
184
|
+
- Fuzz tests (hypothesis) on number formatting, pattern parsing and spec loading; malicious-input tests for every new input.
|
|
185
|
+
|
|
186
|
+
### Added
|
|
187
|
+
- Project setup: package skeleton (`src/` layout), `pyproject.toml` (Python 3.11–3.14), ruff, mypy, pytest, CI workflow, licences and NOTICE.
|
|
188
|
+
- Pinned third-party files with a hash lock: ECharts 6.1.0, topojson-client 3.1.0, Natural Earth 5.1.2 raw data (`tools/fetch_vendor.py`).
|
|
189
|
+
- ECharts feature check in Node (`tests/js/echarts_features.cjs`), see `docs/decisions/0001-echarts-version.md`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Code of conduct
|
|
2
|
+
|
|
3
|
+
tabsight is a welcoming project. Everyone taking part, in issues, pull requests, discussions or anywhere else, is expected to:
|
|
4
|
+
|
|
5
|
+
- Be respectful and patient, including with beginners.
|
|
6
|
+
- Criticise ideas and code, never people.
|
|
7
|
+
- Assume good intent, and ask before assuming.
|
|
8
|
+
- Avoid harassment, insults, discriminatory language and unwanted personal attention.
|
|
9
|
+
|
|
10
|
+
Maintainers may edit or remove comments, and may block people who repeatedly break these rules.
|
|
11
|
+
|
|
12
|
+
To report a problem privately, contact the maintainers through the address in `SECURITY.md`. Reports are handled in confidence.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Contributing to tabsight
|
|
2
|
+
|
|
3
|
+
Thanks for helping. A few ground rules keep the package predictable.
|
|
4
|
+
|
|
5
|
+
## Principles every change must keep
|
|
6
|
+
|
|
7
|
+
1. Never change the user's DataFrame. Work on copies.
|
|
8
|
+
2. Every guess has a default and an override.
|
|
9
|
+
3. Warn, don't block (unless the user asks for strict mode).
|
|
10
|
+
4. Same input gives the same output. No randomness, no clock, no network.
|
|
11
|
+
5. Every data value that reaches HTML is escaped.
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
See the "Development setup" section in `README.md`.
|
|
16
|
+
|
|
17
|
+
## Before opening a pull request
|
|
18
|
+
|
|
19
|
+
- `python -m pytest` passes (Node tests run when Node.js is installed)
|
|
20
|
+
- `python -m ruff check .` and `python -m ruff format --check .` pass
|
|
21
|
+
- `python -m mypy` passes
|
|
22
|
+
- New behaviour has tests, including the "input DataFrame unchanged" check for public functions
|
|
23
|
+
- Code uses Python 3.11 syntax only (no 3.12+ features)
|
|
24
|
+
- `CHANGELOG.md` has an entry under "Unreleased"
|
|
25
|
+
|
|
26
|
+
## Branches and commits
|
|
27
|
+
|
|
28
|
+
- Never push to `main` directly: it is protected. Work on a branch named after the change,
|
|
29
|
+
for example `fix/kpi-compare-label` or `feat/server-mode`, and open a pull request.
|
|
30
|
+
- Write commit messages in the [Conventional Commits](https://www.conventionalcommits.org/)
|
|
31
|
+
style: `type(scope): summary`, in the imperative and under 72 characters. For example:
|
|
32
|
+
`fix(dashboard): keep drill crumbs after a theme switch`.
|
|
33
|
+
Types: `feat`, `fix`, `docs`, `test`, `refactor`, `perf`, `build`, `ci`, `chore`, `security`.
|
|
34
|
+
- Explain *why* in the commit body when it isn't obvious. Mark breaking changes with `!`
|
|
35
|
+
(`feat(spec)!: ...`) and a `BREAKING CHANGE:` line.
|
|
36
|
+
- Keep each pull request to one change. Pull requests are squash-merged, so the title
|
|
37
|
+
must follow the same commit style.
|
|
38
|
+
- CI must be green: tests on Python 3.11–3.14, lint, types and the dependency audit.
|
|
39
|
+
- Never commit data files, secrets, `.env` files, built sites (`site/`) or notebooks with outputs.
|
|
40
|
+
|
|
41
|
+
## Reporting security problems
|
|
42
|
+
|
|
43
|
+
Don't open a public issue. Follow [SECURITY.md](https://github.com/yesh069/tabsight/blob/main/SECURITY.md) and use GitHub's private
|
|
44
|
+
vulnerability reporting.
|
|
45
|
+
|
|
46
|
+
## Third-party files
|
|
47
|
+
|
|
48
|
+
Never edit files in `src/tabsight/render/static/` that come from upstream. Change the pinned version in `tools/fetch_vendor.py`, run `python tools/fetch_vendor.py --update`, and update `NOTICE`.
|
|
49
|
+
|
|
50
|
+
## Releasing (maintainer)
|
|
51
|
+
|
|
52
|
+
1. In a pull request, set the version in `src/tabsight/_version.py` (for example `0.1.0`) and rename the changelog's "Unreleased" heading to that version and date.
|
|
53
|
+
2. Once it is merged and CI is green, tag `main` and push the tag: `git tag v0.1.0 && git push origin v0.1.0`.
|
|
54
|
+
3. The **Release** workflow checks that the tag matches the version, builds the sdist and wheel, checks them, and publishes to PyPI with trusted publishing (no token stored anywhere). The first time, add the repository as a trusted publisher on pypi.org: project `tabsight`, workflow `release.yml`, environment `pypi`.
|
|
55
|
+
|
|
56
|
+
Release tags can't be moved or deleted (a ruleset protects `v*`), so a published version always matches its tag.
|
tabsight-0.1.0a1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tabsight contributors
|
|
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.
|
tabsight-0.1.0a1/NOTICE
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
tabsight
|
|
2
|
+
Copyright (c) 2026 tabsight contributors. Licensed under the MIT License (see LICENSE).
|
|
3
|
+
|
|
4
|
+
This product bundles third-party software and data:
|
|
5
|
+
|
|
6
|
+
------------------------------------------------------------------------------
|
|
7
|
+
Apache ECharts 6.1.0
|
|
8
|
+
File: src/tabsight/render/static/echarts.min.js
|
|
9
|
+
License: Apache License 2.0 (full text: licenses/echarts-LICENSE.txt)
|
|
10
|
+
Its NOTICE file (licenses/echarts-NOTICE.txt) reads:
|
|
11
|
+
|
|
12
|
+
Apache ECharts
|
|
13
|
+
Copyright 2017-2026 The Apache Software Foundation
|
|
14
|
+
|
|
15
|
+
This product includes software developed at
|
|
16
|
+
The Apache Software Foundation (https://www.apache.org/).
|
|
17
|
+
|
|
18
|
+
------------------------------------------------------------------------------
|
|
19
|
+
topojson-client 3.1.0
|
|
20
|
+
File: src/tabsight/render/static/topojson-client.min.js
|
|
21
|
+
Copyright 2012-2019 Michael Bostock
|
|
22
|
+
License: ISC (full text: licenses/topojson-client-LICENSE.txt)
|
|
23
|
+
|
|
24
|
+
------------------------------------------------------------------------------
|
|
25
|
+
Natural Earth (map data, version 5.1.2)
|
|
26
|
+
Made with Natural Earth. Free vector and raster map data @ naturalearthdata.com.
|
|
27
|
+
Public domain. Used to build the bundled map files in src/tabsight/geo/data/.
|
|
28
|
+
Natural Earth's default view is used for disputed borders.
|