Showing preview only (274K chars total). Download the full file or copy to clipboard to get everything.
Repository: cube-js/awesome-tools
Branch: master
Commit: dc042cb6759d
Files: 167
Total size: 238.5 KB
Directory structure:
gitextract_elt7bwjc/
├── .github/
│ └── workflows/
│ └── scheduled-data-update.yml
├── .gitignore
├── .netlify/
│ └── state.json
├── .nvmrc
├── LICENSE
├── README.md
├── components/
│ ├── Button/
│ │ ├── Button.jsx
│ │ ├── Button.module.scss
│ │ └── index.js
│ ├── ButtonLanding/
│ │ ├── ButtonLanding.jsx
│ │ └── ButtonLanding.module.css
│ ├── CTAButtons/
│ │ ├── CTAButtons.jsx
│ │ └── CTAButtons.module.css
│ ├── Card/
│ │ ├── Card.jsx
│ │ └── Card.module.scss
│ ├── Chip/
│ │ ├── Chip.jsx
│ │ ├── Chip.module.scss
│ │ └── index.js
│ ├── ExploreToolsCard/
│ │ ├── ExploreToolsCard.jsx
│ │ ├── ExploreToolsCard.module.scss
│ │ └── index.js
│ ├── Footer/
│ │ ├── Footer.jsx
│ │ ├── Footer.module.scss
│ │ └── index.js
│ ├── Gallery/
│ │ ├── Gallery.jsx
│ │ ├── Gallery.module.scss
│ │ └── index.js
│ ├── GetHelpCard/
│ │ ├── GetHelpCard.jsx
│ │ ├── GetHelpCard.module.scss
│ │ └── index.js
│ ├── GetStartedCard/
│ │ ├── GetStartedCard.jsx
│ │ ├── GetStartedCard.module.scss
│ │ └── index.js
│ ├── GlobalSignUp/
│ │ ├── GlobalSignUp.jsx
│ │ └── GlobalSignUp.module.css
│ ├── Header/
│ │ ├── Header.jsx
│ │ ├── Header.module.scss
│ │ └── index.js
│ ├── ListPage/
│ │ ├── ListPage.jsx
│ │ └── index.js
│ ├── Slider/
│ │ ├── Slider.jsx
│ │ ├── Slider.module.scss
│ │ └── index.js
│ ├── Text/
│ │ ├── AccentedText.jsx
│ │ ├── AccentedText.module.scss
│ │ ├── H1.jsx
│ │ ├── H1.module.scss
│ │ ├── H2.jsx
│ │ └── H2.module.scss
│ ├── ToolCard/
│ │ ├── ToolCard.jsx
│ │ ├── ToolCard.module.scss
│ │ └── index.js
│ ├── ToolPage/
│ │ ├── Description.jsx
│ │ ├── Description.module.scss
│ │ ├── DescriptionCards.jsx
│ │ ├── DescriptionCards.module.scss
│ │ ├── Header.jsx
│ │ ├── Header.module.scss
│ │ ├── HowToGetHelp.jsx
│ │ ├── HowToGetHelp.module.scss
│ │ ├── HowToGetStarted.jsx
│ │ ├── HowToGetStarted.module.scss
│ │ ├── Integrations.jsx
│ │ ├── Integrations.module.scss
│ │ ├── Popularity.jsx
│ │ ├── Popularity.module.scss
│ │ ├── ToolPage.jsx
│ │ └── ToolPageForFramework.jsx
│ └── ToolsNumberControl/
│ ├── ToolsNumberControl.jsx
│ ├── ToolsNumberControl.module.scss
│ └── index.js
├── copy/
│ └── tools/
│ ├── .example
│ ├── .extended.example
│ ├── ag-grid.yml
│ ├── amcharts.yml
│ ├── ant-design-charts.yml
│ ├── anychart.yml
│ ├── apexcharts.yml
│ ├── appsmith.yml
│ ├── billboard.yml
│ ├── c3.yml
│ ├── chartist.yml
│ ├── chartjs.yml
│ ├── cytoscape.yml
│ ├── d3.yml
│ ├── datasette.yml
│ ├── deck-gl.yml
│ ├── echarts.yml
│ ├── flot.yml
│ ├── frappe.yml
│ ├── fusioncharts.yml
│ ├── g2.yml
│ ├── g2plot.yml
│ ├── g6.yml
│ ├── google-charts.yml
│ ├── highcharts.yml
│ ├── kepler-gl.yml
│ ├── laue.yml
│ ├── layer-cake.yml
│ ├── leaflet.yml
│ ├── lightweight-charts.yml
│ ├── mapbox-gl.yml
│ ├── material-ui-data-grid.yml
│ ├── metabase.yml
│ ├── muze.yml
│ ├── ngx-charts.yml
│ ├── nivo.yml
│ ├── observable-plot.yml
│ ├── p5.yml
│ ├── pancake.yml
│ ├── perspective.yml
│ ├── plotly.yml
│ ├── plottable.yml
│ ├── pts.yml
│ ├── react-charts.yml
│ ├── reaflow.yml
│ ├── reaviz.yml
│ ├── recharts.yml
│ ├── redash.yml
│ ├── rough.yml
│ ├── roughviz.yml
│ ├── semiotic.yml
│ ├── stackgl.yml
│ ├── superset.yml
│ ├── three.yml
│ ├── toast-ui-chart.yml
│ ├── unovis.yml
│ ├── vega-lite.yml
│ ├── vega.yml
│ ├── victory.yml
│ ├── vis.yml
│ ├── visx.yml
│ ├── vizzu.yml
│ └── zingchart.yml
├── data/
│ ├── filter.js
│ ├── frameworks.js
│ ├── tools.js
│ ├── types.js
│ └── useSlackMembers.js
├── data-update-worker/
│ ├── .gitignore
│ ├── fetchData.js
│ ├── index.js
│ ├── notifySlack.js
│ └── package.json
├── netlify.toml
├── next-sitemap.config.js
├── next.config.js
├── package.json
├── pages/
│ ├── _app.js
│ ├── _document.js
│ ├── for/
│ │ ├── [framework]/
│ │ │ ├── charting-libraries.js
│ │ │ └── index.js
│ │ └── open-source.js
│ ├── index.js
│ └── tools/
│ └── [id]/
│ ├── [framework].js
│ └── index.js
├── public/
│ ├── browserconfig.xml
│ ├── robots.txt
│ ├── site.webmanifest
│ ├── sitemap-0.xml
│ └── sitemap.xml
├── styles/
│ ├── _variables.scss
│ ├── globals.scss
│ └── indexPage.scss
├── update-copy.sh
└── utils/
├── number.js
└── tracking.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/scheduled-data-update.yml
================================================
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Scheduled data update
on:
workflow_dispatch: null
schedule:
# * is a special character in YAML so you have to quote this string
- cron: "30 10 * * *"
# push:
# branches:
# - master
jobs:
build:
name: Update data on schedule
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "18.x"
- name: Restore cache
uses: actions/cache@v2
with:
path: |
node_modules
*/*/node_modules
key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}
- name: Install
run: yarn install
- name: Run update job script
run: export ACCESS_TOKEN_GITHUB=${{ secrets.ACCESS_TOKEN_GITHUB }} && export SLACK_WEBHOOK_URL=${{ secrets.SLACK_WEBHOOK_URL }} && sh ./update-copy.sh
- name: Commit changes
uses: EndBug/add-and-commit@v7 # You can change this to use a specific version
with:
author_name: Data Update Worker
author_email: igor@cube.dev
cwd: "."
default_author: github_actor
message: "chore(copy): update data on schedule"
pull: "--no-rebase"
push: true
# - name: Build Next site
# run: sh ./build-site.sh
# - name: Install Netlify CLI
# run: npm install -g netlify-cli
# - name: Deploy to Netlify
# run: netlify deploy --dir=out --prod
# env:
# NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
================================================
FILE: .gitignore
================================================
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
# Local Netlify folder
# .netlify
================================================
FILE: .netlify/state.json
================================================
{
"siteId": "51f8094d-998a-424a-b471-6499f5bf2933"
}
================================================
FILE: .nvmrc
================================================
lts/*
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Cube Dev, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
<h1><a href='https://awesome.cube.dev'>awesome.cube.dev</a> — charts, data grids, maps, etc.</h1>
Choose the best tool for your needs by type, framework, language, or license. Get started in an instant.
<p align="center"><img src='.github/screenshot.png'/></p>
Visit [awesome.cube.dev](https://awesome.cube.dev) or suggest an [improvement](https://github.com/cube-js/awesome-tools/issues).
================================================
FILE: components/Button/Button.jsx
================================================
import styles from "./Button.module.scss";
import Link from "next/link";
export default function Button(props) {
return (
<Link href={props.href} legacyBehavior>
<a
type="button"
role="button"
{...props}
className={
props.className
? `${props.className} ${styles.button}`
: styles.button
}
>
<span>{props.children}</span>
</a>
</Link>
);
}
================================================
FILE: components/Button/Button.module.scss
================================================
@import "/styles/variables";
.button {
font-family: CeraPro;
font-size: 20px;
// line-height: 25px;
text-align: center;
letter-spacing: 0.02em;
color: $purple-02;
border: 2px solid $purple-02;
padding: 8px 22px;
border-radius: 12px;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: transparent;
cursor: pointer;
transition: background-color 0.3s ease-in-out, border-color 0.3s ease-in-out,
color 0.3s ease-in-out;
&:hover {
background: rgba(202, 201, 255, 0.5);
color: $purple-hover;
border-color: $purple-hover;
}
&:active {
background: rgba(202, 201, 255, 0.8);
color: $purple-press;
border-color: $purple-press;
}
&[disabled="disabled"] {
user-select: none;
pointer-events: none;
cursor: not-allowed;
border-color: $dark-05;
color: $dark-05;
}
}
================================================
FILE: components/Button/index.js
================================================
import Button from "./Button";
export default Button;
================================================
FILE: components/ButtonLanding/ButtonLanding.jsx
================================================
import * as React from 'react';
import { useEffect } from 'react';
import Link from 'next/link';
import classNames from 'classnames/bind';
import { useState } from 'react';
import styles from './ButtonLanding.module.css';
const cn = classNames.bind(styles);
const loader = (
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none">
<path
d="M8 15a7 7 0 0 1-7-7 .5.5 0 1 1 1 0 6 6 0 0 0 3.7 5.5 6 6 0 0 0 6.6-1.2 6 6 0 0 0 0-8.6A6 6 0 0 0 8 2a.5.5 0 1 1 0-1 7 7 0 0 1 7 7 7 7 0 0 1-7 7Z"
fill="currentColor"
stroke="currentColor"
strokeWidth=".5"
/>
</svg>
);
export const ButtonLanding = React.forwardRef(
(
{
appearance = 'light',
color = 'transparent',
variant = 'default',
type = 'button',
size = 'm',
disabled = false,
pseudoHover = false,
pseudoFocus = false,
pseudoActive = false,
isLoad = false,
className = '',
children,
href = '',
...rest
},
ref
) => {
const loaderAppearAnimationDuration = 700;
const classNames = cn('Button', `Button--appearance-${appearance}`, className, {
'Button--pink': color === 'pink',
'Button--purple': color === 'purple',
'Button--cherry': color === 'cherry',
'Button--transparent': color === 'transparent',
'Button--back': color === 'back',
'Button--size-s': size === 's',
'Button--size-m': size === 'm',
'Button--size-l': size === 'l',
'Button--variant-outline': variant === 'outline',
'Button--pseudoHover': pseudoHover,
'Button--pseudoFocus': pseudoFocus,
'Button--pseudoActive': pseudoActive,
});
const [isLoaderVisible, setIsLoaderVisible] = useState(isLoad);
useEffect(() => {
if (isLoad === false) {
setTimeout(() => {
setIsLoaderVisible(false);
}, loaderAppearAnimationDuration);
} else {
setIsLoaderVisible(true);
}
}, [isLoad]);
let prefix;
if (isLoad || isLoaderVisible) {
const prefixClassName = cn('Button__prefix', 'Button__prefix--loader', {
'Button__prefix--removing': isLoaderVisible !== isLoad && !isLoad,
});
prefix = <span className={prefixClassName}>{loader}</span>;
}
if (href) {
if (href.startsWith('/')) {
return (
<Link href={href} passHref legacyBehavior>
<a ref={ref} {...rest} className={classNames}>
{children}
</a>
</Link>
);
}
return (
<a ref={ref} {...rest} href={href} className={classNames}>
{children}
</a>
);
}
return (
<button
ref={ref}
{...rest}
className={classNames}
type={type}
disabled={disabled || isLoad}
style={{ '--loader-time': loaderAppearAnimationDuration + 'ms' }}
>
{prefix}
{children}
</button>
);
}
);
export default ButtonLanding;
================================================
FILE: components/ButtonLanding/ButtonLanding.module.css
================================================
.Button {
--dark: hsl(240, 32%, 10%);
--dark_a70: rgba(15, 15, 35, 0.7);
--dark_01: var(--dark);
--dark_02: hsla(240, 14%, 23%);
--dark_03: hsl(240, 8%, 45%);
--dark_03_a50: hsl(240, 32%, 10%, 0.5);
--dark_02_a75: hsla(240, 32%, 10%, 0.75);
--dark_04: hsl(240, 9%, 69%);
--dark_04_a30: hsl(240, 32%, 10%, 0.3);
--dark_05_a12: hsl(240, 32%, 10%, 0.12);
--dark_05: hsla(240, 16%, 91%, 1);
--dark_06: hsl(240, 40%, 10%);
--dark_bg: hsl(240, 12%, 97%, 1);
--dark_bg_a04: hsla(240, 32%, 10%, 0.04);
--dark_bg_a08: hsla(240, 32%, 10%, 0.08);
--white: hsla(240, 0%, 100%, 1);
--white_a01: hsla(240, 0%, 100%, 0.1);
--white_a08: hsla(0, 0%, 100%, 0.08);
--white_a12: hsla(240, 0%, 100%, 0.12);
--white_a15: hsla(240, 0%, 100%, 0.15);
--white_a24: hsla(240, 0%, 100%, 0.24);
--gray_01: hsl(228, 6%, 31%, 1);
--gray_02: hsl(225, 4%, 39%, 1);
--purple: hsl(251, 94%, 66%, 1);
--purple_03: hsla(241, 94%, 84%, 1);
--purple_03_a60: hsl(241, 94%, 66%, 0.6);
--purple_04_a30: hsl(241, 94%, 66%, 0.3);
--purple_bg_02: hsl(240, 50%, 98%);
--purple_bg_a08: hsla(244, 94%, 66%, 0.08);
--purple_bright: hsl(251, 61%, 52%, 1);
--purple_a12: hsla(251, 94%, 66%, 0.12);
--pink: hsl(342, 69%, 53%, 1);
--pink_03_a60: hsl(342, 69%, 53%, 0.6);
--pink_04_a30: hsl(342, 69%, 53%, 0.3);
--pink_bg_a10: hsl(342, 69%, 53%, 0.1);
--pink_bright: hsl(342, 62%, 48%, 1);
--pink_bright_02: var(--pink_bright);
--cherry: var(--pink);
--cherry_dark: var(--pink_bright);
--white_a08_on_dark_02: #434353;
--loader_time: 700ms;
--hover_transition: 0.2s;
transition: background-color var(--hover_transition), color var(--hover_transition),
box-shadow var(--hover_transition), opacity var(--loader_time);
font-family: inherit;
font-weight: 700;
border: none;
margin: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
text-decoration: none;
}
.Button:hover {
cursor: pointer;
}
.Button:disabled {
opacity: 0.4;
cursor: default;
}
/* transparent */
.Button--transparent {
background-color: transparent;
color: var(--dark);
}
.Button--transparent.Button--variant-outline {
box-shadow: inset 0 0 0 1px var(--dark_05);
}
.Button--transparent.Button--variant-outline:hover,
.Button--transparent.Button--variant-outline.Button--pseudoHover {
background-color: var(--dark_bg_a04);
}
.Button--transparent.Button--variant-outline:focus-visible,
.Button--transparent.Button--variant-outline.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--transparent.Button--variant-outline:active,
.Button--transparent.Button--variant-outline.Button--pseudoActive {
background-color: var(--dark_bg_a04);
box-shadow: inset 0 0 0 1px var(--dark_03);
}
/* transparent-dark */
.Button--appearance-dark.Button--transparent {
background-color: transparent;
color: var(--white);
}
.Button--appearance-dark.Button--transparent.Button--variant-outline {
box-shadow: inset 0 0 0 1px var(--dark_03);
}
.Button--appearance-dark.Button--transparent.Button--variant-outline:hover,
.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoHover {
background-color: var(--white_a08);
}
.Button--appearance-dark.Button--transparent.Button--variant-outline:focus-visible,
.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--appearance-dark.Button--transparent.Button--variant-outline:active,
.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoActive {
background-color: var(--white_a08);
box-shadow: inset 0 0 0 1px var(--dark_05);
}
/* purple */
.Button--purple {
background-color: var(--purple);
color: var(--white);
}
.Button--purple:hover,
.Button--purple.Button--pseudoHover {
background-color: var(--purple_bright);
color: var(--white);
}
.Button--purple:focus-visible,
.Button--purple.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--purple_04_a30);
}
.Button--purple:active,
.Button--purple.Button--pseudoActive {
background-color: var(--purple);
box-shadow: inset 0 0 0 1px var(--purple_bright);
color: var(--white);
}
/* purple-outline */
.Button--purple.Button--variant-outline {
background-color: var(--white);
color: var(--purple_bright);
box-shadow: inset 0 0 0 1px var(--purple_04_a30);
}
.Button--purple.Button--variant-outline:hover,
.Button--purple.Button--variant-outline.Button--pseudoHover {
background-color: var(--purple_bg_a08);
color: var(--purple_bright);
}
.Button--purple.Button--variant-outline:focus-visible,
.Button--purple.Button--variant-outline.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--purple_04_a30);
}
.Button--purple.Button--variant-outline:active,
.Button--purple.Button--variant-outline.Button--pseudoActive {
background-color: var(--purple_bg_a08);
box-shadow: inset 0 0 0 1px var(--purple_bright);
color: var(--purple_bright);
}
/* autoprefixer: ignore next */
@supports not selector(:focus-visible) {
.Button--purple:focus {
box-shadow: 0 0 0 3px var(--purple_04_a30);
}
}
/* pink */
.Button--pink {
background-color: var(--pink);
color: var(--white);
}
.Button--pink:hover,
.Button--pink.Button--pseudoHover {
background-color: var(--pink_bright);
color: var(--white);
}
.Button--pink:focus-visible,
.Button--pink.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--pink:active,
.Button--pink.Button--pseudoActive {
background-color: var(--pink);
box-shadow: inset 0 0 0 1px var(--pink_bright);
color: var(--white);
}
/* pink-outline */
.Button--pink.Button--variant-outline {
background-color: var(--white);
color: var(--pink_bright);
box-shadow: inset 0 0 0 1px var(--pink_04_a30);
}
.Button--pink.Button--variant-outline:hover,
.Button--pink.Button--variant-outline.Button--pseudoHover {
background-color: var(--pink_bg_a10);
color: var(--pink_bright);
}
.Button--pink.Button--variant-outline:focus-visible,
.Button--pink.Button--variant-outline.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--pink.Button--variant-outline:active,
.Button--pink.Button--variant-outline.Button--pseudoActive {
background-color: var(--pink_bg_a10);
box-shadow: inset 0 0 0 1px var(--pink_bright);
color: var(--pink_bright);
}
/* pink-outline dark */
.Button--appearance-dark.Button--pink.Button--variant-outline {
background-color: transparent;
color: var(--white);
}
/* autoprefixer: ignore next */
@supports not selector(:focus-visible) {
.Button--pink:focus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
}
/* cherry */
.Button--cherry {
background-color: var(--cherry);
color: var(--white);
}
.Button--cherry:hover,
.Button--cherry.Button--pseudoHover {
background-color: var(--cherry_dark);
}
.Button--cherry:focus-visible,
.Button--cherry.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--cherry:active,
.Button--cherry.Button--pseudoActive {
background-color: var(--cherry);
box-shadow: inset 0 0 0 1px var(--cherry_dark);
}
/* cherry-outline */
.Button--cherry.Button--variant-outline {
color: var(--cherry);
background-color: transparent;
box-shadow: inset 0 0 0 1px var(--pink_03_a60);
}
.Button--cherry.Button--variant-outline:hover,
.Button--cherry.Button--variant-outline.Button--pseudoHover {
background-color: var(--pink_bg_a10);
}
.Button--cherry.Button--variant-outline:focus-visible,
.Button--cherry.Button--variant-outline.Button--pseudoFocus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
.Button--cherry.Button--variant-outline:active,
.Button--cherry.Button--variant-outline.Button--pseudoActive {
background-color: var(--pink_bg_a10);
box-shadow: inset 0 0 0 1px var(--cherry);
}
/* cherry-outline dark */
.Button--appearance-dark.Button--cherry.Button--variant-outline {
color: var(--white);
}
/* autoprefixer: ignore next */
@supports not selector(:focus-visible) {
.Button--cherry:focus {
box-shadow: 0 0 0 3px var(--pink_04_a30);
}
}
/* sizes */
.Button--size-s {
height: 40px;
padding: 0 16px;
font-size: 16px;
border-radius: 8px;
}
.Button--size-m {
height: 48px;
padding: 0 24px;
font-size: 16px;
border-radius: 8px;
}
.Button--size-l {
height: 64px;
padding: 0 40px;
font-size: 20px;
font-style: normal;
font-weight: 700;
border-radius: 8px;
}
.Button__prefix--loader {
animation-name: loader_appear;
animation-duration: var(--loader_time);
animation-fill-mode: forwards;
width: 16px;
}
.Button__prefix--loader + * {
margin-left: 8px;
}
.Button__prefix--removing {
animation-name: loader_disappear;
}
.Button__prefix--loader svg {
display: block;
animation-name: loader_rotation;
animation-duration: var(--loader_time);
animation-iteration-count: infinite;
animation-timing-function: linear;
}
@keyframes loader_appear {
0% {
width: 0;
margin-right: 0;
opacity: 0;
}
33% {
opacity: 0;
}
66% {
width: 16px;
margin-right: 8px;
}
100% {
opacity: 1;
}
}
@keyframes loader_disappear {
100% {
width: 0;
margin-right: 0;
opacity: 0;
}
66% {
opacity: 0;
}
33% {
width: 16px;
margin-right: 8px;
}
0% {
opacity: 1;
}
}
@keyframes loader_rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
================================================
FILE: components/CTAButtons/CTAButtons.jsx
================================================
import * as React from 'react';
import classnames from 'classnames/bind';
import classes from './CTAButtons.module.css';
import ButtonLanding from '../ButtonLanding/ButtonLanding';
import { trackClick } from '../../utils/tracking';
const cn = classnames.bind(classes);
export const CTAButtons = ({
reverseButtonsOrder = false,
signupCTAId,
bookDemoCTAId,
}) => {
const reverse = reverseButtonsOrder;
const bookProps = {
href: 'https://cube.dev/contact',
onClick: bookDemoCTAId ? trackClick(bookDemoCTAId) : undefined,
children: 'Request a demo',
};
const signupProps = {
href: 'https://cubecloud.dev/auth/signup',
onClick: signupCTAId ? trackClick(signupCTAId) : undefined,
children: 'Try Free',
};
return (
<>
<ButtonLanding
size="l"
color="cherry"
variant="default"
className={classes.CTAButtons__button}
{...(reverse ? bookProps : signupProps)}
/>
<ButtonLanding
size="l"
color="cherry"
variant="outline"
appearance="dark"
className={classes.CTAButtons__button}
{...(reverse ? signupProps : bookProps)}
/>
</>
);
};
================================================
FILE: components/CTAButtons/CTAButtons.module.css
================================================
.CTAButtons__button {
color: white;
}
================================================
FILE: components/Card/Card.jsx
================================================
import styles from "./Card.module.scss";
import { ReactSVG } from "react-svg";
export default function Card(props) {
let Wrapper = "a";
if (props.notLink) {
Wrapper = "div";
}
return (
<Wrapper
href={props?.link}
target="_blank"
role="button"
className={props.height ? styles.full : null}
>
<div
big={props.isBig ? "big" : null}
color={props.color ? props.color : null}
className={
props.className ? styles.card + " " + props.className : styles.card
}
height={props.height || null}
>
{props.icons &&
props.icons.map((icon) => {
return (
<ReactSVG
key={icon}
className={styles.icon}
wrapper="span"
src={icon}
width="100%"
height="100%"
/>
);
})}
{props.icon && (
<ReactSVG
className={styles.icon}
wrapper="div"
src={props.icon}
></ReactSVG>
)}
<div className={styles.text}>{props.text}</div>
{props.description && (
<div className={styles.description}>{props.description}</div>
)}
{props.smallText && (
<div className={styles.smallText}>{props.smallText}</div>
)}
{props.footerText && (
<div
className={styles.footer}
dangerouslySetInnerHTML={{ __html: props.footerText }}
></div>
)}
</div>
</Wrapper>
);
}
================================================
FILE: components/Card/Card.module.scss
================================================
@import "/styles/variables";
.card {
width: 100%;
padding: 32px;
border-radius: 24px;
border: 1px solid $dark-07;
color: $dark;
background-color: $dark-07;
transition: background-color 0.3s ease-in-out, border-color 0.3s ease-in-out,
color 0.3s ease-in-out;
&:hover {
background: $light;
border-color: $purple-04;
}
&:active {
background: #ececff;
border-color: $purple-03;
}
}
.card[color="orange"] {
color: $orange;
background-color: $orange-02;
border-color: $orange-02;
&:hover {
background: #ffecda;
border-color: #ffc2a5;
}
&:active {
background: #ffe4cb;
border-color: #ff905d;
}
&[disabled="disabled"] {
user-select: none;
pointer-events: none;
cursor: not-allowed;
border-color: $dark-05;
color: $dark-05;
}
}
.icon {
width: 22px;
height: 22px;
margin-bottom: 10px;
display: inline-flex;
margin-right: 8px;
svg {
width: 100%;
height: 100%;
}
}
.text {
// margin-top: 10px;
font-size: 24px;
line-height: 30px;
font-weight: 500;
// margin-bottom: 8px;
}
// .description {
// //
// }
.smallText {
margin-top: 8px;
}
.link {
margin-top: 8px;
}
.footer {
margin-top: 24px;
color: $dark-02;
}
.card[color="orange"] {
.footer {
color: $orange;
}
}
.card[big="big"] {
width: 100%;
padding: 48px 42px;
border-radius: 24px;
.text {
font-size: 48px;
line-height: 60px;
margin-bottom: 0;
}
.icon {
width: 24px;
height: 24px;
margin-bottom: 10px;
}
}
// fix
.full {
height: 100%;
}
.card[height="full"] {
height: 100%;
}
================================================
FILE: components/Chip/Chip.jsx
================================================
import styles from "./Chip.module.scss";
export default function Chip(props) {
return (
<button
type="button"
onClick={props.onClick}
className={
props.className ? styles.chip + " " + props.className : styles.chip
}
active={props.active}
>
<span>
{props.icon && (
<img
className={styles.icon}
src={`/images/logo/${props.icon}`}
alt={props.title}
/>
)}
<span>{props.title}</span>
</span>
</button>
);
}
================================================
FILE: components/Chip/Chip.module.scss
================================================
@import "/styles/variables";
.chip {
font-family: CeraPro;
border: none;
padding: 8px 16px;
background-color: $dark-06;
border: 1px solid $dark-06;
border-radius: 40px;
color: $dark-03;
font-size: 24px;
line-height: 30px;
transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out,
border-color 0.3s ease-in-out;
cursor: pointer;
display: flex;
align-items: center;
span {
display: inline-flex;
align-items: center;
}
img {
width: 18px;
height: 18px;
margin-right: 8px;
fill: red;
}
&:hover {
@media (hover) {
color: $purple-hover;
border: 1px solid $purple-04;
}
}
&[active="active"] {
background-color: $light;
color: $purple-hover;
border: 1px solid $purple-04;
}
@media (max-width: 991.98px) {
margin-top: 8px;
margin-bottom: 8px;
}
@media (max-width: 767.98px) {
padding: 4px 8px;
}
}
.icon {
display: inline-flex;
margin-right: 8px;
min-width: 22px;
min-height: 22px;
svg {
width: 22px;
height: 22px;
}
}
================================================
FILE: components/Chip/index.js
================================================
import Chip from "./Chip";
export default Chip;
================================================
FILE: components/ExploreToolsCard/ExploreToolsCard.jsx
================================================
import styles from "./ExploreToolsCard.module.scss";
import { ReactSVG } from "react-svg";
export default function ExploreToolsCard(props) {
return (
<a
className="col-6 col-md-6 col-lg-4 col-xl-2"
onClick={props.onClick}
role="button"
>
<div className={styles.exploreToolsCard} active={props.active || null}>
<div className={styles.exploreToolsCard__wrap}>
<h2
className={styles.exploreToolsCard__text}
dangerouslySetInnerHTML={{ __html: props.text.replace(' ', '<br/>') }}
></h2>
</div>
{props.image && (
<ReactSVG
wrapper="span"
src={`/images/${props.image}`}
className={styles.exploreToolsCard__image}
/>
)}
</div>
</a>
);
}
================================================
FILE: components/ExploreToolsCard/ExploreToolsCard.module.scss
================================================
@import "/styles/variables";
.exploreToolsCard {
background: $dark-06;
border: 1px solid $dark-06;
transition: border 0.3s ease-in-out, background 0.3s ease-in-out;
border-radius: 24px;
overflow: hidden;
cursor: pointer;
margin-bottom: 16px;
user-select: none;
font-weight: 500;
&[active="active"] {
background-color: darken(#ecebff, 5%);
}
&__wrap {
padding: 24px 24px 0px 24px;
@media (max-width: 767.98px) {
padding: 16px 16px 0 16px;
}
}
&__text {
font-size: 24px;
font-weight: 500;
line-height: 30px;
color: $dark-03;
margin: 0;
transition: color 0.3s ease-in-out;
}
&__image {
display: flex;
align-items: center;
justify-content: flex-end;
transition: color 0.3s ease-in-out;
color: $dark-05;
height: 64px;
}
&:hover {
// fix mobile hover effect
@media (hover) {
border: 1px solid $purple-04;
.exploreToolsCard__text {
color: $purple-hover;
}
.exploreToolsCard__image {
color: $purple-04;
}
}
}
&[active="active"] {
background: $light;
border: 1px solid $purple-04;
.exploreToolsCard__text {
color: $purple-hover;
}
.exploreToolsCard__image {
color: $purple-04;
}
}
&[disabled="disabled"] {
.exploreToolsCard__text {
color: $dark-07;
}
}
@media (max-width: 767.98px) {
margin-bottom: 8px;
}
}
================================================
FILE: components/ExploreToolsCard/index.js
================================================
import ExploreToolsCard from "./ExploreToolsCard";
export default ExploreToolsCard;
================================================
FILE: components/Footer/Footer.jsx
================================================
import styles from "./Footer.module.scss";
import { ReactSVG } from "react-svg";
export default function Footer() {
return (
<footer className={styles.footer + " container custom-container"}>
<div>
<ReactSVG
className={styles.footer__logo}
src="/images/logo/cubejs-logo.svg"
/>
</div>
<div className={styles.info}>
<p>
Created and maintained in open source
<br />
by{" "}
<a href="https://cube.dev/" target="_blank">
Cube Dev
</a>
, the creators of{" "}
<a href="https://github.com/cube-js/cube.js" target="_blank">
Cube
</a>
</p>
<p>
Want to add a new tool or update the info?{" "}
<br className="xs-hidden" />
We appreciate{" "}
<a
href="https://github.com/cube-js/awesome-tools/issues"
target="_blank"
>
issues
</a>{" "}
and{" "}
<a
href="https://github.com/cube-js/awesome-tools/pulls"
target="_blank"
>
pull requests
</a>
</p>
</div>
</footer>
);
}
================================================
FILE: components/Footer/Footer.module.scss
================================================
@import "/styles/variables";
.footer {
margin-top: 90px;
border-top: 2px solid #e7e9ed;
padding-top: 64px;
padding-bottom: 80px;
}
.info {
margin-top: 16px;
display: flex;
align-items: center;
justify-content: space-between;
p {
margin: 0;
font-size: 16px;
line-height: 28px;
color: $dark-03;
}
a {
color: $dark;
}
@media (max-width: 767.98px) {
flex-direction: column;
align-items: flex-start;
p:last-child {
margin-top: 16px;
}
}
}
================================================
FILE: components/Footer/index.js
================================================
import Footer from "./Footer";
export default Footer;
================================================
FILE: components/Gallery/Gallery.jsx
================================================
import dynamic from "next/dynamic";
import styles from "./Gallery.module.scss";
import H2 from "../Text/H2";
const Slider = dynamic(() => import("../../components/Slider"));
export default function Gallery(props) {
return (
<div className={styles.gallery + " row"}>
<div className="col-sm-3">
<H2>Gallery</H2>
{props.link && (
<div className="mt-sm">
<a href={props.link} className="link" target="_blank">
All examples →
</a>
</div>
)}
</div>
<div className={styles.sliderWrap + " col-sm-9"}>
<Slider slidesData={props.gallery} />
</div>
</div>
);
}
================================================
FILE: components/Gallery/Gallery.module.scss
================================================
.gallery {
margin-bottom: 104px;
@media (max-width: 767.98px) {
margin-bottom: 48px;
}
}
.sliderWrap {
@media (max-width: 767.98px) {
margin-top: 24px;
}
}
================================================
FILE: components/Gallery/index.js
================================================
import Gallery from "./Gallery";
export default Gallery;
================================================
FILE: components/GetHelpCard/GetHelpCard.jsx
================================================
import styles from "./GetHelpCard.module.scss";
import Link from "next/link";
export default function Card(props) {
return (
<Link href={props.href} legacyBehavior>
<a target="_blank">
<div
className={
props.className ? styles.card + " " + props.className : styles.card
}
>
{props.icon && (
<div
className={styles.icon}
style={{ backgroundImage: `url(${props.icon})` }}
></div>
)}
{props.title && <div className={styles.title}>{props.title}</div>}
{props.footer && <div className={styles.footer}>{props.footer}</div>}
</div>
</a>
</Link>
);
}
================================================
FILE: components/GetHelpCard/GetHelpCard.module.scss
================================================
@import "/styles/variables";
.card {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);
transition: box-shadow 0.32s ease-in-out;
border-radius: 32px;
background: #ffffff;
padding: 32px;
cursor: pointer;
height: 100%;
&:hover {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);
}
}
.icon {
width: 64px;
height: 64px;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
}
.title {
margin-top: 16px;
font-size: 24px;
font-weight: 500;
line-height: 30px;
color: $dark;
}
.footer {
margin-top: 8px;
font-size: 14px;
line-height: 18px;
letter-spacing: 0.02em;
color: $dark;
}
================================================
FILE: components/GetHelpCard/index.js
================================================
import GetHelpCard from "./GetHelpCard";
export default GetHelpCard;
================================================
FILE: components/GetStartedCard/GetStartedCard.jsx
================================================
import styles from "./GetStartedCard.module.scss";
import { ReactSVG } from "react-svg";
export default function Card(props) {
return (
<a href={props.link} target="_blank">
<div
className={
props.className ? styles.card + " " + props.className : styles.card
}
>
{props.icon && (
<ReactSVG
className={styles.icon}
wrapper="div"
src={props.icon}
></ReactSVG>
)}
{props.type && <div className={styles.type}>{props.type}</div>}
{props.title && <div className={styles.title}>{props.title}</div>}
{props.link && (
<div className={styles.link}>
<span className="link">Read more →</span>
</div>
)}
</div>
</a>
);
}
================================================
FILE: components/GetStartedCard/GetStartedCard.module.scss
================================================
@import "/styles/variables";
.card {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);
transition: box-shadow 0.32s ease-in-out;
border-radius: 32px;
padding: 32px;
height: 100%;
// margin-bottom: 32px;
&:hover {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);
}
&:nth-child(3) {
margin-top: 32px;
}
}
.type {
margin-top: 16px;
font-size: 16px;
line-height: 26px;
text-transform: uppercase;
color: $dark;
}
.title {
font-size: 24px;
line-height: 30px;
font-weight: 500;
color: $dark;
margin-top: 16px;
}
.link {
margin-top: 24px;
margin-bottom: 23px;
}
================================================
FILE: components/GetStartedCard/index.js
================================================
import GetStartedCard from "./GetStartedCard";
export default GetStartedCard;
================================================
FILE: components/GlobalSignUp/GlobalSignUp.jsx
================================================
import * as React from 'react';
import classnames from 'classnames/bind';
import classes from './GlobalSignUp.module.css';
const cn = classnames.bind(classes);
export const GlobalSignUp = ({ className, children }) => {
return (
<div
style={
{
'--section_padding_top': `48px`,
'--section_padding_bottom': `48px`,
}
}
className={cn(
'Section',
`Section--appearance-dark`,
`Section--gap-xl`,
cn('GlobalSignUp', className)
)}
>
<div
className={cn(
'SectionContent',
`SectionContent--align-none`,
`SectionContent--size-m`,
`Section--gap-none`,
classes.GlobalSignUp__content
)}
>
<h2 className={classes.GlobalSignUp__title}>Deliver better data, faster—with Cube.</h2>
<div className={classes.GlobalSignUp__buttons}>{children}</div>
</div>
</div>
);
};
================================================
FILE: components/GlobalSignUp/GlobalSignUp.module.css
================================================
.GlobalSignUp {
background-color: hsl(240, 32%, 10%);
overflow: hidden;
position: relative;
}
.GlobalSignUp::before {
content: "";
position: absolute;
width: 100%;
min-width: 600px;
/* stylelint-disable-next-line */
padding-bottom: 100%;
right: -40%;
top: 50%;
transform: translateY(-50%);
background-image: radial-gradient(#ac0053 30%, #ac005300 65%);
opacity: 0.6;
z-index: 0;
}
@media (max-width: 639px) {
.GlobalSignUp::before {
background-image: radial-gradient(#ac0053 40%, #ac005300 75%);
right: 50%;
transform: translateX(50%) translateY(-5%);
}
}
.GlobalSignUp > * {
z-index: 1;
}
.GlobalSignUp__content {
display: flex;
flex-direction: row;
align-items: center;
gap: 16px;
}
.GlobalSignUp__content a {
color: white;
}
.GlobalSignUp__title {
font-size: 32px;
line-height: 44px;
font-weight: 700;
font-family: CeraPro;
flex-grow: 1;
margin: 0;
}
.GlobalSignUp__buttons {
display: flex;
gap: 16px;
}
@media (min-width: 640px) {
.GlobalSignUp__buttons > * {
flex-grow: 1;
flex-basis: 0;
}
}
@media (max-width: 979px) {
.GlobalSignUp__content {
flex-direction: column;
}
.GlobalSignUp__buttons {
width: 100%;
}
.GlobalSignUp__title {
text-align: center;
}
}
@media (max-width: 639px) {
.GlobalSignUp__buttons {
flex-direction: column;
}
}
.Section {
--section_padding_top: 0px;
--section_padding_bottom: 0px;
display: flex;
flex-flow: column;
overflow: hidden;
padding: var(--section_padding_top) 0 var(--section_padding_bottom);
}
.Section--gap-l {
gap: 32px;
}
.Section--gap-xl {
gap: 48px;
}
.Section--gap-2xl {
gap: 64px;
}
.Section--gap-3xl {
gap: 80px;
}
@media (min-width: 640px) {
.Section--rounded {
border-radius: 32px;
margin: 16px;
}
}
@media (min-width: 1980px) {
.Section--rounded {
max-width: calc(1980px - 32px);
width: 100%;
margin: 16px auto;
}
}
.Section--bordered-bottom {
box-shadow: inset 0 -1px 0 rgba(192, 192, 234, 0.4);
}
.Section--appearance-light {
background-color: white;
}
.Section--hero.Section--appearance-light {
background-color: ¿hsl(240, 12%, 97%, 1);;
}
.Section--appearance-dark {
background-color: hsla(240, 14%, 23%);
color: white;
}
.Section--transparent {
background-color: transparent;
}
/* */
.Section--absoluteTop {
position: relative;
overflow: visible;
}
.Section--absoluteTop > * {
position: absolute !important;
top: 0;
left: 0;
right: 0;
}
.Section--absoluteTop + .Section {
padding-top: calc(var(--section_padding_top) + var(--topbar_height));
}
/* content */
.SectionContent {
width: 100%;
margin: 0 auto;
padding: 0 24px;
}
.SectionContent--size-xs {
max-width: calc(800px + 2 * 24px);
}
.SectionContent--size-s {
max-width: calc(1040px + 2 * 24px);
}
.SectionContent--size-m {
max-width: calc(1120px + 2 * 24px);
}
.SectionContent--size-l {
max-width: calc(1248px + 2 * 24px);
}
.SectionContent--align-center {
display: flex;
align-items: center;
justify-content: center;
}
.SectionContent.Section--gap-xl,
.SectionContent.Section--gap-2xl,
.SectionContent.Section--gap-3xl {
display: flex;
flex-flow: column;
}
================================================
FILE: components/Header/Header.jsx
================================================
import styles from "./Header.module.scss";
import { useRouter } from "next/router";
import Link from "next/link";
export default function Header() {
const router = useRouter();
const isRoot = router.pathname === "/";
return (
<header className={styles.header}>
<div className={styles.header__logo + " container custom-container"}>
<a href="https://cube.dev/" target="_blank" aria-label="Cube">
<span className={styles.header__logo}>
<img src={`/images/logo/cubejs-logo.svg`} alt="Cube" />
</span>
</a>
<ConditionalWrapper
condition={!isRoot}
wrapper={(children) => <Link href="/">{children}</Link>}
>
<span
className={styles.header__text}
active={!isRoot ? "active" : ""}
>
<img
src={`/images/logo/cubejs-awesome-tools.svg`}
alt="Awesome tools"
/>
</span>
</ConditionalWrapper>
</div>
</header>
);
}
const ConditionalWrapper = ({ condition, wrapper, children }) => (
<>{condition ? wrapper(children) : children}</>
);
================================================
FILE: components/Header/Header.module.scss
================================================
.header {
padding: 24px 0;
&__logo {
display: flex;
align-items: center;
min-height: 28px;
}
&__text {
margin-left: 8px;
&[active="active"] {
cursor: pointer;
}
}
}
================================================
FILE: components/Header/index.js
================================================
import Header from "./Header";
export default Header;
================================================
FILE: components/ListPage/ListPage.jsx
================================================
import React, { useState, useEffect } from "react";
import dynamic from "next/dynamic";
import { useRouter } from "next/router";
import { filter, setParamsFromRouter } from "../../data/filter";
import allFrameworks from "../../data/frameworks";
import allTypes from "../../data/types";
import Chip from "../Chip";
import ExploreToolsCard from "../ExploreToolsCard";
import H1 from "../Text/H1";
import AccentedText from "../Text/AccentedText";
import { NextSeo } from "next-seo";
import ToolCard from "../ToolCard";
import ToolsNumberControl from "../ToolsNumberControl";
export default function ListPage({
tools,
framework,
title,
showType = true,
showCompatibleWith = true,
showLicense = true,
}) {
const router = useRouter();
const query = router.query;
const [isFirstLoad, setLoad] = useState(false);
const [exploreTools, setExploreTools] = useState([]);
const [frameworks, setFrameworks] = useState([]);
const [languages, setLanguages] = useState([]);
const [licenses, setLicenses] = useState([]);
const [renders, setRenders] = useState([]);
const isFiltered =
exploreTools.length ||
frameworks.length ||
languages.length ||
licenses.length ||
renders.length;
useEffect(() => {
if (Object.keys(query).length && !isFirstLoad) {
setParamsFromRouter(
query,
setExploreTools,
setFrameworks,
setLanguages,
setLicenses,
setRenders
);
setLoad(true);
}
}, [query]);
useEffect(() => {
router.push(
{
query: {
...(framework && { framework }),
tools: exploreTools,
...(!framework && { frameworks }),
languages,
licenses,
renders,
},
},
undefined,
{ scroll: false }
);
}, [framework, exploreTools, frameworks, languages, licenses, renders]);
const filteredTools = isFiltered
? filter(tools, frameworks, languages, licenses, renders, exploreTools)
: tools;
const setItem = (array, set, item) => {
const index = array.indexOf(item);
if (index === -1) {
set([...array, item]);
// return true;
} else {
array.splice(index, 1);
set([...array]);
// return false;
}
};
return (
<>
<NextSeo
title={`${title} — the awesome list`}
description={`${title} for application developers: charting libraries, data grids, maps, etc.`}
/>
<div className="container custom-container">
<main>
<H1>
{title} <br className="xl-hidden" /> for application developers
</H1>
{showType && (
<div className="row mb-md">
{Object.values(allTypes).map((type, i) => (
<ExploreToolsCard
key={type.slug}
onClick={() =>
setItem(exploreTools, setExploreTools, type.slug)
}
active={exploreTools.includes(type.slug) ? "active" : null}
text={type.name}
image={type.image}
/>
))}
</div>
)}
{showCompatibleWith && (
<div className="flex flex-wrap-row flex-items-center mb-sm">
<AccentedText className="mr-xs">Compatible with</AccentedText>
{Object.values(allFrameworks).map((framework) => (
<Chip
key={framework.slug}
className="mr-xs"
icon={framework.icon}
title={framework.name}
active={frameworks.includes(framework.slug) ? "active" : null}
onClick={() =>
setItem(frameworks, setFrameworks, framework.slug)
}
/>
))}
</div>
)}
<div className="flex flex-wrap-row flex-items-center mb-sm">
<AccentedText className="mr-xs">With support for</AccentedText>
<Chip
icon="typescript.svg"
title="TypeScript"
active={languages.includes("typescript") ? "active" : null}
onClick={() => setItem(languages, setLanguages, "typescript")}
/>
{showLicense && (
<AccentedText className="mr-xs ml-xs">and</AccentedText>
)}
{showLicense && (
<>
<Chip
className="mr-xs"
icon="open-source.svg"
title="open source"
active={licenses.includes("open-source") ? "active" : null}
onClick={() => setItem(licenses, setLicenses, "open-source")}
/>
<Chip
icon="proprietary.svg"
title="proprietary"
active={licenses.includes("proprietary") ? "active" : null}
onClick={() => setItem(licenses, setLicenses, "proprietary")}
/>
<AccentedText className="ml-xs">license</AccentedText>
</>
)}
</div>
<div className="flex flex-wrap-row flex-items-center">
<AccentedText className="mr-xs">Rendering</AccentedText>
<Chip
title="Canvas"
className="mr-xs"
active={renders.includes("canvas") ? "active" : null}
onClick={() => setItem(renders, setRenders, "canvas")}
/>
<Chip
title="SVG"
className="mr-xs"
active={renders.includes("svg") ? "active" : null}
onClick={() => setItem(renders, setRenders, "svg")}
/>
<Chip
title="HTML"
active={renders.includes("html") ? "active" : null}
onClick={() => setItem(renders, setRenders, "html")}
/>
</div>
<div className="number-control-wrap">
<ToolsNumberControl
filteredTools={filteredTools}
isChanged={isFiltered}
clearFilters={() => {
clearFilters([
setExploreTools,
setFrameworks,
setLanguages,
setLicenses,
setRenders,
]);
}}
/>
</div>
<div className="row">
{filteredTools &&
filteredTools.map((tool) => (
<div className="col-xl-6 mb-md" key={tool.id}>
{/* to lazy load on scroll need to set heigth */}
<ToolCard {...tool} />
</div>
))}
</div>
</main>
</div>
</>
);
}
function clearFilters(arrayOfFunctions) {
arrayOfFunctions.forEach((fn) => {
fn([]);
});
}
================================================
FILE: components/ListPage/index.js
================================================
import ListPage from "./ListPage";
export default ListPage;
================================================
FILE: components/Slider/Slider.jsx
================================================
// App.js
import React, { useState, useEffect } from "react";
import styles from "./Slider.module.scss";
// import "./App.css";
import Slider from "react-slick";
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
function getSettingsThumbs(slidesToShow) {
return {
slidesToShow: Math.min(4, slidesToShow),
slidesToScroll: 1,
asNavFor: ".slider-for",
dots: false,
centerMode: false,
swipeToSlide: true,
focusOnSelect: true,
};
}
function App(props) {
const [nav1, setNav1] = useState(null);
const [nav2, setNav2] = useState(null);
const [slider1, setSlider1] = useState(null);
const [slider2, setSlider2] = useState(null);
useEffect(() => {
setNav1(slider1);
setNav2(slider2);
});
const settingsMain = {
slidesToShow: 1,
slidesToScroll: 1,
arrows: false,
fade: true,
asNavFor: ".slider-nav",
};
return (
<div className={styles.slider}>
<div className={styles.sliderWrapper}>
<Slider
{...settingsMain}
asNavFor={nav2}
ref={(slider) => setSlider1(slider)}
>
{props.slidesData &&
props.slidesData.map((slide, i) => (
<div className={styles.slickSlide} key={slide}>
<img
className={styles.slickSlideImage}
src={slide}
alt={`Preview ${i}`}
/>
</div>
))}
</Slider>
<div className={styles.thumbnailSliderWrap}>
<Slider
{...getSettingsThumbs(props.slidesData.length)}
asNavFor={nav1}
ref={(slider) => setSlider2(slider)}
>
{props.slidesData &&
props.slidesData.map((slide, i) => (
<div className={styles.slickSlide} key={slide}>
<img
className={styles.slickSlideImage}
src={slide}
alt={`Thumbnail ${i}`}
/>
</div>
))}
</Slider>
</div>
</div>
</div>
);
}
export default App;
================================================
FILE: components/Slider/Slider.module.scss
================================================
.thumbnailSliderWrap {
margin-top: 27px;
// height: 85px;
@media (max-width: 767.98px) {
margin-top: 16px;
}
}
.slickSlide {
text-align: center;
}
.sliderWrapper {
.slickSlide img {
border: 2px solid #e7e7e7;
box-sizing: border-box;
border-radius: 16px;
width: 100%;
@media (max-width: 767.98px) {
width: 100%;
}
}
}
.thumbnailSliderWrap {
max-height: 111px;
overflow: hidden;
@media (max-width: 1200px) {
height: 70px;
}
@media (max-width: 767.98px) {
height: 50px;
}
.slickSlide img {
cursor: pointer;
// width: 90%;
max-width: 213px;
border: 1px solid #d5d5e2;
border-radius: 8px;
outline: none;
max-height: 111px;
@media (max-width: 1400px) {
width: 90%;
}
@media (max-width: 1200px) {
max-height: 70px;
}
@media (max-width: 767.98px) {
max-height: 50px;
}
}
}
================================================
FILE: components/Slider/index.js
================================================
import Slider from "./Slider";
export default Slider;
================================================
FILE: components/Text/AccentedText.jsx
================================================
import styles from "./AccentedText.module.scss";
export default function AccentedText(props) {
return (
<span
className={
props.className
? styles.accented + " " + props.className
: styles.accented
}
>
{props.children}
</span>
);
}
================================================
FILE: components/Text/AccentedText.module.scss
================================================
.accented {
font-size: 24px;
line-height: 30px;
}
================================================
FILE: components/Text/H1.jsx
================================================
import styles from "./H1.module.scss";
export default function H1(props) {
return <h1 className={styles.title}>{props.children}</h1>;
}
================================================
FILE: components/Text/H1.module.scss
================================================
@import "/styles/variables";
.title {
font-style: normal;
font-weight: 700;
font-size: 64px;
line-height: 72px;
margin: 24px 0;
@media (max-width: 767.98px) {
font-size: 32px;
line-height: 44px;
}
}
================================================
FILE: components/Text/H2.jsx
================================================
import styles from "./H2.module.scss";
export default function H2(props) {
return (
<h2
{...props}
className={
props.className ? styles.h2 + " " + props.className : styles.h2
}
>
{props.children}
</h2>
);
}
================================================
FILE: components/Text/H2.module.scss
================================================
@import "/styles/variables";
.h2 {
font-size: 40px;
line-height: 50px;
color: $dark;
margin: 0;
@media (max-width: 767.98px) {
font-size: 26px;
line-height: 36px;
}
}
================================================
FILE: components/ToolCard/ToolCard.jsx
================================================
import styles from "./ToolCard.module.scss";
import dayjs from "dayjs";
import dayjsUtc from "dayjs/plugin/utc";
import Link from "next/link";
import abbreviateNumber from "../../utils/number";
dayjs.extend(dayjsUtc);
export default function ToolCard(props) {
let shadow = getShadowByLabel(props?.feature_label);
let language = null;
if (props.languages && props.languages.length > 0) {
language = props?.languages?.includes("TypeScript")
? "TypeScript"
: "JavaScript";
}
return (
<Link href={"/tools/" + props.id} className="full-height" legacyBehavior>
<a className="full-height">
<div className={styles.toolCard} shadow={shadow}>
<div className="flex flex-items-center">
<img
className={styles.toolCard__logo}
src={`/images/logo/${props.logo}`}
alt={`${props.title} logo`}
/>
<div className="flex flex-column">
<h2 className={styles.toolCard__title}>
{props.title || ""}
{props.developer && (
<span className={styles.toolCard__developer}>
by {props.developer}
</span>
)}
</h2>
</div>
</div>
<p
className={styles.toolCard__description}
dangerouslySetInnerHTML={{ __html: props.description }}
></p>
<div className="flex flex-wrap-row">
{props?.github_data && (
<div className="flex flex-column">
<span className={styles.features}>GitHub stars</span>
<div className={styles.github}>
<img
className={styles.icon}
src={`/images/logo/github.svg`}
alt={`${props.title} logo`}
/>
<span className={styles.features__text}>
{abbreviateNumber(props?.github_data?.stars) || "-"}
</span>
</div>
</div>
)}
{props.frameworks && props.frameworks.length > 0 && (
<div className="flex flex-column">
<span className={styles.features}>Framework</span>
<div className={styles.framework}>
{props.frameworks &&
props.frameworks.map((framework, i) => {
return (
<div
className={styles.framework__wrapper}
key={`${framework}_${i}`}
>
{framework !== "Universal" ? (
<img
className={styles.icon}
src={`/images/logo/${framework.toLowerCase()}.svg`}
alt={`${props.title} logo`}
/>
) : null}
{props.frameworks.length === 1 && (
<span className={styles.features__text}>
{framework === "vanilla-js"
? "vanilla JS"
: framework}
</span>
)}
</div>
);
})}
</div>
</div>
)}
{language && (
<div className="flex flex-column">
<span className={styles.features}>Language</span>
<div className={styles.language}>
<div className={styles.language__wrapper}>
{language ? (
<img
className={styles.icon}
src={`/images/logo/${language.toLowerCase()}.svg`}
alt={`${props.title} logo`}
/>
) : null}
<span className={styles.features__text}>{language}</span>
</div>
</div>
</div>
)}
{props?.github_data?.last_release?.date && (
<div className="flex flex-column">
<span className={styles.features}>Last release</span>
<div>
<span className={styles.features__text}>
{dayjs(props?.github_data?.last_release?.date)
.utc()
.format("MMM DD, YYYY") || "-"}
</span>
</div>
</div>
)}
</div>
{props.feature_label && (
<div className={styles.toolCard__achievement}>
<img
className={styles.toolCard__achievement__icon}
src={`/images/${props.feature_label}.svg`}
alt={`${props.title} logo`}
/>
</div>
)}
</div>
</a>
</Link>
);
}
function getShadowByLabel(label) {
if (!label) {
return "gray";
}
return label;
}
================================================
FILE: components/ToolCard/ToolCard.module.scss
================================================
@import "/styles/variables";
.toolCard {
cursor: pointer;
padding: 32px;
color: $dark;
background: #ffffff;
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);
border-radius: 40px;
position: relative;
max-width: 600px;
height: 100%;
transition: box-shadow 0.3s ease-in-out;
margin: 0 auto;
@media (max-width: 767.98px) {
padding: 24px;
}
&:hover {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);
}
&__logo {
width: 60px;
height: 60px;
border: 1px solid rgba(213, 213, 226, 0.5);
border-radius: 16px;
}
&__title {
font-weight: 700;
font-size: 26px;
line-height: 36px;
margin: 0 0 0 16px;
}
&__developer {
color: $dark-03;
}
&__description {
font-size: 18px;
line-height: 24px;
font-style: normal;
font-weight: normal;
max-width: 424px;
min-height: 48px;
margin-top: 24px;
margin-bottom: 48px;
@media (min-width: 1200px) and (max-width: 1400px) {
max-width: 400px;
}
@media (min-width: 767.98px) and (max-width: 1200px) {
max-width: 290px;
}
@media (max-width: 767.98px) {
margin-bottom: 16px;
margin-top: 16px;
}
}
&__achievement {
position: absolute;
right: 32px;
top: 32px;
@media (max-width: 767.98px) {
right: 0;
top: 0;
transform: scale3d(0.5, 0.5, 0.5);
}
&__icon {
width: 104px;
height: 104px;
}
}
}
.features {
color: $dark-03;
font-size: 12px;
line-height: 15px;
padding-bottom: 5px;
min-width: 94px;
margin-right: 40px;
&__text {
text-transform: capitalize;
font-size: 16px;
font-weight: 500;
}
@media (max-width: 1400px) {
margin-right: 20px;
}
@media (max-width: 767.98px) {
margin-right: 40px;
}
}
.github {
display: flex;
align-items: center;
.icon {
width: 16px;
height: 16px;
margin-right: 5px;
}
}
.language {
display: flex;
align-items: center;
&__wrapper {
display: flex;
align-items: center;
}
.icon {
width: 16px;
height: 16px;
display: flex;
align-items: center;
margin-right: 5px;
}
}
.framework {
display: flex;
align-items: center;
&__wrapper {
display: flex;
align-items: center;
@media (max-width: 767.98px) {
margin-bottom: 8px;
}
}
.icon {
width: 16px;
height: 16px;
display: flex;
align-items: center;
margin-right: 5px;
}
}
.toolCard[shadow="well-documented"] {
box-shadow: 16px 24px 80px rgba(255, 133, 95, 0.3);
&:hover {
box-shadow: 16px 24px 80px rgba(255, 133, 95, 0.5);
}
}
.toolCard[shadow="easy-to-start-with"] {
box-shadow: -16px 24px 80px rgba(66, 204, 173, 0.3);
&:hover {
box-shadow: -16px 24px 80px rgba(66, 204, 173, 0.5);
}
}
.toolCard[shadow="full-fledged"] {
box-shadow: 0px 24px 80px rgba(255, 124, 226, 0.4);
&:hover {
box-shadow: 0px 24px 80px rgba(255, 124, 226, 0.5);
}
}
.toolCard[shadow="easy-to-customize"] {
box-shadow: 0px 24px 80px rgba(115, 159, 243, 0.4);
&:hover {
box-shadow: 0px 24px 80px rgba(115, 159, 243, 0.5);
}
}
.toolCard[shadow="very-popular"] {
box-shadow: 0px 24px 80px rgba(255, 194, 123, 0.4);
&:hover {
box-shadow: 0px 24px 80px rgba(255, 194, 123, 0.5);
}
}
.toolCard[shadow="gray"] {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);
&:hover {
box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);
}
}
================================================
FILE: components/ToolCard/index.js
================================================
import ToolCard from "./ToolCard";
export default ToolCard;
================================================
FILE: components/ToolPage/Description.jsx
================================================
import styles from "./Description.module.scss";
export default function Description(props) {
return (
<div className={styles.description}>
<div className={styles.description__text}>{props.description}</div>
{props.based && (
<div className={styles.based}>
<span>Based on</span>
{props.based.map((tag) => (
<span key={tag} className={styles.based__tag}>
{tag}
</span>
))}
</div>
)}
</div>
);
}
================================================
FILE: components/ToolPage/Description.module.scss
================================================
@import "/styles/variables";
.description {
margin-top: 24px;
&__text {
font-size: 22px;
line-height: 28px;
color: $dark;
font-style: normal;
font-weight: normal;
}
}
.based {
display: flex;
align-items: center;
color: $dark-03;
font-size: 16px;
line-height: 20px;
margin-top: 24px;
&__tag {
margin-left: 8px;
color: #8381ee;
}
}
================================================
FILE: components/ToolPage/DescriptionCards.jsx
================================================
import styles from "./DescriptionCards.module.scss";
import Card from "../Card/Card";
const getLicense = (props) => {
let isOpen = false;
let isPrice = false;
let smallText = "";
let icon = "/images/logo/proprietary.svg";
let link = props?.links?.pricing;
props?.licenses?.forEach((obj) => {
if (obj.type === "open-source") {
isOpen = true;
smallText = obj.title;
link = obj.link;
icon = "/images/logo/open-source.svg";
} else {
isPrice = true;
link = obj.link;
}
});
if (isOpen && isPrice) {
return {
icons: ["/images/logo/proprietary.svg", "/images/logo/open-source.svg"],
text: "Open-source and proprietary licenses",
link: props?.links?.pricing || link,
smallText: props?.links?.pricing ? "Priсing page →" : "License →",
};
}
if (isOpen) {
return {
text: "Open-source license",
smallText: `${smallText} →`,
link,
icon,
};
}
if (isPrice) {
return {
text: "Proprietary license",
link: props?.links?.pricing || link,
smallText: props?.links?.pricing ? "Priсing page →" : "License →",
icon,
};
}
};
const getFrameworks = (props) => {
if (props?.frameworks?.length === 1) {
let fr = props.frameworks[0];
return {
icon: `/images/logo/${fr.toLowerCase()}.svg`,
text: `${fr === 'vanilla-js' ? 'Vanilla JS' : capitalizeFirstLetter(fr)} only`,
link: `https://github.com/${props.slugs.github}`,
smallText: `GitHub repository →`,
};
}
let frameworksOnly = props.frameworks.filter((fr) => fr !== "vanilla-js");
return {
text: frameworksOnly.map((s, index) => {
return (
<span key={s}>
{capitalizeFirstLetter(s)}
{index === frameworksOnly.length - 1 ? " " : ", "}
</span>
);
}),
icons: props.frameworks.map((fr) => `/images/logo/${fr}.svg`),
smallText: `GitHub repository →`,
link: `https://github.com/${props.slugs.github}`,
};
};
const getLanguage = (languages, slugs) => {
let hasTS = languages.includes("TypeScript");
let hasDT = slugs.npm_types !== undefined
let icon = "/images/logo/javascript.svg";
let text = "JavaScript only";
let smallText = "No TypeScript support";
let color = "orange";
let link = undefined;
if (hasTS) {
icon = "/images/logo/typescript.svg";
text = "TypeScript support";
smallText = hasDT ? "DefinitelyTyped definitions →" : "*.d.ts files →";
color = "gray";
link = hasDT ? `https://www.npmjs.com/package/${slugs.npm_types}` : `https://github.com/search?q=repo%3A${encodeURIComponent(slugs.github)}+filename%3A.d.ts&type=Code`;
}
return {
icon,
text,
smallText,
color,
link,
};
};
export default function DescriptionCards(props) {
return (
<div className={styles.descriptionCards + " row"}>
{props.licenses && (
<div className={styles.cardWrap + " col-xl-4 col-lg-4 col-md-12"}>
<Card height="full" {...getLicense(props)} />
</div>
)}
{props.frameworks && props.slugs.github && (
<div className={styles.cardWrap + " col-xl-4 col-lg-4 col-md-12"}>
<Card height="full" color="gray" {...getFrameworks(props)} />
</div>
)}
{props.languages && (
<div className={styles.cardWrap + " col-xl-4 col-lg-4 col-md-12"}>
<Card height="full" {...getLanguage(props.languages, props.slugs)} />
</div>
)}
</div>
);
}
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
================================================
FILE: components/ToolPage/DescriptionCards.module.scss
================================================
.descriptionCards {
margin-top: 40px;
display: flex;
margin-bottom: 104px;
@media (max-width: 767.98px) {
margin-bottom: 48px;
}
}
.cardWrap {
@media (max-width: 991.98px) {
margin-bottom: 16px;
}
}
================================================
FILE: components/ToolPage/Header.jsx
================================================
import styles from "./Header.module.scss";
import Button from "../Button";
export default function Header(props) {
return (
<div className={styles.header}>
<div className={styles.title}>
<img
className={styles.title__img}
src={`/images/logo/${props.logo}`}
alt={`${props.title} logo`}
/>
<h1 className={styles.title__text}>
{props.title}
{props.developer && (
<span className={styles.title__developer}>
by {props.developer}
</span>
)}
{props.framework && (
<span className={styles.title__framework}>
for {props.framework} developers
</span>
)}
</h1>
{props.achievement && (
<div>
<img
className={styles.achievement}
src={`/images/${props.achievement}.svg`}
alt="tool label"
/>
</div>
)}
</div>
<div className={styles.buttons}>
{props.github && (
<Button target="_blank" href={`https://github.com/${props.github}`}>
GitHub
</Button>
)}
{props.website && (
<Button target="_blank" href={props.website}>
Website
</Button>
)}
</div>
</div>
);
}
================================================
FILE: components/ToolPage/Header.module.scss
================================================
@import "/styles/variables";
.header {
display: flex;
align-items: center;
justify-content: space-between;
@media (max-width: 767.98px) {
flex-direction: column;
}
}
.title {
display: flex;
position: relative;
@media (max-width: 767.98px) {
flex-wrap: wrap;
margin-bottom: 16px;
width: 100%;
}
&__img {
border: 1px solid rgba(213, 213, 226, 0.5);
border-radius: 24px;
width: 77px;
height: 77px;
}
&__text {
display: flex;
align-items: center;
margin: 0 0 0 16px;
font-size: 40px;
line-height: 40px;
color: $dark;
}
&__developer {
color: $dark-03;
}
&__framework {
color: $dark-03;
}
}
.buttons {
display: flex;
a:first-child {
margin-right: 8px;
}
}
.achievement {
margin-top: -56px;
@media (max-width: 767.98px) {
position: absolute;
top: -56px;
right: 0;
margin: 0;
// margin: 0;
transform: scale3d(0.5, 0.5, 0.5);
}
// height: 104px;
// width: 104px;
}
================================================
FILE: components/ToolPage/HowToGetHelp.jsx
================================================
import styles from "./HowToGetHelp.module.scss";
import GetHelpCard from "../GetHelpCard";
import H2 from "../Text/H2";
import abbreviateNumber from "../../utils/number";
export default function HowToGetHelp(props) {
const cards = [
{
href: props.links.slack,
title: `${props.name} Slack →`,
icon: "/images/logo/slack-big.svg",
},
{
href: props.links.docs,
title: `${props.name} docs →`,
icon: `/images/logo/${props.logo}`,
},
{
href: props.stackoverflow,
title: "Stack Overflow →",
icon: "/images/logo/stackoverflow-64.svg",
footer: `${abbreviateNumber(
props?.stackoverflow_data?.questions_count
)} questions`,
},
{
href: "https://slack.cube.dev/",
title: "Cube Slack →",
icon: "/images/logo/slack-big.svg",
footer: `${abbreviateNumber(props.slackMembers)} followers`,
},
];
return (
<div className={styles.HowToGetHelp}>
<div className="row mb-md">
<div className={styles.textWrap + " col-lg-3"}>
<H2>
How to
<br />
Get Help
</H2>
</div>
{cards
.filter((card) => card.href)
.map((card, index) => {
let className = " col-lg-4";
// if (index === 0) {
// className = "col-lg-4";
// }
if (index === 1) {
className = " col-lg-5";
}
if (index === 2) {
className = " col-lg-5 offset-lg-3";
}
// let className = " col-lg-5";
// if (index % 2 === 0 && index !== 0) {
// className = " col-lg-5 offset-lg-3";
// }
// if (index % 2 !== 0) {
// className = " col-lg-4";
// }
return card.href ? (
<div key={card.title} className={styles.cardWrap + className}>
<GetHelpCard {...card} />
</div>
) : null;
})}
</div>
</div>
);
}
================================================
FILE: components/ToolPage/HowToGetHelp.module.scss
================================================
.HowToGetHelp {
margin-bottom: 104px;
@media (max-width: 767.98px) {
margin-bottom: 48px;
}
}
.cardWrap {
margin-bottom: 26px;
@media (max-width: 991.98px) {
margin-bottom: 24px;
}
}
.textWrap {
@media (max-width: 991.98px) {
margin-bottom: 24px;
}
}
================================================
FILE: components/ToolPage/HowToGetStarted.jsx
================================================
import styles from "./HowToGetStarted.module.scss";
import GetStartedCard from "../GetStartedCard";
import H2 from "../Text/H2";
export default function HowToGetStarted(props) {
return (
<div className={styles.HowToGetStarted + " row"}>
<div className="col-sm-3">
<H2>
How to
<br />Get Started
</H2>
</div>
{props.content.map((obj, index) => {
const icon =
obj.type === "official"
? "/images/logo/official.svg"
: "/images/logo/cubejs-big.svg";
const className =
styles.cardWrap + " " +
(index === 0 ? "col-sm-5" : "col-sm-4") +
(index !== 0 && index % 2 === 0 ? " offset-lg-3" : "");
return (
<div key={index} className={className}>
<GetStartedCard
icon={icon}
type={obj.type === "official" ? "Official tutorial" : "Community guide"}
title={obj.title}
link={obj.link}
/>
</div>
);
})}
{/* <div className="col-sm-4">
<GetStartedCard />
</div> */}
</div>
);
}
================================================
FILE: components/ToolPage/HowToGetStarted.module.scss
================================================
.HowToGetStarted {
margin-bottom: 104px;
}
.cardWrap {
margin-bottom: 26px;
@media (max-width: 991.98px) {
margin-bottom: 24px;
}
}
================================================
FILE: components/ToolPage/Integrations.jsx
================================================
import styles from "./Integrations.module.scss";
import Card from "../Card/Card";
import H2 from "../Text/H2";
import frameworks from '../../data/frameworks';
export default function Integrations(props) {
const integrations = props.integrations || [ props.integration ]
return (
<div className={styles.integration + " row"}>
<div className="col-lg-3">
<H2>
{props.integration ? frameworks[props.integration.framework].name : "Framework"} Support
</H2>
</div>
<div className={styles.cards + " col-lg-9 row"}>
{integrations.map(integration => {
const framework = frameworks[integration.framework]
const link = integration.links?.website
? integration.links.website
: `https://github.com/${integration.slugs.github}`;
return (
<div className={styles.cardWrap + (props.integration ? " col-xl-12 col-lg-12 col-md-12" : " col-xl-6 col-lg-6 col-md-12")}>
<Card
key={integration.framework}
link={link}
icon={`/images/logo/${framework.icon}`}
text={integration.slugs.npm}
smallText={`${framework.name} components`}
/>
</div>
);
})}
</div>
</div>
);
}
================================================
FILE: components/ToolPage/Integrations.module.scss
================================================
.integration {
margin-bottom: 104px;
@media (max-width: 767.98px) {
margin-bottom: 48px;
}
}
.cards {
display: flex;
}
.cardWrap {
margin-bottom: 24px;
}
================================================
FILE: components/ToolPage/Popularity.jsx
================================================
import styles from "./Popularity.module.scss";
import Card from "../Card/Card";
import H2 from "../Text/H2";
import dayjs from "dayjs";
import abbreviateNumber from "../../utils/number";
export default function Popularity(props) {
return (
<div className={styles.popularity + " row"}>
<div className="col-lg-3">
<H2>
Popularity
<br />& Relevance
</H2>
</div>
<div className={styles.bigCardWrap + " col-lg-3"}>
<Card
isBig={true}
link={`https://github.com/${props?.slugs?.github}/stargazers`}
color={
props?.positions?.stars / props?.positions?.total > 0.67
? "orange"
: null
}
icon="/images/logo/github-big.svg"
text={abbreviateNumber(props?.github?.stars) || 0}
description="GitHub stars"
footerText={`${props?.positions?.stars} of ${props?.positions?.total} place`}
/>
</div>
<div className={styles.bigCardWrap + " col-lg-3"}>
<Card
isBig={true}
color={props?.percentages?.stale_issues > 50 ? "orange" : null}
link={`https://github.com/${props?.slugs?.github}/issues`}
icon="/images/edit.svg"
text={props?.github?.issues}
description="open issues"
footerText={`${props?.percentages?.stale_issues?.toFixed(
0
)} % older than 1 year`}
/>
</div>
<div className={styles.smallCardWrap + " col-lg-3"}>
<Card
link={`https://github.com/${props?.slugs?.github}/graphs/contributors`}
className="mb-md"
color="gray"
text={abbreviateNumber(props?.github?.contributors)}
description="contributors"
/>
{props?.github?.last_release?.date && (
<Card
link={props?.github?.last_release?.link}
color="gray"
text={
dayjs(props?.github?.last_release?.date).format(
"MMM DD, YYYY"
) || "-"
}
description="last release date"
/>
)}
</div>
</div>
);
}
================================================
FILE: components/ToolPage/Popularity.module.scss
================================================
.popularity {
margin-bottom: 104px;
@media (max-width: 767.98px) {
margin-bottom: 48px;
}
}
.bigCardWrap {
@media (max-width: 991.98px) {
margin-top: 24px;
}
}
.smallCardWrap {
@media (max-width: 991.98px) {
margin-top: 24px;
}
}
================================================
FILE: components/ToolPage/ToolPage.jsx
================================================
import React from "react";
import dynamic from "next/dynamic";
import { NextSeo } from 'next-seo';
import Header from "./Header";
import Description from "./Description";
import DescriptionCards from "./DescriptionCards";
import useSlackMembers from "../../data/useSlackMembers";
import types from '../../data/types';
import Integrations from './Integrations';
const Gallery = dynamic(() => import("../Gallery"));
const Popularity = dynamic(() => import("./Popularity"));
const HowToGetStarted = dynamic(() => import("./HowToGetStarted"));
const HowToGetHelp = dynamic(() => import("./HowToGetHelp"));
export default function ToolPage(props) {
const type = types[props.types[0]];
const slackMembers = useSlackMembers();
return (
<>
<NextSeo
title={`${props.title} — ${type.descriptor}`}
description={`${props.title} examples, tutorials, compatibility, and popularity`}
/>
<div className="container custom-container mt-lg">
<main>
<Header
logo={props.logo}
title={props.title}
developer={props.developer}
website={props?.links?.website}
github={props?.slugs?.github}
achievement={props?.feature_label}
/>
<Description based={props.based_on} description={props.description} />
<DescriptionCards
licenses={props.licenses}
frameworks={props.frameworks}
languages={props.languages}
links={props.links}
slugs={props.slugs}
/>
{props.gallery && props.gallery.length !== 0 && (
<Gallery gallery={props.gallery} link={props?.links?.examples} />
)}
{props.github_data && (
<Popularity
slugs={props.slugs}
github={props.github_data}
positions={props.positions}
percentages={props.percentages}
/>
)}
{props.integrations?.length > 0 && (
<Integrations integrations={props.integrations} />
)}
{props.content && props.content.length > 0 && (
<HowToGetStarted content={props.content} />
)}
<HowToGetHelp
slackMembers={slackMembers}
logo={props.logo}
name={props.title}
links={props.links}
positions={props.positions}
stackoverflow={
props?.tags?.stackoverflow
? `https://stackoverflow.com/questions/tagged/${encodeURIComponent(
props?.tags?.stackoverflow.join(" or "),
)}`
: null
}
stackoverflow_data={props.stackoverflow_data}
/>
</main>
</div>
</>
);
}
================================================
FILE: components/ToolPage/ToolPageForFramework.jsx
================================================
import React from "react";
import dynamic from "next/dynamic";
import { NextSeo } from 'next-seo';
import Header from "./Header";
import Description from "./Description";
import DescriptionCards from "./DescriptionCards";
import useSlackMembers from "../../data/useSlackMembers";
import frameworks from '../../data/frameworks';
import types from '../../data/types';
import Integrations from './Integrations';
const Gallery = dynamic(() => import("../Gallery"));
const Popularity = dynamic(() => import("./Popularity"));
const HowToGetStarted = dynamic(() => import("./HowToGetStarted"));
const HowToGetHelp = dynamic(() => import("./HowToGetHelp"));
export default function ToolPageForFramework(props) {
const type = types[props.types[0]];
const framework = frameworks[props.framework];
const integration = props.integrations?.find(i => i.framework === props.framework);
const slackMembers = useSlackMembers();
return (
<>
<NextSeo
title={`${props.title} — ${type.descriptor} for ${framework.name} developers`}
description={`${props.title} support in ${framework.name}${integration && ` with ${integration.slugs.npm}`}, examples, tutorials, compatibility, and popularity`}
/>
<div className="container custom-container mt-lg">
<main>
<Header
logo={props.logo}
title={props.title}
framework={framework.name}
developer={props.developer}
website={props?.links?.website}
github={props?.slugs?.github}
achievement={props?.feature_label}
/>
<Description description={props.description} />
<DescriptionCards
licenses={props.licenses}
frameworks={props.frameworks}
languages={props.languages}
links={props.links}
slugs={props.slugs}
/>
{integration && (
<Integrations integration={integration} />
)}
{props.gallery && props.gallery.length !== 0 && (
<Gallery gallery={props.gallery} link={props?.links?.examples} />
)}
{props.github_data && (
<Popularity
slugs={props.slugs}
github={props.github_data}
positions={props.positions}
percentages={props.percentages}
/>
)}
{props.content && props.content.length > 0 && (
<HowToGetStarted content={props.content} />
)}
<HowToGetHelp
slackMembers={slackMembers}
logo={props.logo}
name={props.title}
links={props.links}
positions={props.positions}
stackoverflow={
props?.tags?.stackoverflow
? `https://stackoverflow.com/questions/tagged/${encodeURIComponent(
props?.tags?.stackoverflow.join(" or "),
)}`
: null
}
stackoverflow_data={props.stackoverflow_data}
/>
</main>
</div>
</>
);
}
================================================
FILE: components/ToolsNumberControl/ToolsNumberControl.jsx
================================================
import styles from "./ToolsNumberControl.module.scss";
import { ReactSVG } from "react-svg";
export default function ToolsNumberControl(props) {
let text = "awesome tools — and counting!";
if (props.isChanged) {
text = props.filteredTools.length === 1
? "awesome tool matching your criteria"
: "awesome tools matching your criteria";
}
return (
<div className={styles.toolsControl}>
<div className={styles.toolsControl__text}>
{props.filteredTools.length} {text}
</div>
{props.isChanged !== 0 && (
<button
className={styles.toolsControl__button}
role="button"
onClick={props.clearFilters}
>
<span>Clear filter</span>
<ReactSVG
wrapper="span"
className={styles.clear}
src="/images/clear.svg"
/>
</button>
)}
</div>
);
}
================================================
FILE: components/ToolsNumberControl/ToolsNumberControl.module.scss
================================================
@import "/styles/variables";
.toolsControl {
min-height: 34px;
display: flex;
align-items: center;
@media (max-width: 767.98px) {
align-items: flex-start;
flex-direction: column;
}
&__button {
cursor: pointer;
display: flex;
align-items: center;
font-family: CeraPro;
margin-left: 16px;
padding: 0px 12px;
background: rgba(255, 193, 211, 0.24);
border-radius: 20px;
border: none;
font-size: 20px;
line-height: 30px;
color: $pink-hover;
@media (max-width: 767.98px) {
margin-top: 4px;
margin-left: 0;
padding: 0px 8px;
font-size: 16px;
}
}
&__text {
font-size: 20px;
line-height: 30px;
color: $dark-03;
white-space: nowrap;
@media (max-width: 767.98px) {
font-size: 16px;
}
}
}
.clear {
margin-left: 8px;
}
================================================
FILE: components/ToolsNumberControl/index.js
================================================
import ToolsNumberControl from "./ToolsNumberControl";
export default ToolsNumberControl;
================================================
FILE: copy/tools/.example
================================================
title: AG Grid
description: Self-proclaimed best JavaScript grid in the world
logo: ag-grid.svg
developer: Google
based_on:
- d3
licenses:
- type: open-source
title: Apache 2.0
link: https://github.com/apache/echarts/blob/master/LICENSE
types:
- 3d
- app
- charts
- grid
- low-level
- maps
renders:
- svg
- html
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/reaflow-1.png
- /images/slider/reaflow-2.png
- /images/slider/reaflow-3.png
- /images/slider/reaflow-4.png
- /images/slider/reaflow-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
- svelte
slugs:
github: ag-grid/ag-grid
npm: ag-grid-community
npm_types: "@types/mapbox-gl"
tags:
stackoverflow:
- ag-grid
- aggrid
twitter:
- aggrid
- ag_grid
links:
website: https://www.ag-grid.com
examples: https://www.ag-grid.com/example.php
docs: https://www.ag-grid.com/javascript-grid/
pricing: null
slack: https://slack.example.com
content:
- type: official
title: "JavaScript Grid: Get Started with AG Grid"
link: https://www.ag-grid.com/javascript-grid/getting-started/
- type: cube
title: React Pivot Table with AG Grid and Cube.js
link: https://react-pivot-table.cube.dev
github_data:
stars: 7200
contributors: 84
issues: 17
stale_issues: 0
last_release:
date: "2021-04-30T00:00:00Z"
link: https://github.com/ag-grid/ag-grid/releases/tag/v25.2.0
stackoverflow_data:
questions_count: 37620
================================================
FILE: copy/tools/.extended.example
================================================
# Everything from .example and also the following fields
positions:
total: 45
stars: 3
percentages:
stale_issues: 32
================================================
FILE: copy/tools/ag-grid.yml
================================================
title: AG Grid
description: Self-proclaimed best JavaScript grid in the world
logo: ag-grid.svg
based_on: null
licenses:
- type: proprietary
- type: open-source
title: MIT
types:
- grid
renders:
- html
features:
easy-to-customize: 1
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 0
gallery:
- /images/slider/ag-grid-1.png
- /images/slider/ag-grid-2.png
- /images/slider/ag-grid-3.png
- /images/slider/ag-grid-5.png
- /images/slider/ag-grid-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: ag-grid/ag-grid
npm: ag-grid-community
tags:
stackoverflow:
- ag-grid
twitter:
- aggrid
- ag_grid
links:
website: 'https://www.ag-grid.com'
examples: 'https://www.ag-grid.com/example.php'
docs: 'https://www.ag-grid.com/javascript-grid/'
pricing: 'https://www.ag-grid.com/license-pricing.php'
slack: null
content:
- type: official
title: 'JavaScript Grid: Get Started with AG Grid'
link: 'https://www.ag-grid.com/javascript-grid/getting-started/'
- type: cube
title: React Pivot Table with AG Grid and Cube.js
link: 'https://react-pivot-table.cube.dev'
github_data:
stars: 13513
contributors: 193
issues: 39
stale_issues: 1
last_release:
date: '2025-02-20T08:36:33Z'
link: 'https://github.com/ag-grid/ag-grid/releases/tag/v33.1.1'
stackoverflow_data:
questions_count: 5142
================================================
FILE: copy/tools/amcharts.yml
================================================
title: amCharts
description: JavaScript charts & maps for all data visualization needs
logo: amcharts.svg
based_on: null
licenses:
- type: proprietary
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 0
gallery:
- /images/slider/amcharts-1.png
- /images/slider/amcharts-2.png
- /images/slider/amcharts-3.png
- /images/slider/amcharts-4.png
- /images/slider/amcharts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: amcharts/amcharts4
npm: '@amcharts/amcharts4'
tags:
stackoverflow:
- amcharts
- amcharts4
twitter:
- amcharts
- amcharts4
links:
website: 'https://www.amcharts.com'
examples: 'https://www.amcharts.com/demos/'
docs: 'https://www.amcharts.com/docs/v4/'
pricing: 'https://www.amcharts.com/online-store/'
slack: null
content:
- type: official
title: Starting from Basics of amCharts 4
link: 'https://www.amcharts.com/docs/v4/getting-started/basics/'
github_data:
stars: 1157
contributors: 6
issues: 31
stale_issues: 30
last_release:
date: '2024-06-18T09:36:19Z'
link: 'https://github.com/amcharts/amcharts4/releases/tag/4.10.39'
stackoverflow_data:
questions_count: 3221
================================================
FILE: copy/tools/ant-design-charts.yml
================================================
title: Ant Design Charts
description: 'React charting library, based on G2Plot, G6, X6, L7'
logo: antv.svg
developer: AntV
based_on:
- g2plot
- g6
licenses:
- type: open-source
title: MIT
link: 'https://github.com/ant-design/ant-design-charts/blob/master/LICENSE'
types:
- charts
- maps
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 1
gallery:
- /images/slider/ant-design-charts-1.png
- /images/slider/ant-design-charts-2.png
- /images/slider/ant-design-charts-3.png
- /images/slider/ant-design-charts-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: ant-design/ant-design-charts
npm: '@an-design/charts'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://charts.ant.design/en'
examples: 'https://charts.ant.design/en/examples/gallery'
docs: 'https://charts.ant.design/en/docs/manual/introduction'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://charts.ant.design/en/docs/manual/getting-started'
github_data:
stars: 2001
contributors: 72
issues: 336
stale_issues: 156
last_release:
date: '2024-12-13T09:23:24Z'
link: 'https://github.com/ant-design/ant-design-charts/releases/tag/2.2.5'
stackoverflow_data: null
================================================
FILE: copy/tools/anychart.yml
================================================
title: AnyChart
description: Interactive JavaScript charts
logo: anychart.svg
developer: null
based_on: null
licenses:
- type: proprietary
link: 'https://www.anychart.com/support/pages/faq/'
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/anychart-1.png
- /images/slider/anychart-2.png
- /images/slider/anychart-3.png
- /images/slider/anychart-4.png
- /images/slider/anychart-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: AnyChart/AnyChart
npm: anychart
tags:
stackoverflow:
- anychart
twitter:
- AnyChart
links:
website: 'https://www.anychart.com'
examples: 'https://www.anychart.com/products/anychart/gallery/'
docs: 'https://www.anychart.com/products/anychart/docs/'
pricing: 'https://www.anychart.com/buy/'
slack: null
content:
- type: official
title: Getting Started with AnyChart
link: 'https://github.com/AnyChart/AnyChart#getting-started'
- type: official
title: Chartopedia
link: 'https://www.anychart.com/chartopedia/usage-type/'
github_data:
stars: 383
contributors: 21
issues: 18
stale_issues: 13
last_release:
date: '2024-09-25T05:29:05Z'
link: 'https://github.com/AnyChart/AnyChart/releases/tag/v8.13.0'
stackoverflow_data:
questions_count: 474
================================================
FILE: copy/tools/apexcharts.yml
================================================
title: ApexCharts
description: Modern & interactive open-source charts
logo: apexcharts.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/apexcharts/apexcharts.js/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/apexcharts-1.png
- /images/slider/apexcharts-2.png
- /images/slider/apexcharts-3.png
- /images/slider/apexcharts-4.png
- /images/slider/apexcharts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
- svelte
slugs:
github: apexcharts/apexcharts.js
npm: apexcharts
tags:
stackoverflow:
- apexcharts
twitter:
- ApexCharts
links:
website: 'https://apexcharts.com'
examples: 'https://apexcharts.com/javascript-chart-demos/'
docs: 'https://apexcharts.com/docs/installation/'
pricing: null
slack: null
content:
- type: official
title: Creating your first JavaScript chart
link: 'https://apexcharts.com/docs/creating-first-javascript-chart/'
github_data:
stars: 14647
contributors: 224
issues: 297
stale_issues: 218
last_release:
date: '2025-02-19T11:09:43Z'
link: 'https://github.com/apexcharts/apexcharts.js/releases/tag/v4.5.0'
stackoverflow_data:
questions_count: 1087
================================================
FILE: copy/tools/appsmith.yml
================================================
title: Appsmith
description: Low-code tool for building internal apps using pre-built UI widgets
logo: appsmith.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/appsmithorg/appsmith/blob/release/LICENSE'
types:
- app
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/appsmith-1.png
- /images/slider/appsmith-2.png
- /images/slider/appsmith-3.png
- /images/slider/appsmith-5.png
- /images/slider/appsmith-5.png
languages: null
frameworks: null
slugs:
github: appsmithorg/appsmith
npm: null
npm_types: null
tags:
stackoverflow:
- appsmith
twitter:
- appsmith
links:
website: 'https://www.appsmith.com'
examples: 'https://www.appsmith.com/widgets'
docs: 'https://docs.appsmith.com/'
pricing: 'https://www.appsmith.com/pricing'
slack: null
content:
- type: official
title: Getting Started
link: 'https://docs.appsmith.com/#getting-started-with-appsmith'
- type: cube
title: Building an Appsmith Dashboard with Cube
link: 'https://cube.dev/blog/building-an-appsmith-dashboard-with-cube'
github_data:
stars: 35807
contributors: 366
issues: 4138
stale_issues: 2524
last_release:
date: '2025-02-19T09:48:52Z'
link: 'https://github.com/appsmithorg/appsmith/releases/tag/v1.62'
stackoverflow_data:
questions_count: 27
================================================
FILE: copy/tools/billboard.yml
================================================
title: Billboard.js
description: 'Re-usable, easy interface JavaScript chart library based on D3.js'
logo: billboard.svg
developer: null
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/naver/billboard.js/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/billboard-1.png
- /images/slider/billboard-2.png
- /images/slider/billboard-3.png
- /images/slider/billboard-4.png
- /images/slider/billboard-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
slugs:
github: naver/billboard.js
npm: billboard.js
tags:
stackoverflow:
- billboard.js
twitter:
- BillboardJS
links:
website: 'https://naver.github.io/billboard.js/'
examples: 'https://naver.github.io/billboard.js/demo/'
docs: 'https://naver.github.io/billboard.js/release/latest/doc/'
pricing: null
slack: null
content: null
github_data:
stars: 5878
contributors: 190
issues: 146
stale_issues: 139
last_release:
date: '2025-01-07T08:55:27Z'
link: 'https://github.com/naver/billboard.js/releases/tag/3.14.3'
stackoverflow_data:
questions_count: 66
================================================
FILE: copy/tools/c3.yml
================================================
title: C3.js
description: D3.js-based reusable chart library
logo: c3.svg
developer: null
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/c3js/c3/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/c3-1.png
- /images/slider/c3-2.png
- /images/slider/c3-3.png
- /images/slider/c3-4.png
- /images/slider/c3-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: c3js/c3
npm: c3
npm_types: '@types/c3'
tags:
stackoverflow:
- c3.js
twitter:
- c3js
links:
website: 'https://c3js.org'
examples: 'https://c3js.org/examples.html'
docs: 'https://c3js.org/reference.html'
pricing: null
slack: null
content:
- type: official
title: Getting Started with c3.js
link: 'https://c3js.org/gettingstarted.html'
github_data:
stars: 9347
contributors: 169
issues: 726
stale_issues: 723
last_release:
date: '2020-08-08T09:14:36Z'
link: 'https://github.com/c3js/c3/releases/tag/v0.7.20'
stackoverflow_data:
questions_count: 1116
================================================
FILE: copy/tools/chartist.yml
================================================
title: Chartist
description: Simple responsive SVG charts
logo: chartist.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/chartist-js/chartist/blob/main/LICENSE-MIT'
- type: open-source
title: WTFPL
link: 'https://github.com/gionkunz/chartist-js/blob/main/LICENSE-WTFPL'
types:
- charts
renders:
- svg
features:
easy-to-customize: 1
easy-to-start-with: 2
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/chartist-1.png
- /images/slider/chartist-2.png
- /images/slider/chartist-3.png
- /images/slider/chartist-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: chartist-js/chartist
npm: chartist
tags:
stackoverflow:
- chartist.js
links:
website: 'https://gionkunz.github.io/chartist-js/'
examples: 'https://gionkunz.github.io/chartist-js/examples.html'
docs: 'https://gionkunz.github.io/chartist-js/api-documentation.html'
pricing: null
content:
- type: official
title: A quick start guide for Chartist
link: 'https://github.com/chartist-js/chartist#quickstart'
github_data:
stars: 13360
contributors: 89
issues: 198
stale_issues: 197
last_release:
date: '2022-11-03T11:45:38Z'
link: 'https://github.com/chartist-js/chartist/releases/tag/v1.3.0'
stackoverflow_data:
questions_count: 235
================================================
FILE: copy/tools/chartjs.yml
================================================
title: Chart.js
description: Simple yet flexible JavaScript charting for designers & developers
logo: chartjs.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/chartjs/Chart.js/blob/master/LICENSE.md'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 2
easy-to-start-with: 3
full-fledged: 0
very-popular: 1
well-documented: 1
gallery:
- /images/slider/chartjs-1.png
- /images/slider/chartjs-2.png
- /images/slider/chartjs-3.png
- /images/slider/chartjs-4.png
- /images/slider/chartjs-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: chartjs/Chart.js
npm: chart.js
tags:
stackoverflow:
- chart.js
- react-chartjs
- react-chartjs-2
twitter:
- chartjs
links:
website: 'https://www.chartjs.org'
examples: 'https://www.chartjs.org/docs/latest/samples/bar/vertical.html'
docs: 'https://www.chartjs.org/docs/latest/'
pricing: null
slack: 'https://chartjs-slack.herokuapp.com'
content:
- type: official
title: Awesome Chart.js — a curated list of things related to Chart.js
link: 'https://github.com/chartjs/awesome'
- type: cube
title: Chart.js Example with Dynamic Dataset
link: 'https://cube.dev/blog/chart-js-example-with-dynamic-dataset/'
github_data:
stars: 65416
contributors: 514
issues: 442
stale_issues: 331
last_release:
date: '2025-02-19T15:45:55Z'
link: 'https://github.com/chartjs/Chart.js/releases/tag/v4.4.8'
stackoverflow_data:
questions_count: 13463
integrations:
- framework: react
slugs:
github: reactchartjs/react-chartjs-2
npm: react-chartjs-2
links:
website: 'https://react-chartjs-2.js.org'
- framework: angular
slugs:
github: valor-software/ng2-charts
npm: ng2-charts
links:
website: 'https://valor-software.com/ng2-charts/'
- framework: vue
slugs:
github: apertureless/vue-chartjs
npm: vue-chartjs
links:
website: 'https://vue-chartjs.org'
- framework: svelte
slugs:
github: SauravKanchan/svelte-chartjs
npm: svelte-chartjs
links:
website: 'https://saurav.tech/mdbsvelte/?path=/story/charts--examples'
================================================
FILE: copy/tools/cytoscape.yml
================================================
title: Cytoscape.js
description: Graph theory (network) library for visualisation and analysis
logo: cytoscape.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/cytoscape/cytoscape.js/blob/unstable/LICENSE'
types:
- low-level
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/cytoscape-1.png
- /images/slider/cytoscape-2.png
- /images/slider/cytoscape-3.png
- /images/slider/cytoscape-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: cytoscape/cytoscape.js
npm: cytoscape
npm_types: '@types/cytoscape'
tags:
stackoverflow:
- cytoscape.js
twitter: null
links:
website: 'https://js.cytoscape.org'
examples: 'https://js.cytoscape.org/#demos'
docs: 'https://js.cytoscape.org/#notation'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://js.cytoscape.org/#getting-started'
github_data:
stars: 10279
contributors: 155
issues: 14
stale_issues: 2
last_release:
date: '2025-02-26T19:47:13Z'
link: 'https://github.com/cytoscape/cytoscape.js/releases/tag/v3.31.1'
stackoverflow_data:
questions_count: 1283
================================================
FILE: copy/tools/d3.yml
================================================
title: D3.js
description: JavaScript library for manipulating documents based on data
logo: d3.png
developer: null
based_on: null
licenses:
- type: open-source
title: BSD
link: 'https://github.com/d3/d3/blob/master/LICENSE'
types:
- low-level
renders:
- svg
- html
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 2
very-popular: 1
well-documented: 0
gallery:
- /images/slider/d3-1.png
- /images/slider/d3-2.png
- /images/slider/d3-3.png
- /images/slider/d3-4.png
- /images/slider/d3-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: d3/d3
npm: d3
npm_types: '@types/d3'
tags:
stackoverflow:
- d3.js
twitter:
- D3js
links:
website: 'https://d3js.org'
examples: 'https://observablehq.com/@d3/gallery'
docs: 'https://github.com/d3/d3/wiki'
pricing: null
slack: 'https://d3-slackin.herokuapp.com'
content:
- type: official
title: 'Learn D3: Introduction'
link: 'https://observablehq.com/@d3/learn-d3'
- type: cube
title: D3 Dashboard Tutorial
link: 'https://d3-dashboard.cube.dev'
github_data:
stars: 109948
contributors: 152
issues: 9
stale_issues: 6
last_release:
date: '2024-03-12T22:18:19Z'
link: 'https://github.com/d3/d3/releases/tag/v7.9.0'
stackoverflow_data:
questions_count: 39316
================================================
FILE: copy/tools/datasette.yml
================================================
title: Datasette
description: Open-source multi-tool for exploring and publishing data
logo: datasette.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/simonw/datasette/blob/main/LICENSE'
types:
- app
renders: null
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/datasette-1.png
- /images/slider/datasette-2.png
- /images/slider/datasette-3.png
- /images/slider/datasette-4.png
languages: null
frameworks: null
slugs:
github: simonw/datasette
npm: null
npm_types: null
tags:
stackoverflow:
- datasette
twitter: null
links:
website: 'https://datasette.io'
examples: 'https://datasette.io/examples'
docs: 'https://docs.datasette.io/en/stable/'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://docs.datasette.io/en/stable/getting_started.html'
github_data:
stars: 9831
contributors: 81
issues: 565
stale_issues: 500
last_release:
date: '2025-02-06T19:14:10Z'
link: 'https://github.com/simonw/datasette/releases/tag/1.0a17'
stackoverflow_data:
questions_count: 4
================================================
FILE: copy/tools/deck-gl.yml
================================================
title: deck.gl
description: WebGL-powered visualization framework for large-scale datasets
logo: deck-gl.svg
developer: Uber
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/visgl/deck.gl/blob/master/LICENSE'
types:
- low-level
- maps
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/deck-gl-1.jpg
- /images/slider/deck-gl-2.jpg
- /images/slider/deck-gl-3.jpg
- /images/slider/deck-gl-4.jpg
- /images/slider/deck-gl-5.jpg
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- vue
slugs:
github: visgl/deck.gl
npm: deck.gl
npm_types: '@danmarshall/deckgl-typings'
tags:
stackoverflow:
- deck.gl
twitter:
- deckgl
links:
website: 'https://deck.gl'
examples: 'https://deck.gl/examples'
docs: 'https://deck.gl/docs'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://deck.gl/docs/get-started/using-standalone'
github_data:
stars: 12524
contributors: 283
issues: 350
stale_issues: 226
last_release:
date: '2025-02-27T07:02:11Z'
link: 'https://github.com/visgl/deck.gl/releases/tag/v9.1.4'
stackoverflow_data:
questions_count: 258
================================================
FILE: copy/tools/echarts.yml
================================================
title: Apache ECharts
description: Open-source JavaScript visualization library
logo: echarts.png
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/apache/echarts/blob/master/LICENSE'
types:
- charts
- maps
- 3d
renders:
- svg
- canvas
features:
easy-to-customize: 2
easy-to-start-with: 1
full-fledged: 2
very-popular: 0
well-documented: 2
gallery:
- /images/slider/echarts-1.png
- /images/slider/echarts-2.png
- /images/slider/echarts-3.png
- /images/slider/echarts-4.png
- /images/slider/echarts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: apache/echarts
npm: ag-grid-community
npm_types: '@types/echarts'
tags:
stackoverflow:
- echarts
twitter:
- ECharts
links:
website: 'https://echarts.apache.org/en/index.html'
examples: 'https://echarts.apache.org/examples/en/index.html'
docs: 'https://echarts.apache.org/en/api.html#echarts'
pricing: null
slack: null
content:
- type: official
title: Get started with ECharts in 5 minutes
link: >-
https://echarts.apache.org/en/tutorial.html#Get%20Started%20with%20ECharts%20in%205%20minutes
- type: cube
title: Building an Apache ECharts dashboard with React and Cube
link: >-
https://cube.dev/blog/building-an-apache-echarts-dashboard-with-react-and-cube/
- type: cube
title: Building an Apache ECharts Dashboard with Angular and Cube
link: >-
https://cube.dev/blog/building-an-apache-echarts-dashboard-with-angular-and-cube/
- type: cube
title: Building an Apache ECharts Dashboard with Vue 3 and Cube
link: >-
https://cube.dev/blog/building-an-apache-echarts-dashboard-with-vue-3-and-cube/
github_data:
stars: 61997
contributors: 293
issues: 2029
stale_issues: 1406
last_release:
date: '2024-12-28T06:52:31Z'
link: 'https://github.com/apache/echarts/releases/tag/5.6.0'
stackoverflow_data:
questions_count: 1480
integrations:
- framework: react
slugs:
github: hustcc/echarts-for-react
npm: echarts-for-react
links:
website: 'https://git.hust.cc/echarts-for-react/'
- framework: angular
slugs:
github: xieziyu/ngx-echarts
npm: ngx-echarts
links:
website: 'https://xieziyu.github.io/ngx-echarts/'
- framework: vue
slugs:
github: ecomfe/vue-echarts
npm: vue-echarts
links:
website: 'https://vue-echarts.dev'
================================================
FILE: copy/tools/flot.yml
================================================
title: Flot
description: Attractive JavaScript charts for jQuery
logo: flot.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/flot/flot/blob/master/LICENSE.txt'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
slugs:
github: flot/flot
npm: flot
npm_types: '@types/flot'
tags:
stackoverflow:
- flot
twitter: null
links:
website: 'http://www.flotcharts.org'
examples: 'http://www.flotcharts.org/flot/examples/'
docs: 'https://github.com/flot/flot/blob/master/API.md'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://github.com/flot/flot/blob/master/README.md#installation'
github_data:
stars: 5940
contributors: 93
issues: 457
stale_issues: 453
last_release:
date: '2014-04-21T20:53:45Z'
link: 'https://github.com/flot/flot/releases/tag/v0.8.3'
stackoverflow_data:
questions_count: 2059
================================================
FILE: copy/tools/frappe.yml
================================================
title: Frappe
description: >-
GitHub-inspired simple and modern SVG charts for the web with zero
dependencies
logo: frappe.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/frappe/charts/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
frameworks:
- vanilla-js
- react
- vue
- svelte
slugs:
github: frappe/charts
npm: frappe-charts
tags:
stackoverflow:
- frappe
twitter: null
links:
website: 'https://frappe.io/charts'
examples: 'https://frappe.io/charts'
docs: 'https://frappe.io/charts/docs'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://frappe.io/charts/docs'
github_data:
stars: 14984
contributors: 55
issues: 125
stale_issues: 122
last_release:
date: '2022-04-27T10:43:31Z'
link: 'https://github.com/frappe/charts/releases/tag/v1.6.3'
stackoverflow_data:
questions_count: 220
================================================
FILE: copy/tools/fusioncharts.yml
================================================
title: FusionCharts
description: JavaScript charts for web & mobile
logo: fusioncharts.svg
developer: null
based_on: null
licenses:
- type: proprietary
link: >-
https://www.ideracorp.com/Legal/FusionCharts/MasterISVSoftwareSubscriptionAgreement
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/fusioncharts-1.png
- /images/slider/fusioncharts-2.png
- /images/slider/fusioncharts-3.png
- /images/slider/fusioncharts-4.png
- /images/slider/fusioncharts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
- svelte
slugs:
github: fusioncharts/fusioncharts-dist
npm: fusioncharts
npm_types: '@types/fusioncharts'
tags:
stackoverflow:
- fusioncharts
twitter:
- FusionCharts
links:
website: 'https://www.fusioncharts.com/fusioncharts'
examples: 'https://www.fusioncharts.com/charts'
docs: 'https://www.fusioncharts.com/dev/fusioncharts'
pricing: 'https://www.fusioncharts.com/buy'
slack: null
content:
- type: official
title: Create a Chart Using FusionCharts
link: >-
https://www.fusioncharts.com/dev/getting-started/plain-javascript/your-first-chart-using-plain-javascript
github_data:
stars: 85
contributors: 9
issues: 40
stale_issues: 34
last_release:
date: '2024-11-12T14:58:42Z'
link: 'https://github.com/fusioncharts/fusioncharts-dist/releases/tag/4.1.0'
stackoverflow_data:
questions_count: 799
================================================
FILE: copy/tools/g2.yml
================================================
title: G2
description: Highly interactive data-driven visualization grammar for statistical charts
logo: antv.svg
developer: AntV
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/antvis/G2/blob/master/LICENSE'
types:
- charts
- maps
renders:
- svg
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 1
gallery:
- /images/slider/g2-1.png
- /images/slider/g2-2.png
- /images/slider/g2-3.png
- /images/slider/g2-4.png
- /images/slider/g2-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: antvis/G2
npm: '@antv/g2'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://g2.antv.vision/en'
examples: 'https://g2.antv.vision/en/examples/gallery'
docs: 'https://g2.antv.vision/en/docs/manual/about-g2'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://g2.antv.vision/en/docs/manual/getting-started'
github_data:
stars: 12209
contributors: 207
issues: 214
stale_issues: 80
last_release:
date: '2025-02-11T08:23:42Z'
link: 'https://github.com/antvis/G2/releases/tag/5.2.11'
stackoverflow_data: null
================================================
FILE: copy/tools/g2plot.yml
================================================
title: G2Plot
description: Interactive and responsive charting library based on the grammar of graphics
logo: antv.svg
developer: AntV
based_on:
- g2
licenses:
- type: open-source
title: MIT
link: 'https://github.com/antvis/G2Plot/blob/master/LICENSE'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 1
gallery:
- /images/slider/g2plot-1.png
- /images/slider/g2plot-2.png
- /images/slider/g2plot-3.png
- /images/slider/g2plot-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- vue
slugs:
github: antvis/G2Plot
npm: '@antv/g2plot'
tags:
stackoverflow:
- g2plot
twitter:
- G2Plot
links:
website: 'https://g2plot.antv.vision/en'
examples: 'https://g2plot.antv.vision/en/examples/gallery'
docs: 'https://g2plot.antv.vision/en/docs/manual/introduction'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://g2plot.antv.vision/en/docs/manual/getting-started'
github_data:
stars: 2584
contributors: 67
issues: 438
stale_issues: 393
last_release:
date: '2024-07-30T08:47:03Z'
link: 'https://github.com/antvis/G2Plot/releases/tag/2.4.32'
stackoverflow_data:
questions_count: 10
================================================
FILE: copy/tools/g6.yml
================================================
title: G6
description: Graph visualization engine with simplicity and convenience
logo: antv.svg
developer: AntV
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/antvis/G6/blob/master/LICENSE'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 1
gallery:
- /images/slider/g6-1.png
- /images/slider/g6-2.png
- /images/slider/g6-3.png
- /images/slider/g6-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: antvis/G6
npm: '@antv/g6'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://g6.antv.vision/en'
examples: 'https://g6.antv.vision/en/examples/gallery'
docs: 'https://g6.antv.vision/en/docs/manual/introduction'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://g6.antv.vision/en/docs/manual/getting-started'
github_data:
stars: 11338
contributors: 171
issues: 158
stale_issues: 3
last_release:
date: '2025-02-14T08:55:41Z'
link: 'https://github.com/antvis/G6/releases/tag/5.0.43'
stackoverflow_data: null
================================================
FILE: copy/tools/google-charts.yml
================================================
title: Google Charts
description: Interactive charts for browsers and mobile devices
logo: google-charts.png
developer: null
based_on: null
licenses:
- type: proprietary
link: 'https://developers.google.com/chart/terms'
types:
- charts
- maps
renders:
- svg
- html
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/google-charts-1.png
- /images/slider/google-charts-2.png
- /images/slider/google-charts-3.png
- /images/slider/google-charts-4.png
- /images/slider/google-charts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
npm_types: '@types/google.visualization'
tags:
stackoverflow:
- google-visualization
twitter:
- googlecharts
links:
website: 'https://developers.google.com/chart'
examples: 'https://developers.google.com/chart/interactive/docs/gallery'
docs: 'https://developers.google.com/chart/interactive/docs'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://developers.google.com/chart/interactive/docs/quick_start'
- type: cube
title: "Google Charts Dashboard: a Tutorial with an Artistic Touch of MoMA \U0001F5BC"
link: 'https://cube.dev/blog/google-charts-dashboard/'
- type: cube
title: Building a Dashboard with a React Wrapper for Google Charts
link: 'https://cube.dev/blog/react-google-charts-dashboard/'
github_data: null
stackoverflow_data:
questions_count: 9023
integrations:
- framework: react
slugs:
github: RakanNimer/react-google-charts
npm: react-google-charts
links:
website: 'https://react-google-charts.com'
- framework: angular
slugs:
github: FERNman/angular-google-charts
npm: angular-google-charts
links:
website: null
- framework: vue
slugs:
github: devstark-com/vue-google-charts
npm: vue-google-charts
links:
website: null
================================================
FILE: copy/tools/highcharts.yml
================================================
title: Highcharts
description: Modern SVG-based multi-platform charting library
logo: highcharts.svg
developer: null
based_on: null
licenses:
- type: proprietary
license: 'https://github.com/highcharts/highcharts/blob/master/license.txt'
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 1
easy-to-start-with: 0
full-fledged: 1
very-popular: 0
well-documented: 0
gallery:
- /images/slider/highcharts-1.png
- /images/slider/highcharts-2.png
- /images/slider/highcharts-3.png
- /images/slider/highcharts-4.png
- /images/slider/highcharts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: highcharts/highcharts
npm: highcharts
tags:
stackoverflow:
- highcharts
twitter:
- highcharts
links:
website: 'https://www.highcharts.com'
examples: 'https://www.highcharts.com/demo'
docs: 'https://www.highcharts.com/docs/index'
pricing: 'https://shop.highsoft.com'
slack: null
content:
- type: cube
title: React Highcharts Example with Cube.js
link: 'https://cube.dev/blog/react-highcharts-example/'
github_data:
stars: 12176
contributors: 264
issues: 849
stale_issues: 465
last_release:
date: null
link: null
stackoverflow_data:
questions_count: 26238
================================================
FILE: copy/tools/kepler-gl.yml
================================================
title: Kepler.gl
description: Open-source geospatial analysis tool for large-scale data sets
logo: kepler-gl.svg
developer: Uber
based_on:
- mapbox-gl
- deck-gl
licenses:
- type: open-source
title: MIT
link: 'https://github.com/keplergl/kepler.gl/blob/master/LICENSE'
types:
- maps
renders:
- svg
- html
- canvas
- webgl
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
slugs:
github: keplergl/kepler.gl
npm: kepler.gl
tags:
stackoverflow:
- kepler.gl
twitter:
- KeplerGL
links:
website: 'https://kepler.gl'
examples: 'https://docs.kepler.gl/examples'
docs: 'https://docs.kepler.gl/docs'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://vis.academy/#/kepler.gl/setup'
- type: community
title: Exploring Geospatial Data with Kepler.gl
link: >-
https://medium.com/vis-gl/exploring-geospatial-data-with-kepler-gl-cf655839628f
github_data:
stars: 10596
contributors: 130
issues: 498
stale_issues: 444
last_release:
date: '2025-01-29T16:00:29Z'
link: 'https://github.com/keplergl/kepler.gl/releases/tag/v3.1.0'
stackoverflow_data:
questions_count: 77
================================================
FILE: copy/tools/laue.yml
================================================
title: Laue
description: Modern charts for Vue.js
logo: laue.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/QingWei-Li/laue/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/laue-1.png
- /images/slider/laue-2.png
- /images/slider/laue-3.png
- /images/slider/laue-4.png
- /images/slider/laue-5.png
languages:
- JavaScript
frameworks:
- vue
slugs:
github: qingwei-li/laue
npm: laue
tags:
stackoverflow: null
twitter: null
links:
website: 'https://laue.js.org'
examples: 'https://laue.js.org/examples'
docs: 'https://laue.js.org/api'
pricing: null
slack: null
content:
- type: official
title: Quick start with Laue
link: 'https://laue.js.org/guide#quick-started'
github_data:
stars: 263
contributors: 8
issues: 15
stale_issues: 15
last_release:
date: '2018-10-31T15:52:54Z'
link: 'https://github.com/QingWei-Li/laue/releases/tag/v0.2.0'
stackoverflow_data: null
================================================
FILE: copy/tools/layer-cake.yml
================================================
title: Layer Cake
description: Graphics framework for Svelte
logo: layer-cake.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/mhkeller/layercake/blob/master/LICENSE'
types:
- charts
- low-level
- maps
renders:
- svg
- html
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
frameworks:
- svelte
slugs:
github: mhkeller/layercake
npm: layercake
tags:
stackoverflow: null
twitter: null
links:
website: 'https://layercake.graphics'
examples: 'https://layercake.graphics'
docs: 'https://layercake.graphics/guide'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://layercake.graphics/guide#getting-started'
github_data:
stars: 1516
contributors: 11
issues: 7
stale_issues: 2
last_release:
date: '2024-10-19T23:08:21Z'
link: 'https://github.com/mhkeller/layercake/releases/tag/v8.4.0'
stackoverflow_data: null
================================================
FILE: copy/tools/leaflet.yml
================================================
title: Leaflet
description: JavaScript library for mobile-friendly interactive maps
logo: leafletjs.png
developer: null
based_on: null
licenses:
- type: open-source
title: BSD
link: 'https://github.com/Leaflet/Leaflet/blob/main/LICENSE'
types:
- maps
renders:
- svg
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/leaflet-1.png
- /images/slider/leaflet-2.png
- /images/slider/leaflet-3.png
- /images/slider/leaflet-4.png
- /images/slider/leaflet-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: leaflet/leaflet
npm: leaflet
npm_types: '@types/leaflet'
tags:
stackoverflow:
- leaflet
twitter:
- leafletjs
links:
website: 'https://leafletjs.com'
examples: 'https://leafletjs.com/examples.html'
docs: 'https://leafletjs.com/reference-1.7.1.html'
pricing: null
slack: null
content:
- type: official
title: leafletjs Quick Start Guide
link: 'https://leafletjs.com/examples/quick-start/'
github_data:
stars: 42153
contributors: 987
issues: 404
stale_issues: 377
last_release:
date: '2023-05-18T11:12:03Z'
link: 'https://github.com/Leaflet/Leaflet/releases/tag/v1.9.4'
stackoverflow_data:
questions_count: 12948
================================================
FILE: copy/tools/lightweight-charts.yml
================================================
title: Lightweight Charts
description: Financial lightweight charts built with HTML5 canvas
logo: lightweight-charts.svg
developer: TradingView
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/tradingview/lightweight-charts/blob/master/LICENSE'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- vue
- angular
slugs:
github: tradingview/lightweight-charts
npm: lightweight-charts
tags:
stackoverflow:
- lightweight-charts
twitter:
- lightweightcharts
links:
website: 'https://www.tradingview.com/lightweight-charts/'
examples: 'https://www.tradingview.com/lightweight-charts/'
docs: 'https://tradingview.github.io/lightweight-charts/'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://tradingview.github.io/lightweight-charts/docs'
- type: official
title: Customization
link: >-
https://tradingview.github.io/lightweight-charts/tutorials/customization/intro
- type: official
title: Framework integrations
link: >-
https://tradingview.github.io/lightweight-charts/tutorials#framework-integrations
github_data:
stars: 10832
contributors: 55
issues: 97
stale_issues: 50
last_release:
date: '2025-02-26T14:27:04Z'
link: 'https://github.com/tradingview/lightweight-charts/releases/tag/v5.0.3'
stackoverflow_data:
questions_count: 162
================================================
FILE: copy/tools/mapbox-gl.yml
================================================
title: Mapbox GL JS
description: >-
Interactive, thoroughly customizable maps in the browser, powered by vector
tiles and WebGL
logo: mapbox-gl.png
developer: null
based_on: null
licenses:
- type: proprietary
link: 'https://github.com/mapbox/mapbox-gl-js/blob/main/LICENSE.txt'
types:
- maps
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/mapbox-gl-1.png
- /images/slider/mapbox-gl-2.png
- /images/slider/mapbox-gl-3.png
- /images/slider/mapbox-gl-4.png
- /images/slider/mapbox-gl-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: mapbox/mapbox-gl-js
npm: mapbox-gl
npm_types: '@types/mapbox-gl'
tags:
stackoverflow:
- mapbox
- mapbox-gl-js
twitter:
- mapbox
links:
website: 'https://docs.mapbox.com/mapbox-gl-js/api/'
examples: 'https://docs.mapbox.com/mapbox-gl-js/example/'
docs: 'https://docs.mapbox.com/mapbox-gl-js/api/'
pricing: null
slack: null
content:
- type: official
title: Tutorials
link: 'https://docs.mapbox.com/help/tutorials/?product=Mapbox+GL+JS'
- type: cube
title: JavaScript Map Data Visualization with Mapbox
link: 'https://mapbox-guide.cube.dev'
github_data:
stars: 11440
contributors: 440
issues: 1316
stale_issues: 1152
last_release:
date: '2025-02-13T16:41:06Z'
link: 'https://github.com/mapbox/mapbox-gl-js/releases/tag/v3.10.0'
stackoverflow_data:
questions_count: 9204
================================================
FILE: copy/tools/material-ui-data-grid.yml
================================================
title: MUI X Data Grid
description: Fast and extendable data table and data grid for React
logo: material-ui.svg
developer: MUI
based_on: null
licenses:
- type: proprietary
title: MUI X Premium
link: >-
https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid-premium/LICENSE
- type: proprietary
title: MUI X Pro
link: >-
https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid-pro/LICENSE
- type: open-source
title: MIT
link: 'https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/LICENSE'
types:
- grid
renders:
- html
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/mui-x-data-grid-1.png
- /images/slider/mui-x-data-grid-2.png
- /images/slider/mui-x-data-grid-3.png
- /images/slider/mui-x-data-grid-4.png
- /images/slider/mui-x-data-grid-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: mui/mui-x
npm: '@mui/x-data-grid'
tags:
stackoverflow:
- mui-x
twitter:
- MUI_hq
links:
website: 'https://mui.com/x/react-data-grid/'
examples: 'https://mui.com/x/react-data-grid/#mit-version-free-forever'
docs: 'https://mui.com/x/react-data-grid/'
pricing: 'https://mui.com/pricing/'
slack: null
content:
- type: cube
title: Material UI Dashboard with React
link: 'https://material-ui-dashboard.cube.dev'
github_data:
stars: 4692
contributors: 440
issues: 1308
stale_issues: 787
last_release:
date: '2025-02-28T16:07:27Z'
link: 'https://github.com/mui/mui-x/releases/tag/v8.0.0-alpha.13'
stackoverflow_data:
questions_count: 261
================================================
FILE: copy/tools/metabase.yml
================================================
title: Metabase
description: 'Easy, open-source way to ask questions and learn from data'
logo: metabase.png
developer: null
based_on: null
licenses:
- type: proprietary
link: 'https://github.com/metabase/metabase/blob/master/LICENSE.txt'
- type: open-source
title: AGPL
link: 'https://github.com/metabase/metabase/blob/master/LICENSE.txt'
types:
- app
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/metabase-1.png
- /images/slider/metabase-2.png
- /images/slider/metabase-3.png
- /images/slider/metabase-4.png
- /images/slider/metabase-5.png
languages: null
frameworks: null
slugs:
github: metabase/metabase
tags:
stackoverflow:
- metabase
twitter:
- Metabase
links:
website: 'https://www.metabase.com'
examples: >-
https://www.metabase.com/learn/getting-started/getting-started/tour-of-metabase.html
docs: 'https://www.ag-grid.com/javascript-grid/'
pricing: null
slack: null
content:
- type: official
title: Getting started with Metabase
link: >-
https://www.metabase.com/learn/getting-started/getting-started/getting-started.html
- type: cube
title: Connecting Metabase to Cube.js
link: 'https://github.com/pyrooka/metabase-cubejs-driver#usage'
github_data:
stars: 41031
contributors: 441
issues: 3803
stale_issues: 2364
last_release:
date: '2025-02-25T19:30:05Z'
link: 'https://github.com/metabase/metabase/releases/tag/v0.52.13'
stackoverflow_data:
questions_count: 382
================================================
FILE: copy/tools/muze.yml
================================================
title: Muze
description: Free library for creating exploratory data visualizations using WebAssembly
logo: muze.svg
developer: Charts.com
based_on: null
licenses:
- type: proprietary
title: EULA
link: 'https://github.com/chartshq/muze/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/muze-1.png
- /images/slider/muze-2.png
- /images/slider/muze-3.png
- /images/slider/muze-4.png
- /images/slider/muze-5.png
languages:
- JavaScript
frameworks:
- vanilla-js
- react
slugs:
github: chartshq/muze
npm: muze
tags:
stackoverflow:
- muze
twitter: null
links:
website: 'https://muzejs.org'
examples: 'https://muzejs.org/demos/wa/latest'
docs: 'https://muzejs.org/docs/wa/latest/introduction'
pricing: null
slack: null
content:
- type: official
title: Getting Started with Muze
link: >-
https://muzejs.org/docs/wa/latest/introduction?id=getting-started-with-muze
- type: cube
title: 'Tableau-like Charts with MuzeJS, Cube.js, and React'
link: 'https://cube.dev/blog/react-muzejs-tutorial/'
github_data:
stars: 1185
contributors: 21
issues: 4
stale_issues: 4
last_release:
date: '2020-07-31T14:11:59Z'
link: 'https://github.com/chartshq/muze/releases/tag/v2.0.0'
stackoverflow_data:
questions_count: 0
================================================
FILE: copy/tools/ngx-charts.yml
================================================
title: ngx-charts
description: Declarative charting framework for Angular
logo: ngx-charts.svg
developer: Swimlane
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/swimlane/ngx-charts/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/ngx-charts-1.png
- /images/slider/ngx-charts-2.png
- /images/slider/ngx-charts-3.png
- /images/slider/ngx-charts-4.png
- /images/slider/ngx-charts-5.png
languages:
- TypeScript
frameworks:
- angular
slugs:
github: swimlane/ngx-charts
npm: '@swimlane/ngx-charts'
tags:
stackoverflow:
- ngx-charts
twitter:
- ngxcharts
links:
website: 'https://swimlane.github.io/ngx-charts/'
examples: 'https://swimlane.github.io/ngx-charts/'
docs: 'https://swimlane.gitbook.io/ngx-charts'
pricing: null
slack: null
content: null
github_data:
stars: 4312
contributors: 133
issues: 712
stale_issues: 688
last_release:
date: null
link: null
stackoverflow_data:
questions_count: 247
================================================
FILE: copy/tools/nivo.yml
================================================
title: nivo
description: Supercharged React components to easily build dataviz apps
logo: nivo.png
developer: null
based_on:
- d3
licenses:
- type: open-source
title: MIT
types:
- charts
- maps
renders:
- svg
- html
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/nivo-1.png
- /images/slider/nivo-2.png
- /images/slider/nivo-3.png
- /images/slider/nivo-4.png
- /images/slider/nivo-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: plouc/nivo
npm: null
tags:
stackoverflow:
- nivo-react
twitter:
- nivo
links:
website: 'https://nivo.rocks'
examples: 'https://nivo.rocks/storybook/'
docs: 'https://nivo.rocks/components'
pricing: null
slack: null
content:
- type: cube
title: Building a nivo Dashboard with Cube
link: 'https://cube.dev/blog/building-a-nivo-dashboard-with-cube'
github_data:
stars: 13415
contributors: 220
issues: 89
stale_issues: 56
last_release:
date: '2024-11-11T01:52:42Z'
link: 'https://github.com/plouc/nivo/releases/tag/v0.88.0'
stackoverflow_data:
questions_count: 84
================================================
FILE: copy/tools/observable-plot.yml
================================================
title: Observable Plot
description: Concise API for exploratory data visualization
logo: observable.png
developer: null
based_on:
- d3
licenses:
- type: open-source
title: ISC
link: 'https://github.com/observablehq/plot/blob/main/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/observable-plot-1.png
- /images/slider/observable-plot-2.png
- /images/slider/observable-plot-3.png
- /images/slider/observable-plot-4.png
- /images/slider/observable-plot-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: observablehq/plot
npm: '@observablehq/plot'
tags:
stackoverflow:
- observablehq
twitter:
- observablehq
links:
website: 'https://observablehq.com/plot'
examples: 'https://observablehq.com/@observablehq/plot-gallery'
docs: 'https://observablehq.com/plot'
pricing: null
slack: 'https://observable-community.slack.com/ssb/redirect'
content:
- type: official
title: Getting Started
link: 'https://observablehq.com/plot/getting-started'
github_data:
stars: 4605
contributors: 26
issues: 250
stale_issues: 204
last_release:
date: '2025-02-14T16:05:17Z'
link: 'https://github.com/observablehq/plot/releases/tag/v0.6.17'
stackoverflow_data:
questions_count: 136
================================================
FILE: copy/tools/p5.yml
================================================
title: p5.js
description: >-
JavaScript library for creative coding that makes coding accessible and
inclusive
logo: p5.svg
developer: null
based_on: null
licenses:
- type: open-source
title: GNU LGPL 2.1
link: 'https://github.com/processing/p5.js/blob/main/license.txt'
types:
- low-level
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/p5-1.png
- /images/slider/p5-2.png
- /images/slider/p5-3.png
- /images/slider/p5-4.png
- /images/slider/p5-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: processing/p5.js
npm: p5
npm_types: '@types/p5'
tags:
stackoverflow:
- p5.js
twitter:
- p5js
- p5xjs
links:
website: 'https://p5js.org'
examples: 'https://p5js.org/examples/'
docs: 'https://p5js.org/examples/'
pricing: null
slack: null
content:
- type: official
title: Get Started with p5.js
link: 'https://p5js.org/get-started/'
github_data:
stars: 22172
contributors: 796
issues: 302
stale_issues: 201
last_release:
date: '2025-02-25T21:27:36Z'
link: 'https://github.com/processing/p5.js/releases/tag/v2.0.0-beta.3'
stackoverflow_data:
questions_count: 3185
================================================
FILE: copy/tools/pancake.yml
================================================
title: Pancake
description: 'Responsive charts, JavaScript optional'
logo: pancake.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/Rich-Harris/pancake/blob/master/package.json#L24'
types:
- charts
renders:
- svg
- html
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
frameworks:
- svelte
slugs:
github: Rich-Harris/pancake
npm: '@sveltejs/pancake'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://pancake-charts.surge.sh'
examples: 'https://pancake-charts.surge.sh'
docs: null
pricing: null
slack: null
content:
- type: official
title: 'A new technique for making responsive, JavaScript-free charts'
link: >-
https://dev.to/richharris/a-new-technique-for-making-responsive-javascript-free-charts-gmp
github_data:
stars: 1303
contributors: 2
issues: 17
stale_issues: 17
last_release:
date: null
link: null
stackoverflow_data: null
================================================
FILE: copy/tools/perspective.yml
================================================
title: Perspective
description: >-
Interactive analytics and data visualization component, especially well-suited
for large and/or streaming datasets
logo: finos.svg
developer: J.P. Morgan
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/finos/perspective/blob/master/LICENSE'
types:
- charts
renders:
- svg
- html
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/perspective-1.png
- /images/slider/perspective-2.png
- /images/slider/perspective-3.png
- /images/slider/perspective-4.png
- /images/slider/perspective-5.png
languages:
- JavaScript
- Python
frameworks:
- vanilla-js
slugs:
github: finos/perspective
npm: '@finos/perspective'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://perspective.finos.org'
examples: 'https://perspective.finos.org'
docs: 'https://perspective.finos.org/docs/js'
pricing: null
slack: null
content:
- type: official
title: JavaScript User Guide
link: 'https://perspective.finos.org/docs/js'
- type: official
title: Python User Guide
link: 'https://perspective.finos.org/docs/python'
github_data:
stars: 8836
contributors: 98
issues: 97
stale_issues: 69
last_release:
date: '2025-02-10T05:23:05Z'
link: 'https://github.com/finos/perspective/releases/tag/v3.3.4'
stackoverflow_data: null
================================================
FILE: copy/tools/plotly.yml
================================================
title: Plotly
description: 'High-level, declarative charting library'
logo: plotly.svg
developer: null
based_on:
- d3
- stackgl
licenses:
- type: open-source
title: MIT
link: 'https://github.com/plotly/plotly.js/blob/master/LICENSE'
types:
- charts
- maps
- 3d
renders:
- svg
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/plotly-1.png
- /images/slider/plotly-2.png
- /images/slider/plotly-3.png
- /images/slider/plotly-4.png
- /images/slider/plotly-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: plotly/plotly.js
npm: plotly.js
npm_types: '@types/plotly.js'
tags:
stackoverflow:
- plotly
- plotly.js
twitter:
- plotly
- plotlyjs
links:
website: 'https://plotly.com/javascript/'
examples: 'https://plotly.com/javascript/'
docs: 'https://www.ag-grid.com/javascript-grid/'
pricing: null
slack: null
content:
- type: official
title: Getting Started in JavaScript
link: 'https://plotly.com/javascript/getting-started/'
github_data:
stars: 17388
contributors: 295
issues: 634
stale_issues: 472
last_release:
date: '2025-02-18T16:55:38Z'
link: 'https://github.com/plotly/plotly.js/releases/tag/v3.0.1'
stackoverflow_data:
questions_count: 15318
================================================
FILE: copy/tools/plottable.yml
================================================
title: Plottable
description: Library of modular chart components built on D3.js
logo: plottable.svg
developer: Palantir
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/palantir/plottable/blob/develop/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: palantir/plottable
npm: plottable
tags:
stackoverflow:
- plottable
twitter:
- aggrid
- ag_grid
links:
website: 'http://plottablejs.org'
examples: 'http://plottablejs.org/examples/'
docs: 'http://plottablejs.org/docs/modules/plottable.html'
pricing: null
slack: null
content:
- type: official
title: Quick Start
link: 'https://github.com/palantir/plottable/blob/develop/README.md#quick-start'
github_data:
stars: 2989
contributors: 85
issues: 305
stale_issues: 305
last_release:
date: '2021-11-22T14:30:28Z'
link: 'https://github.com/palantir/plottable/releases/tag/v3.13.0'
stackoverflow_data:
questions_count: 44
================================================
FILE: copy/tools/pts.yml
================================================
title: Pts
description: Library for visualization and creative-coding
logo: pts.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/williamngan/pts/blob/master/LICENSE'
types:
- low-level
renders:
- svg
- html
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/pts-1.png
- /images/slider/pts-2.png
- /images/slider/pts-3.png
- /images/slider/pts-4.png
- /images/slider/pts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: williamngan/pts
npm: pts
tags:
stackoverflow: null
twitter:
- ptsjs
links:
website: 'https://ptsjs.org'
examples: 'https://ptsjs.org/demo/'
docs: 'https://ptsjs.org/docs/'
pricing: null
slack: null
content:
- type: official
title: Get started with Pts.js
link: 'https://ptsjs.org/guide/get-started-0100'
github_data:
stars: 5225
contributors: 24
issues: 48
stale_issues: 42
last_release:
date: '2022-12-08T09:43:45Z'
link: 'https://github.com/williamngan/pts/releases/tag/v0.11.3'
stackoverflow_data: null
================================================
FILE: copy/tools/react-charts.yml
================================================
title: React Charts
description: 'Simple, immersive & interactive charts for React'
logo: react-charts.svg
developer: null
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/TanStack/react-charts/blob/main/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: TanStack/react-charts
npm: react-charts
tags:
stackoverflow:
- react-charts
twitter:
- ReactCharts
links:
website: 'https://react-charts.tanstack.com'
examples: 'https://react-charts.tanstack.com/examples/simple'
docs: 'https://react-charts.tanstack.com/docs/overview'
pricing: null
slack: null
content:
- type: official
title: Installation
link: 'https://react-charts.tanstack.com/docs/installation'
github_data:
stars: 3043
contributors: 32
issues: 60
stale_issues: 52
last_release:
date: '2023-11-02T22:14:26Z'
link: 'https://github.com/TanStack/react-charts/releases/tag/v3.0.0-beta.57'
stackoverflow_data:
questions_count: 11
================================================
FILE: copy/tools/reaflow.yml
================================================
title: reaflow
description: 'React library for building workflow editors, flow charts, and diagrams'
logo: reaflow.png
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/reaviz/reaflow/blob/master/LICENSE'
types:
- low-level
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/reaflow-1.png
- /images/slider/reaflow-2.png
- /images/slider/reaflow-3.png
- /images/slider/reaflow-4.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: reaviz/reaflow
npm: reaflow
tags:
stackoverflow: null
twitter: null
links:
website: 'https://reaflow.dev'
examples: 'https://reaflow.dev/?path=/story/demos-basic--custom-elements'
docs: 'https://reaflow.dev/?path=/story/docs-introduction--page'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://reaflow.dev/?path=/story/docs-getting-started-installing--page'
github_data:
stars: 2248
contributors: 27
issues: 86
stale_issues: 78
last_release:
date: null
link: null
stackoverflow_data: null
================================================
FILE: copy/tools/reaviz.yml
================================================
title: REAVIZ
description: >-
Modular chart library that leverages React natively while using D3.js under
the hood
logo: reaviz.png
developer: null
based_on:
- d3
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/reaviz/reaviz/blob/master/LICENSE'
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: reaviz/reaviz
npm: reaviz
tags:
stackoverflow: null
twitter: null
links:
website: 'https://reaviz.io'
examples: 'https://reaviz.io/?path=/story/docs-intro--page'
docs: 'https://reaviz.io/?path=/story/docs-intro--page'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://reaviz.io/?path=/story/docs-getting-started-quick-start--page'
github_data:
stars: 1092
contributors: 28
issues: 36
stale_issues: 27
last_release:
date: null
link: null
stackoverflow_data: null
================================================
FILE: copy/tools/recharts.yml
================================================
title: Recharts
description: Composable charting library built on React components
logo: recharts.png
developer: null
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/recharts/recharts/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 1
easy-to-start-with: 3
full-fledged: 0
very-popular: 1
well-documented: 3
gallery:
- /images/slider/recharts-1.png
- /images/slider/recharts-2.png
- /images/slider/recharts-3.png
- /images/slider/recharts-4.png
- /images/slider/recharts-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: recharts/recharts
npm: recharts
tags:
stackoverflow:
- recharts
twitter:
- recharts
links:
website: 'https://recharts.org/en-US/'
examples: 'https://recharts.org/en-US/examples'
docs: 'https://recharts.org/en-US/api'
pricing: null
slack: null
content:
- type: official
title: Getting started
link: 'https://recharts.org/en-US/guide/getting-started'
- type: cube
title: Building a Recharts Dashboard with Cube
link: 'https://cube.dev/blog/building-a-recharts-dashboard-with-cube/'
- type: cube
title: 'React Dashboard: an Ultimate Guide'
link: 'https://react-dashboard.cube.dev'
github_data:
stars: 24690
contributors: 351
issues: 444
stale_issues: 348
last_release:
date: '2025-02-26T04:14:36Z'
link: 'https://github.com/recharts/recharts/releases/tag/v3.0.0-alpha.8'
stackoverflow_data:
questions_count: 783
================================================
FILE: copy/tools/redash.yml
================================================
title: Redash
description: Collaborative visualization and dashboarding platform
logo: redash.svg
developer: null
based_on: null
licenses:
- type: open-source
title: BSD
link: 'https://github.com/getredash/redash/blob/master/LICENSE'
types:
- app
renders: null
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages: null
frameworks: null
slugs:
github: getredash/redash
npm: null
npm_types: null
tags:
stackoverflow:
- redash
twitter:
- redash
links:
website: 'https://redash.io'
examples: 'https://redash.io/help/user-guide/visualizations/visualization-types'
docs: 'https://redash.io/help/open-source/setup'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://redash.io/help/user-guide/getting-started'
github_data:
stars: 27000
contributors: 525
issues: 595
stale_issues: 525
last_release:
date: '2025-01-08T19:06:48Z'
link: 'https://github.com/getredash/redash/releases/tag/v25.1.0'
stackoverflow_data:
questions_count: 138
================================================
FILE: copy/tools/rough.yml
================================================
title: Rough.js
description: 'Graphics library for drawing with a hand-drawn, sketchy appearance'
logo: rough.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/rough-stuff/rough/blob/master/LICENSE'
types:
- low-level
renders:
- svg
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/rough-1.png
- /images/slider/rough-2.png
- /images/slider/rough-3.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- vue
slugs:
github: rough-stuff/rough
npm: roughjs
tags:
stackoverflow: null
twitter:
- roughjs
links:
website: 'https://roughjs.com'
examples: null
docs: 'https://github.com/rough-stuff/rough/wiki'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://roughjs.com'
github_data:
stars: 20139
contributors: 13
issues: 34
stale_issues: 29
last_release:
date: '2019-03-14T19:05:30Z'
link: 'https://github.com/rough-stuff/rough/releases/tag/v3.1.0'
stackoverflow_data: null
================================================
FILE: copy/tools/roughviz.yml
================================================
title: roughViz.js
description: >-
JavaScript library for creating sketchy/hand-drawn styled charts, based on
D3.js, Rough.js, and Handy
logo: roughviz.png
developer: null
based_on:
- d3
- rough
licenses:
- type: open-source
title: MIT
link: 'https://github.com/jwilber/roughViz/blob/master/LICENSE'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/roughviz-1.png
- /images/slider/roughviz-2.png
languages:
- JavaScript
frameworks:
- vanilla-js
- react
- vue
slugs:
github: jwilber/roughViz
npm: rough-viz
tags:
stackoverflow: null
twitter:
- roughViz
links:
website: null
examples: null
docs: 'https://github.com/jwilber/roughViz#api'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://github.com/jwilber/roughViz#installation'
github_data:
stars: 6762
contributors: 16
issues: 10
stale_issues: 10
last_release:
date: null
link: null
stackoverflow_data: null
================================================
FILE: copy/tools/semiotic.yml
================================================
title: Semiotic
description: Data visualization framework for React
logo: semiotic.png
developer: null
based_on:
- d3
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/nteract/semiotic/blob/master/LICENSE'
types:
- low-level
renders:
- svg
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/semiotic-1.png
- /images/slider/semiotic-2.png
- /images/slider/semiotic-3.png
- /images/slider/semiotic-4.png
- /images/slider/semiotic-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: nteract/semiotic
npm: semiotic
tags:
stackoverflow:
- semiotic
twitter: null
links:
website: 'https://semiotic.nteract.io'
examples: 'https://semiotic.nteract.io/examples'
docs: 'https://semiotic.nteract.io/api'
pricing: null
slack: null
content: null
github_data:
stars: 2444
contributors: 31
issues: 33
stale_issues: 33
last_release:
date: '2020-01-21T03:13:12Z'
link: 'https://github.com/nteract/semiotic/releases/tag/v1.20.5'
stackoverflow_data:
questions_count: 4
================================================
FILE: copy/tools/stackgl.yml
================================================
title: stackgl
description: Open software ecosystem for WebGL
logo: stackgl.svg
developer: null
based_on: null
licenses: null
types:
- low-level
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/stackgl-1.jpg
- /images/slider/stackgl-2.jpg
- /images/slider/stackgl-3.jpg
- /images/slider/stackgl-4.jpg
- /images/slider/stackgl-5.jpg
languages:
- JavaScript
frameworks:
- vanilla-js
slugs:
github: stackgl/shader-school
tags:
stackoverflow: null
twitter: null
links:
website: 'http://stack.gl'
examples: 'http://stack.gl/#examples'
docs: 'http://stack.gl/packages/'
pricing: null
slack: null
content: null
github_data:
stars: 4342
contributors: 22
issues: 44
stale_issues: 44
last_release:
date: null
link: null
stackoverflow_data: null
================================================
FILE: copy/tools/superset.yml
================================================
title: Apache Superset
description: Modern data exploration and visualization platform
logo: superset.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/apache/superset/blob/master/LICENSE.txt'
types:
- app
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/superset-1.png
- /images/slider/superset-2.png
- /images/slider/superset-3.png
- /images/slider/superset-4.png
- /images/slider/superset-5.png
languages: null
frameworks: null
slugs:
github: apache/superset
tags:
stackoverflow:
- superset
- apache-superset
twitter:
- ApacheSuperset
links:
website: 'https://superset.apache.org'
examples: 'https://superset.apache.org/gallery'
docs: 'https://superset.apache.org/docs/intro'
pricing: null
slack: >-
https://apache-superset.slack.com/join/shared_invite/zt-l5f5e0av-fyYu8tlfdqbMdz_sPLwUqQ
content:
- type: official
title: What is Apache Superset?
link: 'https://superset.apache.org/docs/intro'
- type: cube
title: Building a metrics dashboard with Superset and Cube
link: 'https://cube.dev/blog/building-metrics-dashboard-with-superset/'
github_data:
stars: 64736
contributors: 1275
issues: 766
stale_issues: 203
last_release:
date: '2025-02-04T19:04:37Z'
link: 'https://github.com/apache/superset/releases/tag/5.0.0rc1'
stackoverflow_data:
questions_count: 1417
================================================
FILE: copy/tools/three.yml
================================================
title: three.js
description: JavaScript 3D library
logo: threejs.svg
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/mrdoob/three.js/blob/dev/LICENSE'
types:
- 3d
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 1
well-documented: 0
gallery:
- /images/slider/three-1.jpg
- /images/slider/three-2.jpg
- /images/slider/three-3.jpg
- /images/slider/three-4.jpg
- /images/slider/three-5.jpg
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: mrdoob/three.js
npm: three
npm_types: '@types/three'
tags:
stackoverflow:
- three.js
twitter:
- threejs
links:
website: 'https://threejs.org'
examples: 'https://threejs.org/examples/#webgl_animation_cloth'
docs: 'https://threejs.org/docs/index.html'
pricing: null
slack: null
content:
- type: official
title: Creating a scene in three.js
link: >-
https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene
github_data:
stars: 104617
contributors: 2359
issues: 428
stale_issues: 296
last_release:
date: '2025-02-27T09:33:44Z'
link: 'https://github.com/mrdoob/three.js/releases/tag/r174'
stackoverflow_data:
questions_count: 21272
================================================
FILE: copy/tools/toast-ui-chart.yml
================================================
title: TOAST UI Chart
description: Beautiful chart for data visualization
logo: toast-ui-chart.png
developer: null
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/nhn/tui.chart/blob/main/LICENSE'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- vue
slugs:
github: nhn/tui.chart
npm: tui-chart
tags:
stackoverflow:
- toast-ui-chart
twitter: null
links:
website: 'https://ui.toast.com/tui-chart'
examples: >-
https://nhn.github.io/tui.chart/latest/tutorial-example01-01-area-chart-basic
docs: 'https://nhn.github.io/tui.chart/latest/'
pricing: null
slack: null
content:
- type: official
title: Getting Started
link: 'https://github.com/nhn/tui.chart/blob/main/docs/en/getting-started.md'
github_data:
stars: 5363
contributors: 12
issues: 19
stale_issues: 15
last_release:
date: '2022-12-21T03:06:57Z'
link: 'https://github.com/nhn/tui.chart/releases/tag/v4.6.1'
stackoverflow_data:
questions_count: 2
================================================
FILE: copy/tools/unovis.yml
================================================
title: Unovis
description: >-
Modular data visualization framework for React, Angular, Svelte, and vanilla
TypeScript or JavaScript
logo: unovis.svg
developer: null
based_on:
- d3
- leaflet
- maplibre
licenses:
- type: open-source
title: Apache-2.0
link: 'https://github.com/f5/unovis/blob/main/LICENSE'
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 1
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 1
gallery:
- /images/slider/unovis-1.png
- /images/slider/unovis-2.png
- /images/slider/unovis-3.png
- /images/slider/unovis-4.png
- /images/slider/unovis-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- svelte
slugs:
github: f5/unovis
npm: '@unovis'
tags:
stackoverflow:
- unovis
twitter:
- unovisdev
links:
website: 'https://unovis.dev'
examples: 'https://unovis.dev/gallery'
docs: 'https://unovis.dev/docs'
pricing: null
content:
- type: official
title: Quick Start Guide
link: 'https://unovis.dev/docs/quick-start'
github_data:
stars: 2384
contributors: 14
issues: 52
stale_issues: 11
last_release:
date: '2025-02-19T18:33:01Z'
link: 'https://github.com/f5/unovis/releases/tag/1.5.1'
stackoverflow_data:
questions_count: 0
================================================
FILE: copy/tools/vega-lite.yml
================================================
title: Vega-Lite
description: 'Concise grammar of interactive graphics, built on Vega'
logo: vega-lite.svg
developer: null
based_on:
- vega
licenses:
- type: open-source
title: BSD
link: 'https://github.com/vega/vega-lite/blob/master/LICENSE'
types:
- low-level
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/vega-lite-1.png
- /images/slider/vega-lite-2.png
- /images/slider/vega-lite-3.png
- /images/slider/vega-lite-4.png
- /images/slider/vega-lite-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
slugs:
github: vega/vega-lite
npm: vega-lite
tags:
stackoverflow:
- vega-lite
twitter:
- vegalite
links:
website: 'https://vega.github.io/vega-lite/'
examples: 'https://vega.github.io/vega-lite/examples/'
docs: 'https://vega.github.io/vega-lite/docs/'
pricing: null
slack: 'https://bit.ly/join-vega-slack-2020'
content:
- type: official
title: Introduction to Vega-Lite
link: 'https://vega.github.io/vega-lite/tutorials/getting_started.html'
github_data:
stars: 4774
contributors: 213
issues: 708
stale_issues: 637
last_release:
date: '2024-12-10T17:38:11Z'
link: 'https://github.com/vega/vega-lite/releases/tag/v5.23.0'
stackoverflow_data:
questions_count: 1552
================================================
FILE: copy/tools/vega.yml
================================================
title: Vega
description: >-
Visualization grammar, a declarative language for creating and sharing
visualization designs
logo: vega.svg
developer: null
based_on:
- d3
licenses:
- type: open-source
title: BSD
link: 'https://github.com/vega/vega/blob/master/LICENSE'
types:
- low-level
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/vega-1.png
- /images/slider/vega-2.png
- /images/slider/vega-3.png
- /images/slider/vega-4.png
- /images/slider/vega-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
slugs:
github: vega/vega
npm: vega
tags:
stackoverflow:
- vega
twitter:
- vegajs
links:
website: 'https://vega.github.io/vega/'
examples: 'https://vega.github.io/vega/examples/'
docs: 'https://vega.github.io/vega/docs/'
pricing: null
slack: 'https://bit.ly/join-vega-slack-2020'
content:
- type: official
title: Let's Make a Bar Chart
link: 'https://vega.github.io/vega/tutorials/bar-chart/'
github_data:
stars: 11384
contributors: 156
issues: 445
stale_issues: 407
last_release:
date: '2025-02-28T02:48:35Z'
link: 'https://github.com/vega/vega/releases/tag/v5.32.0'
stackoverflow_data:
questions_count: 1077
================================================
FILE: copy/tools/victory.yml
================================================
title: Victory
description: React components for modular charting and data visualization
logo: victory.png
developer: Formidable
based_on: null
licenses:
- type: open-source
title: MIT
link: 'https://github.com/FormidableLabs/victory/blob/main/LICENSE.txt'
types:
- charts
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/victory-1.png
- /images/slider/victory-2.png
- /images/slider/victory-3.png
- /images/slider/victory-4.png
- /images/slider/victory-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: FormidableLabs/victory
npm: victory
tags:
stackoverflow:
- victory-charts
- victory-native
twitter:
- VictoryCharts
links:
website: 'https://formidable.com/open-source/victory/'
examples: 'https://formidable.com/open-source/victory/gallery'
docs: 'https://formidable.com/open-source/victory/docs'
pricing: null
slack: null
content:
- type: official
title: Getting Started with Victory
link: 'https://formidable.com/open-source/victory/docs'
- type: cube
title: React Native Charts with Cube.js and Victory
link: 'https://cube.dev/blog/react-native-charts-with-cubejs-victory/'
github_data:
stars: 11096
contributors: 247
issues: 91
stale_issues: 66
last_release:
date: '2025-01-14T17:23:54Z'
link: 'https://github.com/FormidableLabs/victory/releases/tag/v37.3.6'
stackoverflow_data:
questions_count: 306
================================================
FILE: copy/tools/vis.yml
================================================
title: vis.js
description: Dynamic visualization library
logo: visjs.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/visjs/vis-charts/blob/master/LICENSE-APACHE-2.0'
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/vis-1.png
- /images/slider/vis-2.png
- /images/slider/vis-3.png
- /images/slider/vis-4.png
- /images/slider/vis-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
slugs:
github: visjs/vis-charts
npm: vis-charts
npm_types: '@types/vis'
tags:
stackoverflow:
- vis.js
twitter:
- visjs
links:
website: 'https://visjs.org'
examples: 'https://visjs.github.io/vis-timeline/examples/graph2d/'
docs: 'https://visjs.github.io/vis-timeline/docs/graph2d/'
pricing: null
slack: null
content: null
github_data:
stars: 113
contributors: 43
issues: 0
stale_issues: 0
last_release:
date: '2020-05-17T12:03:36Z'
link: 'https://github.com/visjs/vis-charts/releases/tag/v3.0.0'
stackoverflow_data:
questions_count: 795
================================================
FILE: copy/tools/visx.yml
================================================
title: visx
description: 'Collection of expressive, low-level visualization primitives for React'
logo: visx.png
developer: Airbnb
based_on:
- d3
licenses:
- type: open-source
title: MIT
link: 'https://github.com/airbnb/visx/blob/master/LICENSE'
types:
- low-level
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/visx-1.png
- /images/slider/visx-2.png
- /images/slider/visx-3.png
- /images/slider/visx-4.png
- /images/slider/visx-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- react
slugs:
github: airbnb/visx
npm: '@visxx/visx'
tags:
stackoverflow: null
twitter: null
links:
website: 'https://airbnb.io/visx/'
examples: 'https://airbnb.io/visx/gallery'
docs: 'https://airbnb.io/visx/docs'
pricing: null
slack: null
content:
- type: official
title: Getting started with vx
link: 'https://medium.com/vx-code/getting-started-with-vx-1756bb661410'
- type: cube
title: Building a visx Dashboard with Cube
link: 'https://cube.dev/blog/building-a-visx-dashboard-with-cube'
github_data:
stars: 19799
contributors: 177
issues: 126
stale_issues: 106
last_release:
date: '2024-11-07T18:38:04Z'
link: 'https://github.com/airbnb/visx/releases/tag/v3.12.0'
stackoverflow_data: null
================================================
FILE: copy/tools/vizzu.yml
================================================
title: Vizzu
description: Library for animated data visualizations and data stories
logo: vizzu.svg
developer: null
based_on: null
licenses:
- type: open-source
title: Apache 2.0
link: 'https://github.com/vizzuhq/vizzu-lib/blob/main/LICENSE'
types:
- charts
renders:
- canvas
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery: []
languages:
- JavaScript
frameworks:
- vanilla-js
slugs:
github: vizzuhq/vizzu-lib
npm: vizzu
tags:
stackoverflow: null
twitter:
- Vizzu
links:
website: 'https://vizzuhq.com'
examples: 'https://lib.vizzuhq.com/0.3.0/#examples-1.0'
docs: 'https://lib.vizzuhq.com/0.3.0/'
pricing: null
slack: >-
https://join.slack.com/t/vizzu-community/shared_invite/zt-w2nqhq44-2CCWL4o7qn2Ns1EFSf9kEg
content:
- type: official
title: Getting Started
link: 'https://lib.vizzuhq.com/0.3.0/'
github_data:
stars: 1954
contributors: 14
issues: 2
stale_issues: 2
last_release:
date: '2025-02-24T19:33:42Z'
link: 'https://github.com/vizzuhq/vizzu-lib/releases/tag/v0.16.1'
stackoverflow_data: null
================================================
FILE: copy/tools/zingchart.yml
================================================
title: ZingChart
description: >-
Declarative, efficient, and simple JavaScript library for building responsive
charts
logo: zingchart.png
developer: null
based_on: null
licenses:
- type: proprietary
types:
- charts
- maps
renders:
- svg
features:
easy-to-customize: 0
easy-to-start-with: 0
full-fledged: 0
very-popular: 0
well-documented: 0
gallery:
- /images/slider/zingchart-1.png
- /images/slider/zingchart-2.png
- /images/slider/zingchart-3.png
- /images/slider/zingchart-4.png
- /images/slider/zingchart-5.png
languages:
- JavaScript
- TypeScript
frameworks:
- vanilla-js
- react
- angular
- vue
slugs:
github: zingchart/ZingChart
npm: zingchart
npm_types: '@types/zingchart'
tags:
stackoverflow:
- zingchart
twitter:
- ZingChart
links:
website: 'https://www.zingchart.com'
examples: 'https://www.zingchart.com/gallery?type=chartType'
docs: 'https://www.zingchart.com/docs'
pricing: 'https://www.zingchart.com/pricing'
slack: null
content:
- type: official
title: Your First JavaScript Chart
link: 'https://www.zingchart.com/docs/getting-started/your-first-javascript-chart'
github_data:
stars: 277
contributors: 23
issues: 0
stale_issues: 0
last_release:
date: '2025-01-16T18:07:36Z'
link: 'https://github.com/zingchart/ZingChart/releases/tag/2.9.16-1'
stackoverflow_data:
questions_count: 259
================================================
FILE: data/filter.js
================================================
const filter = (tools, framework, language, license, render, exploreTools) => {
const filtered = tools.filter((tool) => {
let isValid = true;
if (exploreTools.length && isValid) {
isValid = hasTypes(tool, exploreTools);
}
if (framework.length && isValid) {
isValid = isCompatibleWith(tool, framework);
}
if (language.length && isValid) {
let hasInclude = 0;
tool?.languages?.forEach((lg) => {
if (language.includes(lg.toLowerCase())) {
hasInclude++;
}
});
isValid = language.length === hasInclude;
}
if (license.length && isValid) {
isValid = hasLicenses(tool, license);
}
if (render.length && isValid) {
let hasInclude = 0;
tool?.renders?.forEach((obj) => {
if (render.includes(obj.toLowerCase())) {
hasInclude++;
}
});
isValid = render.length === hasInclude;
}
return isValid;
});
const maxFeatureScores = getMaxFeatureScores(tools);
const maxFeatureScoresCopy = Object.assign({}, maxFeatureScores);
return filtered
.map((tool) => {
const feature_label = getFeatureWithMaxScore(tool, maxFeatureScores);
if (feature_label) {
delete maxFeatureScores[feature_label];
}
return {
...tool,
feature_label,
};
})
.sort(getComparator(maxFeatureScoresCopy));
};
function getComparator(maxFeatureScores) {
return function (a, b) {
// Adding 1,000,000 to the number of GitHub stars is going to pull the tool up to the top.
// As of 2021-06-01, freeCodeCamp/freeCodeCamp has 325,000 stars
const aSortKey =
(a.feature_label ? 1000000 : 0) + (a.github_data?.stars || 0);
const bSortKey =
(b.feature_label ? 1000000 : 0) + (b.github_data?.stars || 0);
return bSortKey - aSortKey;
};
}
function getMaxFeatureScores(tools) {
return tools.reduce((features, tool) => {
if (tool.features) {
Object.entries(tool.features)
.filter(([_, score]) => score !== 0)
.forEach(([feature, score]) => {
features[feature] =
features[feature] !== undefined
? Math.max(features[feature], score)
: score;
});
}
return features;
}, {});
}
function getFeatureWithMaxScore(tool, maxFeatureScores) {
if (tool.features) {
return Object.entries(tool.features)
.sort((a, b) => b[1] - a[1])
.filter(([_, score]) => score !== 0)
.reduce((selectMaxFeature, [feature, score]) => {
return (
selectMaxFeature ||
Object.entries(maxFeatureScores).find(
([maxFeature, maxScore]) =>
feature === maxFeature && score === maxScore
)?.[0]
);
}, undefined);
}
return false;
}
const setParamsFromRouter = (
query,
setExploreTools,
setFramework,
setLanguage,
setLicense
) => {
if (query.tools) {
setExploreTools(
typeof query.tools === "string" ? [query.tools] : [...query.tools]
);
}
if (query.framework) {
setFramework(
typeof query.framework === "string"
? [query.framework]
: [...query.framework]
);
}
if (query.language) {
setLanguage(
typeof query.language === "string"
? [query.language]
: [...query.language]
);
}
if (query.license) {
setLicense(
typeof query.license === "string" ? [query.license] : [...query.license]
);
}
};
function hasTypes(tool, types) {
return types.every(t => tool?.types?.some(type => type === t.toLowerCase()))
}
function isCompatibleWith(tool, frameworks) {
return frameworks.every(fw => tool?.frameworks?.some(framework => framework === fw.toLowerCase()))
}
function hasLicenses(tool, licenses) {
return licenses.every(l => tool?.licenses?.some(license => license.type === l.toLowerCase()))
}
export { filter, setParamsFromRouter, hasTypes, isCompatibleWith, hasLicenses };
================================================
FILE: data/frameworks.js
================================================
export default {
react: {
slug: "react",
name: "React",
icon: "react.svg",
},
angular: {
slug: "angular",
name: "Angular",
icon: "angular.svg",
},
vue: {
slug: "vue",
name: "Vue",
icon: "vue.svg",
},
svelte: {
slug: "svelte",
name: "Svelte",
icon: "svelte.svg",
},
};
================================================
FILE: data/tools.js
================================================
import fs from "fs";
import yaml from "node-yaml";
export const toolCopyPath = `${process.cwd()}/copy/tools`;
async function readTools() {
const files = fs.readdirSync(toolCopyPath);
const ids = files
.filter((filename) => filename.endsWith(".yml"))
.map((filename) => filename.split(".")[0]);
const tools = {};
const extendedTools = {};
for (const id of ids) {
tools[id] = await readTool(id);
}
for (const id of ids) {
extendedTools[id] = await extendTool(tools[id], tools);
}
return extendedTools;
}
export async function readTool(id) {
const tool = await yaml.read(`${toolCopyPath}/${id}.yml`);
return { id, ...tool };
}
async function extendTool(tool, tools) {
const positionsByStars = Object.values(tools)
.map((t) => ({ key: t.id, value: t.github_data?.stars }))
.sort(compare);
tool.positions = {
total: Object.keys(tools).length,
stars:
1 +
positionsByStars.findIndex(
(pair) => pair.value === tool.github_data?.stars
),
};
tool.percentages = {
stale_issues:
tool.github_data?.issues > 0
? 100 *
(
(tool.github_data?.stale_issues || 0) / tool.github_data?.issues
).toFixed(2)
: 0,
};
return tool;
}
function compare(a, b) {
return (b.value || 0) - (a.value || 0);
}
export async function getTools() {
const tools = await readTools();
return Object.values(tools);
}
export async function getTool(id) {
const tools = await readTools();
return tools[id];
}
================================================
FILE: data/types.js
================================================
export default {
charts: {
slug: "charts",
name: "Charting libraries",
image: "chart.svg",
descriptor: "a charting library",
},
"low-level": {
slug: "low-level",
name: "Low-level tools",
image: "lines.svg",
descriptor: "a low-level data visualization library",
},
maps: {
slug: "maps",
name: "Mapping tools",
image: "globe.svg",
descriptor: "a mapping or spatial library",
},
grid: {
slug: "grid",
name: "Data grids",
image: "grid.svg",
descriptor: "a data grid or pivot table library",
},
"3d": {
slug: "3d",
name: "3D tools",
image: "3d.svg",
descriptor: "a 3D visualization library",
},
app: {
slug: "app",
name: "Exploration apps",
image: "apps.svg",
descriptor: "a data exploration application",
},
};
================================================
FILE: data/useSlackMembers.js
================================================
import { useState, useEffect } from "react";
import fetch from "isomorphic-unfetch";
import abbreviateNumber from "../utils/number";
const cubeUrl = "https://amaranth-leech.gcp-us-central1.cubecloudapp.dev/cubejs-api/v1/load";
const cubeToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEwMDAwMDAwMDAsImV4cCI6NTAwMDAwMDAwMH0.OHZOpOBVKr-sCwn8sbZ5UFsqI3uCs6e4omT7P6WVMFw";
const cubeQuery = {
measures: [
"SlackUsers.count"
]
};
export default function useSlackMembers() {
const [slackMembers, setSlackMembers] = useState(abbreviateNumber(5100));
useEffect(() => {
const url = new URL(cubeUrl);
url.search = new URLSearchParams({
query: JSON.stringify(cubeQuery, null, 2)
}).toString();
const options = {
headers: {
Authorization: cubeToken
},
};
fetch(url, options)
.then((response) => response.json())
.then((response) => response.data[0]["SlackUsers.count"])
.then((count) => setSlackMembers(abbreviateNumber(count)))
.catch(() => {}); // Skip error
}, []);
return slackMembers;
}
================================================
FILE: data-update-worker/.gitignore
================================================
.env
node_modules
================================================
FILE: data-update-worker/fetchData.js
================================================
const fetch = require("node-fetch");
require("dotenv").config();
const getGithubData = async (githubSlug) => {
if (!githubSlug) {
return null;
}
const headers = {
headers: {
Authorization: `token ${process.env.ACCESS_TOKEN_GITHUB}`,
},
};
let repo = null;
let contributors = null;
let releases = null;
let issues = null;
let stale_issues = null;
let stale_date = getStaleDate();
try {
issues = await loadJSON(
`https://api.github.com/search/issues?q=repo:${githubSlug}+type:issue+state:open&per_page=1`,
headers
);
stale_issues = await loadJSON(
`https://api.github.com/search/issues?q=repo:${githubSlug}+type:issue+created:<${stale_date}+state:open&per_page=1`,
headers
);
repo = await loadJSON(
`https://api.github.com/repos/${githubSlug}`,
headers
);
contributors = await loadHeaders(
`https://api.github.com/repos/${githubSlug}/contributors?per_page=1&anon=true`,
headers
);
releases = await loadJSON(
`https://api.github.com/repos/${githubSlug}/releases`,
headers
);
} catch (e) {
throw new Error(e);
}
if (
repo.message ||
releases.message ||
issues.message ||
stale_issues.message ||
contributors.message
) {
throw new Error(
`Bad request: ${
repo.message ||
releases.message ||
issues.message ||
stale_issues.message ||
contributors.message
}`
);
}
return {
stars: repo?.stargazers_count,
contributors: getContributorsByResponseHeaders(contributors),
issues: issues?.total_count,
stale_issues: stale_issues?.total_count,
last_release: {
date: releases?.[0]?.published_at || null,
link: releases?.[0]?.html_url || null,
},
};
};
const getStackoverflowDataByTags = async (tags) => {
if (!tags) {
return null;
}
// const headers = {};
let result = 0;
try {
await asyncForEach(tags, async (tag) => {
const response = await loadJSON(
`https://api.stackexchange.com/2.2/tags?order=desc&sort=popular&inname=${tag}&site=stackoverflow`
);
response?.items?.forEach((item) => {
if (item.name === tag && item.count) {
result += item.count;
}
});
});
} catch (e) {
console.log(e);
throw new Error(e);
}
return {
questions_count: result,
};
};
async function loadJSON(url, headers) {
try {
const res = await fetch(url, headers);
return await res.json();
} catch (e) {
throw new Error(e);
}
}
async function loadHeaders(url, headers) {
try {
const res = await fetch(url, headers);
return await res.headers.get("Link");
} catch (e) {
throw new Error(e);
}
}
function getStaleDate() {
var date = new Date();
date.setFullYear(date.getFullYear() - 1);
return date.toISOString().split("T")[0];
}
function getContributorsByResponseHeaders(str) {
if (!str) {
return null;
}
let newStr = str.slice(str.indexOf('rel="next"'));
let start = newStr.indexOf("&page=");
let end = newStr.length - 13;
let result = newStr.slice(start, end);
let numb = result.match(/\d/g);
return parseInt(numb.join(""));
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
exports.getGithubData = getGithubData;
exports.getStackoverflowDataByTags = getStackoverflowDataByTags;
================================================
FILE: data-update-worker/index.js
================================================
const yaml = require("node-yaml");
const fs = require("fs");
const get = require("./fetchData.js");
const { notifySlackUpdateFailures } = require("./notifySlack.js");
const files = fs.readdirSync("../copy/tools");
const ids = files
.filter((filename) => filename.endsWith(".yml"))
.map((filename) => filename.split(".")[0]);
let failures = [];
asyncForEach(ids, async (id) => {
try {
const file = await yaml.read(`../copy/tools/${id}.yml`);
file.github_data = await get.getGithubData(file?.slugs?.github);
file.stackoverflow_data = await get.getStackoverflowDataByTags(
file?.tags?.stackoverflow
);
await yaml.write(`../copy/tools/${id}.yml`, file);
console.log(id, "success");
// sleep
await new Promise((resolve) => setTimeout(resolve, 15000));
} catch (e) {
console.log(`${id}`, e);
failures.push({
id,
error: e,
});
}
}).then(() => {
if (failures.length) {
return notifySlackUpdateFailures(failures);
}
});
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
================================================
FILE: data-update-worker/notifySlack.js
================================================
const fetch = require("node-fetch");
require("dotenv").config();
/**
* @param {Array<any>} blocks
* @returns Promise
*/
const notifySlack = async (blocks) =>
fetch(process.env.SLACK_WEBHOOK_URL, {
method: "POST",
body: JSON.stringify({
blocks,
}),
});
/**
* @param {Array<{ id: string; error: string }>} failures
* @returns Promise
*/
const notifySlackUpdateFailures = async (failures) =>
notifySlack([
{
type: "header",
text: {
type: "plain_text",
text: "⚠️ Failed to update some tools",
emoji: true,
},
},
{
type: "section",
text: {
type: "mrkdwn",
text: `<${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}|GitHub Run>`,
},
},
...failures.map((failure) => ({
type: "section",
text: {
type: "mrkdwn",
text: `*${failure.id}:*\n${failure.error}`,
},
})),
]);
exports.notifySlack = notifySlack;
exports.notifySlackUpdateFailures = notifySlackUpdateFailures;
================================================
FILE: data-update-worker/package.json
================================================
{
"name": "job",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"dotenv": "^10.0.0",
"fs": "^0.0.1-security",
"js-yaml": "^4.1.0",
"node-fetch": "^2.6.1"
}
}
================================================
FILE: netlify.toml
================================================
[build]
publish = ".next"
================================================
FILE: next-sitemap.config.js
================================================
/** @type {import('next-sitemap').IConfig} */
module.exports = {
siteUrl: process.env.SITE_URL || "https://awesome.cube.dev/",
generateRobotsTxt: true, // (optional)
};
================================================
FILE: next.config.js
================================================
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
});
const ContentSecurityPolicy = `
default-src 'self';
script-src 'report-sample' 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'report-sample' 'self' 'unsafe-inline';
object-src 'none';
base-uri 'self';
connect-src 'self' https://amaranth-leech.gcp-us-central1.cubecloudapp.dev https://track.cube.dev https://graphql.contentful.com;
font-src 'self';
frame-src 'self';
img-src 'self';
manifest-src 'self';
media-src 'self';
worker-src 'none';
`;
/**
* @type {import('next').NextConfig}
*/
const config = {
reactStrictMode: true,
async headers() {
return [
{
source: "/(.*)",
headers: [
{
key: "Strict-Transport-Security",
value: "max-age=31536000; includeSubDomains;",
},
{
key: 'Content-Security-Policy',
value: ContentSecurityPolicy.replace(/\s{2,}/g, ' ').trim(),
}
]
},
]
},
}
module.exports = withBundleAnalyzer(config);
================================================
FILE: package.json
================================================
{
"name": "awesome-dataviz-tools",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"postbuild": "next-sitemap",
"export": "next export",
"start": "next start"
},
"dependencies": {
"@cube-dev/purple-banner": "2.0.19",
"@netlify/plugin-nextjs": "^4.30.3",
"bootstrap": "^5.0.1",
"classnames": "^2.3.2",
"cubedev-tracking": "1.1.0",
"dayjs": "^1.10.7",
"isomorphic-unfetch": "^3.1.0",
"js-yaml": "^3.14.1",
"next": "^13.1.6",
"next-seo": "^5.15.0",
"next-sitemap": "^3.1.49",
"node-yaml": "^4.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-slick": "^0.28.1",
"react-svg": "^13.0.5",
"slick-carousel": "^1.8.1"
},
"devDependencies": {
"@netlify/ne
gitextract_elt7bwjc/
├── .github/
│ └── workflows/
│ └── scheduled-data-update.yml
├── .gitignore
├── .netlify/
│ └── state.json
├── .nvmrc
├── LICENSE
├── README.md
├── components/
│ ├── Button/
│ │ ├── Button.jsx
│ │ ├── Button.module.scss
│ │ └── index.js
│ ├── ButtonLanding/
│ │ ├── ButtonLanding.jsx
│ │ └── ButtonLanding.module.css
│ ├── CTAButtons/
│ │ ├── CTAButtons.jsx
│ │ └── CTAButtons.module.css
│ ├── Card/
│ │ ├── Card.jsx
│ │ └── Card.module.scss
│ ├── Chip/
│ │ ├── Chip.jsx
│ │ ├── Chip.module.scss
│ │ └── index.js
│ ├── ExploreToolsCard/
│ │ ├── ExploreToolsCard.jsx
│ │ ├── ExploreToolsCard.module.scss
│ │ └── index.js
│ ├── Footer/
│ │ ├── Footer.jsx
│ │ ├── Footer.module.scss
│ │ └── index.js
│ ├── Gallery/
│ │ ├── Gallery.jsx
│ │ ├── Gallery.module.scss
│ │ └── index.js
│ ├── GetHelpCard/
│ │ ├── GetHelpCard.jsx
│ │ ├── GetHelpCard.module.scss
│ │ └── index.js
│ ├── GetStartedCard/
│ │ ├── GetStartedCard.jsx
│ │ ├── GetStartedCard.module.scss
│ │ └── index.js
│ ├── GlobalSignUp/
│ │ ├── GlobalSignUp.jsx
│ │ └── GlobalSignUp.module.css
│ ├── Header/
│ │ ├── Header.jsx
│ │ ├── Header.module.scss
│ │ └── index.js
│ ├── ListPage/
│ │ ├── ListPage.jsx
│ │ └── index.js
│ ├── Slider/
│ │ ├── Slider.jsx
│ │ ├── Slider.module.scss
│ │ └── index.js
│ ├── Text/
│ │ ├── AccentedText.jsx
│ │ ├── AccentedText.module.scss
│ │ ├── H1.jsx
│ │ ├── H1.module.scss
│ │ ├── H2.jsx
│ │ └── H2.module.scss
│ ├── ToolCard/
│ │ ├── ToolCard.jsx
│ │ ├── ToolCard.module.scss
│ │ └── index.js
│ ├── ToolPage/
│ │ ├── Description.jsx
│ │ ├── Description.module.scss
│ │ ├── DescriptionCards.jsx
│ │ ├── DescriptionCards.module.scss
│ │ ├── Header.jsx
│ │ ├── Header.module.scss
│ │ ├── HowToGetHelp.jsx
│ │ ├── HowToGetHelp.module.scss
│ │ ├── HowToGetStarted.jsx
│ │ ├── HowToGetStarted.module.scss
│ │ ├── Integrations.jsx
│ │ ├── Integrations.module.scss
│ │ ├── Popularity.jsx
│ │ ├── Popularity.module.scss
│ │ ├── ToolPage.jsx
│ │ └── ToolPageForFramework.jsx
│ └── ToolsNumberControl/
│ ├── ToolsNumberControl.jsx
│ ├── ToolsNumberControl.module.scss
│ └── index.js
├── copy/
│ └── tools/
│ ├── .example
│ ├── .extended.example
│ ├── ag-grid.yml
│ ├── amcharts.yml
│ ├── ant-design-charts.yml
│ ├── anychart.yml
│ ├── apexcharts.yml
│ ├── appsmith.yml
│ ├── billboard.yml
│ ├── c3.yml
│ ├── chartist.yml
│ ├── chartjs.yml
│ ├── cytoscape.yml
│ ├── d3.yml
│ ├── datasette.yml
│ ├── deck-gl.yml
│ ├── echarts.yml
│ ├── flot.yml
│ ├── frappe.yml
│ ├── fusioncharts.yml
│ ├── g2.yml
│ ├── g2plot.yml
│ ├── g6.yml
│ ├── google-charts.yml
│ ├── highcharts.yml
│ ├── kepler-gl.yml
│ ├── laue.yml
│ ├── layer-cake.yml
│ ├── leaflet.yml
│ ├── lightweight-charts.yml
│ ├── mapbox-gl.yml
│ ├── material-ui-data-grid.yml
│ ├── metabase.yml
│ ├── muze.yml
│ ├── ngx-charts.yml
│ ├── nivo.yml
│ ├── observable-plot.yml
│ ├── p5.yml
│ ├── pancake.yml
│ ├── perspective.yml
│ ├── plotly.yml
│ ├── plottable.yml
│ ├── pts.yml
│ ├── react-charts.yml
│ ├── reaflow.yml
│ ├── reaviz.yml
│ ├── recharts.yml
│ ├── redash.yml
│ ├── rough.yml
│ ├── roughviz.yml
│ ├── semiotic.yml
│ ├── stackgl.yml
│ ├── superset.yml
│ ├── three.yml
│ ├── toast-ui-chart.yml
│ ├── unovis.yml
│ ├── vega-lite.yml
│ ├── vega.yml
│ ├── victory.yml
│ ├── vis.yml
│ ├── visx.yml
│ ├── vizzu.yml
│ └── zingchart.yml
├── data/
│ ├── filter.js
│ ├── frameworks.js
│ ├── tools.js
│ ├── types.js
│ └── useSlackMembers.js
├── data-update-worker/
│ ├── .gitignore
│ ├── fetchData.js
│ ├── index.js
│ ├── notifySlack.js
│ └── package.json
├── netlify.toml
├── next-sitemap.config.js
├── next.config.js
├── package.json
├── pages/
│ ├── _app.js
│ ├── _document.js
│ ├── for/
│ │ ├── [framework]/
│ │ │ ├── charting-libraries.js
│ │ │ └── index.js
│ │ └── open-source.js
│ ├── index.js
│ └── tools/
│ └── [id]/
│ ├── [framework].js
│ └── index.js
├── public/
│ ├── browserconfig.xml
│ ├── robots.txt
│ ├── site.webmanifest
│ ├── sitemap-0.xml
│ └── sitemap.xml
├── styles/
│ ├── _variables.scss
│ ├── globals.scss
│ └── indexPage.scss
├── update-copy.sh
└── utils/
├── number.js
└── tracking.js
SYMBOL INDEX (70 symbols across 41 files)
FILE: components/Button/Button.jsx
function Button (line 4) | function Button(props) {
FILE: components/Card/Card.jsx
function Card (line 4) | function Card(props) {
FILE: components/Chip/Chip.jsx
function Chip (line 3) | function Chip(props) {
FILE: components/ExploreToolsCard/ExploreToolsCard.jsx
function ExploreToolsCard (line 4) | function ExploreToolsCard(props) {
FILE: components/Footer/Footer.jsx
function Footer (line 4) | function Footer() {
FILE: components/Gallery/Gallery.jsx
function Gallery (line 6) | function Gallery(props) {
FILE: components/GetHelpCard/GetHelpCard.jsx
function Card (line 4) | function Card(props) {
FILE: components/GetStartedCard/GetStartedCard.jsx
function Card (line 4) | function Card(props) {
FILE: components/Header/Header.jsx
function Header (line 5) | function Header() {
FILE: components/ListPage/ListPage.jsx
function ListPage (line 15) | function ListPage({
function clearFilters (line 218) | function clearFilters(arrayOfFunctions) {
FILE: components/Slider/Slider.jsx
function getSettingsThumbs (line 11) | function getSettingsThumbs(slidesToShow) {
function App (line 23) | function App(props) {
FILE: components/Text/AccentedText.jsx
function AccentedText (line 3) | function AccentedText(props) {
FILE: components/Text/H1.jsx
function H1 (line 3) | function H1(props) {
FILE: components/Text/H2.jsx
function H2 (line 3) | function H2(props) {
FILE: components/ToolCard/ToolCard.jsx
function ToolCard (line 9) | function ToolCard(props) {
function getShadowByLabel (line 138) | function getShadowByLabel(label) {
FILE: components/ToolPage/Description.jsx
function Description (line 3) | function Description(props) {
FILE: components/ToolPage/DescriptionCards.jsx
function DescriptionCards (line 104) | function DescriptionCards(props) {
function capitalizeFirstLetter (line 126) | function capitalizeFirstLetter(string) {
FILE: components/ToolPage/Header.jsx
function Header (line 4) | function Header(props) {
FILE: components/ToolPage/HowToGetHelp.jsx
function HowToGetHelp (line 6) | function HowToGetHelp(props) {
FILE: components/ToolPage/HowToGetStarted.jsx
function HowToGetStarted (line 5) | function HowToGetStarted(props) {
FILE: components/ToolPage/Integrations.jsx
function Integrations (line 6) | function Integrations(props) {
FILE: components/ToolPage/Popularity.jsx
function Popularity (line 7) | function Popularity(props) {
FILE: components/ToolPage/ToolPage.jsx
function ToolPage (line 17) | function ToolPage(props) {
FILE: components/ToolPage/ToolPageForFramework.jsx
function ToolPageForFramework (line 18) | function ToolPageForFramework(props) {
FILE: components/ToolsNumberControl/ToolsNumberControl.jsx
function ToolsNumberControl (line 3) | function ToolsNumberControl(props) {
FILE: data-update-worker/fetchData.js
function loadJSON (line 102) | async function loadJSON(url, headers) {
function loadHeaders (line 110) | async function loadHeaders(url, headers) {
function getStaleDate (line 119) | function getStaleDate() {
function getContributorsByResponseHeaders (line 126) | function getContributorsByResponseHeaders(str) {
function asyncForEach (line 138) | async function asyncForEach(array, callback) {
FILE: data-update-worker/index.js
function asyncForEach (line 40) | async function asyncForEach(array, callback) {
FILE: data/filter.js
function getComparator (line 54) | function getComparator(maxFeatureScores) {
function getMaxFeatureScores (line 67) | function getMaxFeatureScores(tools) {
function getFeatureWithMaxScore (line 84) | function getFeatureWithMaxScore(tool, maxFeatureScores) {
function hasTypes (line 136) | function hasTypes(tool, types) {
function isCompatibleWith (line 140) | function isCompatibleWith(tool, frameworks) {
function hasLicenses (line 144) | function hasLicenses(tool, licenses) {
FILE: data/tools.js
function readTools (line 6) | async function readTools() {
function readTool (line 26) | async function readTool(id) {
function extendTool (line 31) | async function extendTool(tool, tools) {
function compare (line 58) | function compare(a, b) {
function getTools (line 62) | async function getTools() {
function getTool (line 67) | async function getTool(id) {
FILE: data/useSlackMembers.js
function useSlackMembers (line 14) | function useSlackMembers() {
FILE: next.config.js
method headers (line 25) | async headers() {
FILE: pages/_app.js
function MyApp (line 13) | function MyApp({ Component, pageProps }) {
FILE: pages/_document.js
class MyDocument (line 3) | class MyDocument extends Document {
method render (line 4) | render() {
FILE: pages/for/[framework]/charting-libraries.js
function Page (line 6) | function Page({ tools, framework }) {
function getStaticPaths (line 20) | async function getStaticPaths() {
function getStaticProps (line 31) | async function getStaticProps({ params }) {
FILE: pages/for/[framework]/index.js
function Page (line 6) | function Page({ tools, framework }) {
function getStaticPaths (line 19) | async function getStaticPaths() {
function getStaticProps (line 30) | async function getStaticProps({ params }) {
FILE: pages/for/open-source.js
function Page (line 5) | function Page({ tools }) {
function getStaticProps (line 15) | async function getStaticProps() {
FILE: pages/index.js
function Home (line 6) | function Home({ tools }) {
function getStaticProps (line 23) | async function getStaticProps() {
FILE: pages/tools/[id]/[framework].js
function Tool (line 9) | function Tool(props) {
function getStaticPaths (line 15) | async function getStaticPaths() {
function getStaticProps (line 34) | async function getStaticProps({ params }) {
FILE: pages/tools/[id]/index.js
function Tool (line 7) | function Tool(props) {
function getStaticPaths (line 13) | async function getStaticPaths() {
function getStaticProps (line 31) | async function getStaticProps({ params }) {
FILE: utils/number.js
function abbreviateNumber (line 1) | function abbreviateNumber(value) {
FILE: utils/tracking.js
method init (line 2) | async init() {
Condensed preview — 167 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (264K chars).
[
{
"path": ".github/workflows/scheduled-data-update.yml",
"chars": 1831,
"preview": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versi"
},
{
"path": ".gitignore",
"chars": 420,
"preview": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pn"
},
{
"path": ".netlify/state.json",
"chars": 53,
"preview": "{\n\t\"siteId\": \"51f8094d-998a-424a-b471-6499f5bf2933\"\n}"
},
{
"path": ".nvmrc",
"chars": 5,
"preview": "lts/*"
},
{
"path": "LICENSE",
"chars": 1071,
"preview": "MIT License\n\nCopyright (c) 2021 Cube Dev, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a "
},
{
"path": "README.md",
"chars": 393,
"preview": "<h1><a href='https://awesome.cube.dev'>awesome.cube.dev</a> — charts, data grids, maps, etc.</h1>\n\nChoose the best tool "
},
{
"path": "components/Button/Button.jsx",
"chars": 453,
"preview": "import styles from \"./Button.module.scss\";\nimport Link from \"next/link\";\n\nexport default function Button(props) {\n retu"
},
{
"path": "components/Button/Button.module.scss",
"chars": 890,
"preview": "@import \"/styles/variables\";\n\n.button {\n font-family: CeraPro;\n font-size: 20px;\n // line-height: 25px;\n text-align:"
},
{
"path": "components/Button/index.js",
"chars": 54,
"preview": "import Button from \"./Button\";\nexport default Button;\n"
},
{
"path": "components/ButtonLanding/ButtonLanding.jsx",
"chars": 2998,
"preview": "import * as React from 'react';\nimport { useEffect } from 'react';\nimport Link from 'next/link';\nimport classNames from "
},
{
"path": "components/ButtonLanding/ButtonLanding.module.css",
"chars": 9518,
"preview": ".Button {\n --dark: hsl(240, 32%, 10%);\n --dark_a70: rgba(15, 15, 35, 0.7);\n --dark_01: var(--dark);\n --dark_02: hsla"
},
{
"path": "components/CTAButtons/CTAButtons.jsx",
"chars": 1188,
"preview": "import * as React from 'react';\nimport classnames from 'classnames/bind';\nimport classes from './CTAButtons.module.css';"
},
{
"path": "components/CTAButtons/CTAButtons.module.css",
"chars": 40,
"preview": ".CTAButtons__button {\n color: white;\n}\n"
},
{
"path": "components/Card/Card.jsx",
"chars": 1593,
"preview": "import styles from \"./Card.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Card(props) {\n "
},
{
"path": "components/Card/Card.module.scss",
"chars": 1611,
"preview": "@import \"/styles/variables\";\n\n.card {\n width: 100%;\n padding: 32px;\n border-radius: 24px;\n border: 1px solid $dark-0"
},
{
"path": "components/Chip/Chip.jsx",
"chars": 549,
"preview": "import styles from \"./Chip.module.scss\";\n\nexport default function Chip(props) {\n return (\n <button\n type=\"butto"
},
{
"path": "components/Chip/Chip.module.scss",
"chars": 1069,
"preview": "@import \"/styles/variables\";\n\n.chip {\n font-family: CeraPro;\n border: none;\n padding: 8px 16px;\n background-color: $"
},
{
"path": "components/Chip/index.js",
"chars": 48,
"preview": "import Chip from \"./Chip\";\nexport default Chip;\n"
},
{
"path": "components/ExploreToolsCard/ExploreToolsCard.jsx",
"chars": 808,
"preview": "import styles from \"./ExploreToolsCard.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Expl"
},
{
"path": "components/ExploreToolsCard/ExploreToolsCard.module.scss",
"chars": 1438,
"preview": "@import \"/styles/variables\";\n\n.exploreToolsCard {\n background: $dark-06;\n border: 1px solid $dark-06;\n transition: bo"
},
{
"path": "components/ExploreToolsCard/index.js",
"chars": 84,
"preview": "import ExploreToolsCard from \"./ExploreToolsCard\";\nexport default ExploreToolsCard;\n"
},
{
"path": "components/Footer/Footer.jsx",
"chars": 1235,
"preview": "import styles from \"./Footer.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Footer() {\n r"
},
{
"path": "components/Footer/Footer.module.scss",
"chars": 505,
"preview": "@import \"/styles/variables\";\n\n.footer {\n margin-top: 90px;\n border-top: 2px solid #e7e9ed;\n padding-top: 64px;\n padd"
},
{
"path": "components/Footer/index.js",
"chars": 54,
"preview": "import Footer from \"./Footer\";\nexport default Footer;\n"
},
{
"path": "components/Gallery/Gallery.jsx",
"chars": 677,
"preview": "import dynamic from \"next/dynamic\";\nimport styles from \"./Gallery.module.scss\";\nimport H2 from \"../Text/H2\";\nconst Slide"
},
{
"path": "components/Gallery/Gallery.module.scss",
"chars": 174,
"preview": ".gallery {\n margin-bottom: 104px;\n @media (max-width: 767.98px) {\n margin-bottom: 48px;\n }\n}\n.sliderWrap {\n @medi"
},
{
"path": "components/Gallery/index.js",
"chars": 57,
"preview": "import Gallery from \"./Gallery\";\nexport default Gallery;\n"
},
{
"path": "components/GetHelpCard/GetHelpCard.jsx",
"chars": 716,
"preview": "import styles from \"./GetHelpCard.module.scss\";\nimport Link from \"next/link\";\n\nexport default function Card(props) {\n r"
},
{
"path": "components/GetHelpCard/GetHelpCard.module.scss",
"chars": 657,
"preview": "@import \"/styles/variables\";\n.card {\n box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n transition: box-shadow 0.32s"
},
{
"path": "components/GetHelpCard/index.js",
"chars": 69,
"preview": "import GetHelpCard from \"./GetHelpCard\";\nexport default GetHelpCard;\n"
},
{
"path": "components/GetStartedCard/GetStartedCard.jsx",
"chars": 801,
"preview": "import styles from \"./GetStartedCard.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Card(p"
},
{
"path": "components/GetStartedCard/GetStartedCard.module.scss",
"chars": 610,
"preview": "@import \"/styles/variables\";\n\n.card {\n box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n transition: box-shadow 0.32"
},
{
"path": "components/GetStartedCard/index.js",
"chars": 78,
"preview": "import GetStartedCard from \"./GetStartedCard\";\nexport default GetStartedCard;\n"
},
{
"path": "components/GlobalSignUp/GlobalSignUp.jsx",
"chars": 979,
"preview": "import * as React from 'react';\nimport classnames from 'classnames/bind';\nimport classes from './GlobalSignUp.module.css"
},
{
"path": "components/GlobalSignUp/GlobalSignUp.module.css",
"chars": 3225,
"preview": ".GlobalSignUp {\n background-color: hsl(240, 32%, 10%);\n overflow: hidden;\n position: relative;\n}\n\n.GlobalSignUp::befo"
},
{
"path": "components/Header/Header.jsx",
"chars": 1149,
"preview": "import styles from \"./Header.module.scss\";\nimport { useRouter } from \"next/router\";\nimport Link from \"next/link\";\n\nexpor"
},
{
"path": "components/Header/Header.module.scss",
"chars": 208,
"preview": ".header {\n padding: 24px 0;\n\n &__logo {\n display: flex;\n align-items: center;\n min-height: 28px;\n }\n\n &__te"
},
{
"path": "components/Header/index.js",
"chars": 54,
"preview": "import Header from \"./Header\";\nexport default Header;\n"
},
{
"path": "components/ListPage/ListPage.jsx",
"chars": 6882,
"preview": "import React, { useState, useEffect } from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { useRouter } from \"next/"
},
{
"path": "components/ListPage/index.js",
"chars": 60,
"preview": "import ListPage from \"./ListPage\";\nexport default ListPage;\n"
},
{
"path": "components/Slider/Slider.jsx",
"chars": 2162,
"preview": "// App.js\nimport React, { useState, useEffect } from \"react\";\nimport styles from \"./Slider.module.scss\";\n// import \"./Ap"
},
{
"path": "components/Slider/Slider.module.scss",
"chars": 907,
"preview": ".thumbnailSliderWrap {\n margin-top: 27px;\n // height: 85px;\n @media (max-width: 767.98px) {\n margin-top: 16px;\n }"
},
{
"path": "components/Slider/index.js",
"chars": 54,
"preview": "import Slider from \"./Slider\";\nexport default Slider;\n"
},
{
"path": "components/Text/AccentedText.jsx",
"chars": 295,
"preview": "import styles from \"./AccentedText.module.scss\";\n\nexport default function AccentedText(props) {\n return (\n <span\n "
},
{
"path": "components/Text/AccentedText.module.scss",
"chars": 54,
"preview": ".accented {\n font-size: 24px;\n line-height: 30px;\n}\n"
},
{
"path": "components/Text/H1.jsx",
"chars": 139,
"preview": "import styles from \"./H1.module.scss\";\n\nexport default function H1(props) {\n return <h1 className={styles.title}>{props"
},
{
"path": "components/Text/H1.module.scss",
"chars": 223,
"preview": "@import \"/styles/variables\";\n\n.title {\n font-style: normal;\n font-weight: 700;\n font-size: 64px;\n line-height: 72px;"
},
{
"path": "components/Text/H2.jsx",
"chars": 256,
"preview": "import styles from \"./H2.module.scss\";\n\nexport default function H2(props) {\n return (\n <h2\n {...props}\n cl"
},
{
"path": "components/Text/H2.module.scss",
"chars": 188,
"preview": "@import \"/styles/variables\";\n\n.h2 {\n font-size: 40px;\n line-height: 50px;\n color: $dark;\n margin: 0;\n @media (max-w"
},
{
"path": "components/ToolCard/ToolCard.jsx",
"chars": 5157,
"preview": "import styles from \"./ToolCard.module.scss\";\nimport dayjs from \"dayjs\";\nimport dayjsUtc from \"dayjs/plugin/utc\";\nimport "
},
{
"path": "components/ToolCard/ToolCard.module.scss",
"chars": 3441,
"preview": "@import \"/styles/variables\";\n\n.toolCard {\n cursor: pointer;\n padding: 32px;\n color: $dark;\n background: #ffffff;\n b"
},
{
"path": "components/ToolCard/index.js",
"chars": 60,
"preview": "import ToolCard from \"./ToolCard\";\nexport default ToolCard;\n"
},
{
"path": "components/ToolPage/Description.jsx",
"chars": 508,
"preview": "import styles from \"./Description.module.scss\";\n\nexport default function Description(props) {\n return (\n <div classN"
},
{
"path": "components/ToolPage/Description.module.scss",
"chars": 382,
"preview": "@import \"/styles/variables\";\n\n.description {\n margin-top: 24px;\n &__text {\n font-size: 22px;\n line-height: 28px;"
},
{
"path": "components/ToolPage/DescriptionCards.jsx",
"chars": 3606,
"preview": "import styles from \"./DescriptionCards.module.scss\";\nimport Card from \"../Card/Card\";\n\nconst getLicense = (props) => {\n "
},
{
"path": "components/ToolPage/DescriptionCards.module.scss",
"chars": 221,
"preview": ".descriptionCards {\n margin-top: 40px;\n display: flex;\n margin-bottom: 104px;\n @media (max-width: 767.98px) {\n ma"
},
{
"path": "components/ToolPage/Header.jsx",
"chars": 1391,
"preview": "import styles from \"./Header.module.scss\";\nimport Button from \"../Button\";\n\nexport default function Header(props) {\n re"
},
{
"path": "components/ToolPage/Header.module.scss",
"chars": 1000,
"preview": "@import \"/styles/variables\";\n\n.header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n @med"
},
{
"path": "components/ToolPage/HowToGetHelp.jsx",
"chars": 2066,
"preview": "import styles from \"./HowToGetHelp.module.scss\";\nimport GetHelpCard from \"../GetHelpCard\";\nimport H2 from \"../Text/H2\";\n"
},
{
"path": "components/ToolPage/HowToGetHelp.module.scss",
"chars": 279,
"preview": ".HowToGetHelp {\n margin-bottom: 104px;\n @media (max-width: 767.98px) {\n margin-bottom: 48px;\n }\n}\n.cardWrap {\n ma"
},
{
"path": "components/ToolPage/HowToGetStarted.jsx",
"chars": 1160,
"preview": "import styles from \"./HowToGetStarted.module.scss\";\nimport GetStartedCard from \"../GetStartedCard\";\nimport H2 from \"../T"
},
{
"path": "components/ToolPage/HowToGetStarted.module.scss",
"chars": 143,
"preview": ".HowToGetStarted {\n margin-bottom: 104px;\n}\n.cardWrap {\n margin-bottom: 26px;\n @media (max-width: 991.98px) {\n mar"
},
{
"path": "components/ToolPage/Integrations.jsx",
"chars": 1321,
"preview": "import styles from \"./Integrations.module.scss\";\nimport Card from \"../Card/Card\";\nimport H2 from \"../Text/H2\";\nimport fr"
},
{
"path": "components/ToolPage/Integrations.module.scss",
"chars": 167,
"preview": ".integration {\n margin-bottom: 104px;\n @media (max-width: 767.98px) {\n margin-bottom: 48px;\n }\n}\n.cards {\n displa"
},
{
"path": "components/ToolPage/Popularity.jsx",
"chars": 2183,
"preview": "import styles from \"./Popularity.module.scss\";\nimport Card from \"../Card/Card\";\nimport H2 from \"../Text/H2\";\nimport dayj"
},
{
"path": "components/ToolPage/Popularity.module.scss",
"chars": 256,
"preview": ".popularity {\n margin-bottom: 104px;\n @media (max-width: 767.98px) {\n margin-bottom: 48px;\n }\n}\n.bigCardWrap {\n @"
},
{
"path": "components/ToolPage/ToolPage.jsx",
"chars": 2789,
"preview": "import React from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { NextSeo } from 'next-seo';\nimport Header from \"."
},
{
"path": "components/ToolPage/ToolPageForFramework.jsx",
"chars": 3086,
"preview": "import React from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { NextSeo } from 'next-seo';\nimport Header from \"."
},
{
"path": "components/ToolsNumberControl/ToolsNumberControl.jsx",
"chars": 910,
"preview": "import styles from \"./ToolsNumberControl.module.scss\";\nimport { ReactSVG } from \"react-svg\";\nexport default function Too"
},
{
"path": "components/ToolsNumberControl/ToolsNumberControl.module.scss",
"chars": 849,
"preview": "@import \"/styles/variables\";\n\n.toolsControl {\n min-height: 34px;\n display: flex;\n align-items: center;\n @media (max-"
},
{
"path": "components/ToolsNumberControl/index.js",
"chars": 90,
"preview": "import ToolsNumberControl from \"./ToolsNumberControl\";\nexport default ToolsNumberControl;\n"
},
{
"path": "copy/tools/.example",
"chars": 1630,
"preview": "title: AG Grid\ndescription: Self-proclaimed best JavaScript grid in the world\nlogo: ag-grid.svg\ndeveloper: Google\n\nbased"
},
{
"path": "copy/tools/.extended.example",
"chars": 124,
"preview": "# Everything from .example and also the following fields\n\npositions:\n total: 45\n stars: 3\n\npercentages:\n stale_issues"
},
{
"path": "copy/tools/ag-grid.yml",
"chars": 1457,
"preview": "title: AG Grid\ndescription: Self-proclaimed best JavaScript grid in the world\nlogo: ag-grid.svg\nbased_on: null\nlicenses:"
},
{
"path": "copy/tools/amcharts.yml",
"chars": 1304,
"preview": "title: amCharts\ndescription: JavaScript charts & maps for all data visualization needs\nlogo: amcharts.svg\nbased_on: null"
},
{
"path": "copy/tools/ant-design-charts.yml",
"chars": 1356,
"preview": "title: Ant Design Charts\ndescription: 'React charting library, based on G2Plot, G6, X6, L7'\nlogo: antv.svg\ndeveloper: An"
},
{
"path": "copy/tools/anychart.yml",
"chars": 1450,
"preview": "title: AnyChart\ndescription: Interactive JavaScript charts\nlogo: anychart.svg\ndeveloper: null\nbased_on: null\nlicenses:\n "
},
{
"path": "copy/tools/apexcharts.yml",
"chars": 1407,
"preview": "title: ApexCharts\ndescription: Modern & interactive open-source charts\nlogo: apexcharts.png\ndeveloper: null\nbased_on: nu"
},
{
"path": "copy/tools/appsmith.yml",
"chars": 1448,
"preview": "title: Appsmith\ndescription: Low-code tool for building internal apps using pre-built UI widgets\nlogo: appsmith.svg\ndeve"
},
{
"path": "copy/tools/billboard.yml",
"chars": 1277,
"preview": "title: Billboard.js\ndescription: 'Re-usable, easy interface JavaScript chart library based on D3.js'\nlogo: billboard.svg"
},
{
"path": "copy/tools/c3.yml",
"chars": 1199,
"preview": "title: C3.js\ndescription: D3.js-based reusable chart library\nlogo: c3.svg\ndeveloper: null\nbased_on:\n - d3\nlicenses:\n -"
},
{
"path": "copy/tools/chartist.yml",
"chars": 1396,
"preview": "title: Chartist\ndescription: Simple responsive SVG charts\nlogo: chartist.svg\ndeveloper: null\nbased_on: null\nlicenses:\n "
},
{
"path": "copy/tools/chartjs.yml",
"chars": 2275,
"preview": "title: Chart.js\ndescription: Simple yet flexible JavaScript charting for designers & developers\nlogo: chartjs.svg\ndevelo"
},
{
"path": "copy/tools/cytoscape.yml",
"chars": 1340,
"preview": "title: Cytoscape.js\ndescription: Graph theory (network) library for visualisation and analysis\nlogo: cytoscape.svg\ndevel"
},
{
"path": "copy/tools/d3.yml",
"chars": 1349,
"preview": "title: D3.js\ndescription: JavaScript library for manipulating documents based on data\nlogo: d3.png\ndeveloper: null\nbased"
},
{
"path": "copy/tools/datasette.yml",
"chars": 1226,
"preview": "title: Datasette\ndescription: Open-source multi-tool for exploring and publishing data\nlogo: datasette.svg\ndeveloper: nu"
},
{
"path": "copy/tools/deck-gl.yml",
"chars": 1318,
"preview": "title: deck.gl\ndescription: WebGL-powered visualization framework for large-scale datasets\nlogo: deck-gl.svg\ndeveloper: "
},
{
"path": "copy/tools/echarts.yml",
"chars": 2517,
"preview": "title: Apache ECharts\ndescription: Open-source JavaScript visualization library\nlogo: echarts.png\ndeveloper: null\nbased_"
},
{
"path": "copy/tools/flot.yml",
"chars": 1147,
"preview": "title: Flot\ndescription: Attractive JavaScript charts for jQuery\nlogo: flot.svg\ndeveloper: null\nbased_on: null\nlicenses:"
},
{
"path": "copy/tools/frappe.yml",
"chars": 1106,
"preview": "title: Frappe\ndescription: >-\n GitHub-inspired simple and modern SVG charts for the web with zero\n dependencies\nlogo: "
},
{
"path": "copy/tools/fusioncharts.yml",
"chars": 1572,
"preview": "title: FusionCharts\ndescription: JavaScript charts for web & mobile\nlogo: fusioncharts.svg\ndeveloper: null\nbased_on: nul"
},
{
"path": "copy/tools/g2.yml",
"chars": 1251,
"preview": "title: G2\ndescription: Highly interactive data-driven visualization grammar for statistical charts\nlogo: antv.svg\ndevelo"
},
{
"path": "copy/tools/g2plot.yml",
"chars": 1315,
"preview": "title: G2Plot\ndescription: Interactive and responsive charting library based on the grammar of graphics\nlogo: antv.svg\nd"
},
{
"path": "copy/tools/g6.yml",
"chars": 1196,
"preview": "title: G6\ndescription: Graph visualization engine with simplicity and convenience\nlogo: antv.svg\ndeveloper: AntV\nbased_o"
},
{
"path": "copy/tools/google-charts.yml",
"chars": 1984,
"preview": "title: Google Charts\ndescription: Interactive charts for browsers and mobile devices\nlogo: google-charts.png\ndeveloper: "
},
{
"path": "copy/tools/highcharts.yml",
"chars": 1314,
"preview": "title: Highcharts\ndescription: Modern SVG-based multi-platform charting library\nlogo: highcharts.svg\ndeveloper: null\nbas"
},
{
"path": "copy/tools/kepler-gl.yml",
"chars": 1338,
"preview": "title: Kepler.gl\ndescription: Open-source geospatial analysis tool for large-scale data sets\nlogo: kepler-gl.svg\ndevelop"
},
{
"path": "copy/tools/laue.yml",
"chars": 1130,
"preview": "title: Laue\ndescription: Modern charts for Vue.js\nlogo: laue.svg\ndeveloper: null\nbased_on: null\nlicenses:\n - type: open"
},
{
"path": "copy/tools/layer-cake.yml",
"chars": 1077,
"preview": "title: Layer Cake\ndescription: Graphics framework for Svelte\nlogo: layer-cake.png\ndeveloper: null\nbased_on: null\nlicense"
},
{
"path": "copy/tools/leaflet.yml",
"chars": 1330,
"preview": "title: Leaflet\ndescription: JavaScript library for mobile-friendly interactive maps\nlogo: leafletjs.png\ndeveloper: null\n"
},
{
"path": "copy/tools/lightweight-charts.yml",
"chars": 1604,
"preview": "title: Lightweight Charts\ndescription: Financial lightweight charts built with HTML5 canvas\nlogo: lightweight-charts.svg"
},
{
"path": "copy/tools/mapbox-gl.yml",
"chars": 1544,
"preview": "title: Mapbox GL JS\ndescription: >-\n Interactive, thoroughly customizable maps in the browser, powered by vector\n tile"
},
{
"path": "copy/tools/material-ui-data-grid.yml",
"chars": 1693,
"preview": "title: MUI X Data Grid\ndescription: Fast and extendable data table and data grid for React\nlogo: material-ui.svg\ndevelop"
},
{
"path": "copy/tools/metabase.yml",
"chars": 1570,
"preview": "title: Metabase\ndescription: 'Easy, open-source way to ask questions and learn from data'\nlogo: metabase.png\ndeveloper: "
},
{
"path": "copy/tools/muze.yml",
"chars": 1433,
"preview": "title: Muze\ndescription: Free library for creating exploratory data visualizations using WebAssembly\nlogo: muze.svg\ndeve"
},
{
"path": "copy/tools/ngx-charts.yml",
"chars": 1145,
"preview": "title: ngx-charts\ndescription: Declarative charting framework for Angular\nlogo: ngx-charts.svg\ndeveloper: Swimlane\nbased"
},
{
"path": "copy/tools/nivo.yml",
"chars": 1209,
"preview": "title: nivo\ndescription: Supercharged React components to easily build dataviz apps\nlogo: nivo.png\ndeveloper: null\nbased"
},
{
"path": "copy/tools/observable-plot.yml",
"chars": 1407,
"preview": "title: Observable Plot\ndescription: Concise API for exploratory data visualization\nlogo: observable.png\ndeveloper: null\n"
},
{
"path": "copy/tools/p5.yml",
"chars": 1294,
"preview": "title: p5.js\ndescription: >-\n JavaScript library for creative coding that makes coding accessible and\n inclusive\nlogo:"
},
{
"path": "copy/tools/pancake.yml",
"chars": 1074,
"preview": "title: Pancake\ndescription: 'Responsive charts, JavaScript optional'\nlogo: pancake.png\ndeveloper: null\nbased_on: null\nli"
},
{
"path": "copy/tools/perspective.yml",
"chars": 1460,
"preview": "title: Perspective\ndescription: >-\n Interactive analytics and data visualization component, especially well-suited\n fo"
},
{
"path": "copy/tools/plotly.yml",
"chars": 1413,
"preview": "title: Plotly\ndescription: 'High-level, declarative charting library'\nlogo: plotly.svg\ndeveloper: null\nbased_on:\n - d3\n"
},
{
"path": "copy/tools/plottable.yml",
"chars": 1174,
"preview": "title: Plottable\ndescription: Library of modular chart components built on D3.js\nlogo: plottable.svg\ndeveloper: Palantir"
},
{
"path": "copy/tools/pts.yml",
"chars": 1201,
"preview": "title: Pts\ndescription: Library for visualization and creative-coding\nlogo: pts.svg\ndeveloper: null\nbased_on: null\nlicen"
},
{
"path": "copy/tools/react-charts.yml",
"chars": 1184,
"preview": "title: React Charts\ndescription: 'Simple, immersive & interactive charts for React'\nlogo: react-charts.svg\ndeveloper: nu"
},
{
"path": "copy/tools/reaflow.yml",
"chars": 1217,
"preview": "title: reaflow\ndescription: 'React library for building workflow editors, flow charts, and diagrams'\nlogo: reaflow.png\nd"
},
{
"path": "copy/tools/reaviz.yml",
"chars": 1084,
"preview": "title: REAVIZ\ndescription: >-\n Modular chart library that leverages React natively while using D3.js under\n the hood\nl"
},
{
"path": "copy/tools/recharts.yml",
"chars": 1542,
"preview": "title: Recharts\ndescription: Composable charting library built on React components\nlogo: recharts.png\ndeveloper: null\nba"
},
{
"path": "copy/tools/redash.yml",
"chars": 1118,
"preview": "title: Redash\ndescription: Collaborative visualization and dashboarding platform\nlogo: redash.svg\ndeveloper: null\nbased_"
},
{
"path": "copy/tools/rough.yml",
"chars": 1163,
"preview": "title: Rough.js\ndescription: 'Graphics library for drawing with a hand-drawn, sketchy appearance'\nlogo: rough.png\ndevelo"
},
{
"path": "copy/tools/roughviz.yml",
"chars": 1105,
"preview": "title: roughViz.js\ndescription: >-\n JavaScript library for creating sketchy/hand-drawn styled charts, based on\n D3.js,"
},
{
"path": "copy/tools/semiotic.yml",
"chars": 1173,
"preview": "title: Semiotic\ndescription: Data visualization framework for React\nlogo: semiotic.png\ndeveloper: null\nbased_on:\n - d3\n"
},
{
"path": "copy/tools/stackgl.yml",
"chars": 896,
"preview": "title: stackgl\ndescription: Open software ecosystem for WebGL\nlogo: stackgl.svg\ndeveloper: null\nbased_on: null\nlicenses:"
},
{
"path": "copy/tools/superset.yml",
"chars": 1509,
"preview": "title: Apache Superset\ndescription: Modern data exploration and visualization platform\nlogo: superset.svg\ndeveloper: nul"
},
{
"path": "copy/tools/three.yml",
"chars": 1346,
"preview": "title: three.js\ndescription: JavaScript 3D library\nlogo: threejs.svg\ndeveloper: null\nbased_on: null\nlicenses:\n - type: "
},
{
"path": "copy/tools/toast-ui-chart.yml",
"chars": 1196,
"preview": "title: TOAST UI Chart\ndescription: Beautiful chart for data visualization\nlogo: toast-ui-chart.png\ndeveloper: null\nbased"
},
{
"path": "copy/tools/unovis.yml",
"chars": 1322,
"preview": "title: Unovis\ndescription: >-\n Modular data visualization framework for React, Angular, Svelte, and vanilla\n TypeScrip"
},
{
"path": "copy/tools/vega-lite.yml",
"chars": 1388,
"preview": "title: Vega-Lite\ndescription: 'Concise grammar of interactive graphics, built on Vega'\nlogo: vega-lite.svg\ndeveloper: nu"
},
{
"path": "copy/tools/vega.yml",
"chars": 1335,
"preview": "title: Vega\ndescription: >-\n Visualization grammar, a declarative language for creating and sharing\n visualization des"
},
{
"path": "copy/tools/victory.yml",
"chars": 1542,
"preview": "title: Victory\ndescription: React components for modular charting and data visualization\nlogo: victory.png\ndeveloper: Fo"
},
{
"path": "copy/tools/vis.yml",
"chars": 1201,
"preview": "title: vis.js\ndescription: Dynamic visualization library\nlogo: visjs.svg\ndeveloper: null\nbased_on: null\nlicenses:\n - ty"
},
{
"path": "copy/tools/visx.yml",
"chars": 1374,
"preview": "title: visx\ndescription: 'Collection of expressive, low-level visualization primitives for React'\nlogo: visx.png\ndevelop"
},
{
"path": "copy/tools/vizzu.yml",
"chars": 1147,
"preview": "title: Vizzu\ndescription: Library for animated data visualizations and data stories\nlogo: vizzu.svg\ndeveloper: null\nbase"
},
{
"path": "copy/tools/zingchart.yml",
"chars": 1402,
"preview": "title: ZingChart\ndescription: >-\n Declarative, efficient, and simple JavaScript library for building responsive\n chart"
},
{
"path": "data/filter.js",
"chars": 3968,
"preview": "const filter = (tools, framework, language, license, render, exploreTools) => {\n const filtered = tools.filter((tool) ="
},
{
"path": "data/frameworks.js",
"chars": 331,
"preview": "export default {\n react: {\n slug: \"react\",\n name: \"React\",\n icon: \"react.svg\",\n },\n angular: {\n slug: \"an"
},
{
"path": "data/tools.js",
"chars": 1536,
"preview": "import fs from \"fs\";\nimport yaml from \"node-yaml\";\n\nexport const toolCopyPath = `${process.cwd()}/copy/tools`;\n\nasync fu"
},
{
"path": "data/types.js",
"chars": 826,
"preview": "export default {\n charts: {\n slug: \"charts\",\n name: \"Charting libraries\",\n image: \"chart.svg\",\n descriptor:"
},
{
"path": "data/useSlackMembers.js",
"chars": 1085,
"preview": "import { useState, useEffect } from \"react\";\nimport fetch from \"isomorphic-unfetch\";\nimport abbreviateNumber from \"../ut"
},
{
"path": "data-update-worker/.gitignore",
"chars": 17,
"preview": ".env\nnode_modules"
},
{
"path": "data-update-worker/fetchData.js",
"chars": 3492,
"preview": "const fetch = require(\"node-fetch\");\nrequire(\"dotenv\").config();\n\nconst getGithubData = async (githubSlug) => {\n if (!g"
},
{
"path": "data-update-worker/index.js",
"chars": 1154,
"preview": "const yaml = require(\"node-yaml\");\nconst fs = require(\"fs\");\nconst get = require(\"./fetchData.js\");\nconst { notifySlackU"
},
{
"path": "data-update-worker/notifySlack.js",
"chars": 1087,
"preview": "const fetch = require(\"node-fetch\");\nrequire(\"dotenv\").config();\n\n/**\n * @param {Array<any>} blocks \n * @returns Promise"
},
{
"path": "data-update-worker/package.json",
"chars": 330,
"preview": "{\n \"name\": \"job\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"index.js\",\n \"scripts\": {\n \"test\": \"echo \\\"E"
},
{
"path": "netlify.toml",
"chars": 28,
"preview": "[build]\n publish = \".next\"\n"
},
{
"path": "next-sitemap.config.js",
"chars": 173,
"preview": "/** @type {import('next-sitemap').IConfig} */\nmodule.exports = {\n siteUrl: process.env.SITE_URL || \"https://awesome.cub"
},
{
"path": "next.config.js",
"chars": 1219,
"preview": "const withBundleAnalyzer = require(\"@next/bundle-analyzer\")({\n enabled: process.env.ANALYZE === \"true\",\n});\n\nconst Cont"
},
{
"path": "package.json",
"chars": 889,
"preview": "{\n \"name\": \"awesome-dataviz-tools\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"dev\": \"next dev\",\n "
},
{
"path": "pages/_app.js",
"chars": 2606,
"preview": "import React, { Fragment, useEffect } from \"react\";\nimport dynamic from \"next/dynamic\";\nimport \"../styles/globals.scss\";"
},
{
"path": "pages/_document.js",
"chars": 301,
"preview": "import Document, { Html, Head, Main, NextScript } from 'next/document'\n\nclass MyDocument extends Document {\n render() {"
},
{
"path": "pages/for/[framework]/charting-libraries.js",
"chars": 1026,
"preview": "import ListPage from '../../../components/ListPage';\nimport { getTools } from '../../../data/tools';\nimport { hasTypes, "
},
{
"path": "pages/for/[framework]/index.js",
"chars": 967,
"preview": "import ListPage from '../../../components/ListPage';\nimport { getTools } from '../../../data/tools';\nimport { isCompatib"
},
{
"path": "pages/for/open-source.js",
"chars": 538,
"preview": "import ListPage from '../../components/ListPage';\nimport { getTools } from '../../data/tools';\nimport { hasLicenses, isC"
},
{
"path": "pages/index.js",
"chars": 708,
"preview": "import ListPage from '../components/ListPage';\nimport { getTools } from '../data/tools';\nimport { GlobalSignUp } from '."
},
{
"path": "pages/tools/[id]/[framework].js",
"chars": 1025,
"preview": "import React from \"react\";\nimport ToolPage from '../../../components/ToolPage/ToolPage';\n\nimport fs from \"fs\";\nimport { "
},
{
"path": "pages/tools/[id]/index.js",
"chars": 756,
"preview": "import React from \"react\";\nimport ToolPage from '../../../components/ToolPage/ToolPage';\n\nimport fs from \"fs\";\nimport { "
},
{
"path": "public/browserconfig.xml",
"chars": 246,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n <msapplication>\n <tile>\n <square150x150logo"
},
{
"path": "public/robots.txt",
"chars": 125,
"preview": "# *\nUser-agent: *\nAllow: /\n\n# Host\nHost: https://awesome.cube.dev/\n\n# Sitemaps\nSitemap: https://awesome.cube.dev/sitemap"
},
{
"path": "public/site.webmanifest",
"chars": 426,
"preview": "{\n \"name\": \"\",\n \"short_name\": \"\",\n \"icons\": [\n {\n \"src\": \"/android-chrome-192x192.png\",\n "
},
{
"path": "public/sitemap-0.xml",
"chars": 51139,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:news=\"http://ww"
},
{
"path": "public/sitemap.xml",
"chars": 190,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n<sitemap><loc>"
},
{
"path": "styles/_variables.scss",
"chars": 429,
"preview": "$dark: #141446;\n$dark-02: #43436b;\n$dark-03: #727290;\n$dark-04: #a1a1b5;\n$dark-05: #d5d5e2;\n$dark-06: #f8f8f8;\n$light-da"
},
{
"path": "styles/globals.scss",
"chars": 2121,
"preview": "@import \"/styles/variables\";\nhtml,\nbody {\n padding: 0;\n margin: 0;\n font-family: CeraPro, -apple-system, BlinkMacSyst"
},
{
"path": "styles/indexPage.scss",
"chars": 56,
"preview": ".counter {\n margin-top: 80px;\n margin-bottom: 80px;\n}\n"
},
{
"path": "update-copy.sh",
"chars": 53,
"preview": "cd data-update-worker && npm install && node index.js"
},
{
"path": "utils/number.js",
"chars": 796,
"preview": "export default function abbreviateNumber(value) {\n if (!value) {\n return null;\n }\n var newValue = value;\n if (val"
},
{
"path": "utils/tracking.js",
"chars": 645,
"preview": "export const tracking = {\n async init() {\n tracking.gateway = await import('cubedev-tracking');\n window.cubedevEv"
}
]
About this extraction
This page contains the full source code of the cube-js/awesome-tools GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 167 files (238.5 KB), approximately 78.3k tokens, and a symbol index with 70 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.