npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

wc-charts-kit

v1.0.1

Published

Ferramenta agnóstica de Data-Visualization para Vanilla JS & Web Components com zero-dependencies e suporte a Next.js/React.

Readme

WC Charts Kit

A robust and component-oriented Web Component to add interactive Chart.js charts in any framework (or Vanilla JS) with zero bundled dependencies. The architecture closely follows the scalability guidelines of wc-forms-kit.

🚀 Installation and Usage

The component doesn't require node modules, bundlers, or CDNs for basic usage. Just import the library via script and register the module in your HTML. Chart.js is dynamically auto-injected under the hood, providing full Server-Side Rendering (SSR) safety for Next.js users.

<!-- Web Component Initialization via ESModules -->
<script type="module" src="wc-chart.js"></script>

<!-- Declarative Rendering -->
<wc-chart 
    type="bar" 
    label="2026 Sales"
    x='["Jan", "Feb", "Mar"]' 
    y='[1200, 1900, 3000]'>
</wc-chart>

🎨 Visual Customization via CSS Variables

Styles can be declared using CSS variables on the wrapper class or directly in :root.

Supported variables:

  • --wc-chart-bg: Chart background color (default: #ffffff)
  • --wc-chart-height: Height enclosing the diagram (default: 400px)
  • --wc-chart-padding: Internal padding (default: 1.5rem)
  • --wc-chart-radius: Border radius of the view (default: 16px)
  • --wc-chart-shadow: Base shadows (default: soft shadow)
  • --wc-chart-hover-shadow: Shadow when in hover state

Example:

wc-chart {
    --wc-chart-bg: #1e293b; /* Dark mode card */
    --wc-chart-height: 500px;
}

🔌 Architecture: Extending New Charts

To build and natively register complex render engines, the logic must export a Class that respects the constructor API initialization:

import { Config, WcChart } from './wc-chart.js';

class RadarChart {
    constructor({ el, shadow, emitEvent }) {
        this.el = el;
        this.shadow = shadow;
        this.emitEvent = emitEvent;
        
        // 1. Creates the container and Canvas inside the Shadow DOM
        this.shadow.innerHTML = `
            <style>
                .chart-container {
                    position: relative;
                    height: var(--wc-chart-height, 400px);
                    width: 100%;
                }
                canvas { display: block; }
            </style>
            <div class="chart-container"><canvas></canvas></div>
        `;
        
        // 2. Waits for the template to mount before rendering the chart
        setTimeout(() => this.initChart(), 0);
    }

    // Parses JSON arrays that come from HTML attributes
    getParams() {
        try {
            return {
                x: JSON.parse(this.el.getAttribute('x') || '[]'),
                y: JSON.parse(this.el.getAttribute('y') || '[]'),
                label: this.el.getAttribute('label') || 'Radar Data'
            };
        } catch {
            return { x: [], y: [], label: '' };
        }
    }

    initChart() {
        const canvas = this.shadow.querySelector('canvas');
        if (!canvas || typeof Chart === 'undefined') return;

        const { x, y, label } = this.getParams();

        this.chartInstance = new Chart(canvas.getContext('2d'), {
            type: 'radar',
            data: {
                labels: x,
                datasets: [{
                    label: label,
                    data: y,
                    backgroundColor: 'rgba(54, 162, 235, 0.4)',
                    borderColor: 'rgba(54, 162, 235, 1)',
                    borderWidth: 2
                }]
            },
            options: { responsive: true, maintainAspectRatio: false }
        });
    }

    // 3. Reactively updates data when HTML element attributes mutate
    onAttributeChanged(name, oldValue, newValue) {
        if (oldValue !== newValue && this.chartInstance) {
            const { x, y, label } = this.getParams();
            this.chartInstance.data.labels = x;
            this.chartInstance.data.datasets[0].data = y;
            this.chartInstance.data.datasets[0].label = label;
            this.chartInstance.update();
        }
    }
}

Config.registerChart('radar', RadarChart);

To use your chart, simply pass the type attribute equal to what you used to register it: <wc-chart type="radar"></wc-chart>.

⚡ Native Events

You can "listen" to the library stages using native DOM events:

  • @before-mount - Intercepted before the Canvas is drawn to the DOM
  • @after-mount - As soon as the rendering engine has drawn the chart (event details provide { instance })
  • @updated - Whenever a new value is sent via attributes and the component reacts
  • @click - When a specific area of the chart/view is clicked
document.querySelector('#my-chart').addEventListener('updated', (e) => {
    console.log('Component updated its attribute:', e.detail.attribute);
});

🧮 ChartDataHelper (Pandas/Dataframe Style)

Included in the library, there is a dedicated Javascript utility heavily inspired by the seamless developer experience of Pandas (Python) to filter, sort and format pure raw datasets before injecting them into the Web Component.

It supports "Dot-Notation" to natively access deep/nested object properties (e.g. address.street):

import { ChartDataHelper } from './wc-chart.js';

// 1. Instantiate your native collection
const resultDataset = new ChartDataHelper(mockApiData)
    // 2. Dynamically filter elements (query) with classic operators
    .query('meta.status', '==', 'active') 
    .query('price', '>', 50)
    
    // 3. Sort the data source (sortValues) - true = ascending / false = descending
    .sortValues('meta.barcode', false) 
    
    // 4. Group or Sum a field relative to another
    .sumBy('category.id', 'price') // Groups Category ID alongside the Total Revenue gathered
    
    // 5. Format converts the final outcome into a secure stringified JSON Payload of X/Y Arrays
    .format();

// resultDataset will output: { x: '["Electronics", "Fashion"]', y: '[1500, 300]' }
// Ready for: myElement.setAttribute('x', resultDataset.x);

📚 API and Methods Table (ChartDataHelper)

All methods dealing with native data keys support "Dot-Notation" natively (ex: user.meta.age).

| Method | Returns | Description | Usage Example | |:---|:---:|:---|:---| | .query(field, op, val) | this | Filters the collection while preserving the objects natively. Available operators: ==, !=, >, <, >=, <=, in, not in, contains. Also supports an arrow function as a custom check. | .query('price', '>', 50) or .query('age', v => v > 18) | | .sortValues(field, asc) | this | Flattens and reorders the collection based on a primitive field. The second parameter dictates true (Ascending) or false (Descending). | .sortValues('meta.date', false) | | .groupBy(field) | this | Groups objects holding identically matched keys and stores them in dictionary arrays (generates Volume/Length stacked bars over the same baseline scale). | .groupBy('category.id') | | .countBy(field) | this | Similar to groupBy, but automatically consolidates the records by adding +1 to its dictionary quantity output amount natively. | .countBy('status') | | .sumBy(group, sum) | this | Groups everything relying on group, but instead of bumping +1 over the items array, it precisely sums targeted numerical values from sum (If sum is numerical, it appends itself into the total; if it is a string or fails parsing, it falls back to a unitary string count of 1). | .sumBy('month', 'financial.profit') | | .extractBy(field) | this | Erases collection-level depth and outputs a static 1D Array extracting strictly the field references (ideal for Scatter or simple sequential linear traces). | .extractBy('email') | | .rangeBy(field, ranges) | this | Categorizes chronological/statistical inputs according to a predefined Array bounded by limits { label, min, max }. Supports Date objects or Float/Int parsing. Bypasses unparsed inputs grouping them into an "Out of bounds" bracket. | .rangeBy('age', [{label: 'Youth', min: 0, max: 20}]) | | .getCount() | Number | Observation utility function. Returns the total amount of axes filtered/captured/created after the recent extraction parses. | .getCount() | | .format() | JSON | Macro closer encompassing the prior manipulations, rendering stringified architectures mapped explicitly for native Web Component attributes: { x: '["A", "B"]', y: '[10, 20]' }. It triggers the .getLabels() pipeline abstracting X-axis variables. | .format() |


Inspired by Next.js Web Components Design and Vanilla JS Scalable Code.