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

@rm-graph/core

v0.1.13

Published

RM-Graphs Core - Charting library built on SciChart

Downloads

91

Readme

@rm-graph/core

RM-Graphs Core - Framework-agnostic charting library built on SciChart.js. This package provides the core functionality for creating high-performance 2D and 3D charts, including license management with encrypted storage.

Installation

npm install @rm-graph/core
# or
pnpm add @rm-graph/core
# or
yarn add @rm-graph/core

scichart is automatically installed as a dependency!

Quick Start

import { createColumn3DChart, createPRPDChart, loadLicense } from '@rm-graph/core';

// Load license on app startup (optional - removes watermark)
await loadLicense();

// Create a 3D column chart
const chart = await createColumn3DChart('container-id', {
  theme: 'dark',
  data: [[45, 1500, 1], [90, 2200, 2], [180, 1800, 3]],
  xAxisTitle: 'Phase Angle (°)',
  yAxisTitle: 'Amplitude (mVp)',
  zAxisTitle: 'Cycle',
});

// Update data dynamically
chart.setData([[50, 1600, 1], [95, 2300, 2]]);

// Change theme
chart.setOptions({ theme: 'light' });

// Cleanup when done
chart.destroy();

Chart Types

Column3DChart

3D column/bar charts for phase-resolved data visualization.

import { createColumn3DChart, type Column3DDataPoint } from '@rm-graph/core';

// Data format: [phaseAngle, amplitude, cycle][]
const data: Column3DDataPoint[] = [
  [45, 1500, 1],   // 45° phase, 1500mV amplitude, cycle 1
  [90, 2200, 2],   // 90° phase, 2200mV amplitude, cycle 2
  [180, 1800, 3],  // 180° phase, 1800mV amplitude, cycle 3
];

const chart = await createColumn3DChart('container', {
  data,
  theme: 'dark',
  xAxisTitle: 'Phase Angle (°)',
  yAxisTitle: 'Amplitude (mVp)',
  zAxisTitle: 'Cycle',
  xRange: { min: 0, max: 360 },
  yRange: { min: 0, max: 5000 },
  zRange: { min: 0, max: 50 },
  barFill: '#52aaf2',
  barOpacity: 0.95,
  showSineWave: true,
});

PRPDChart

Phase Resolved Partial Discharge heatmap visualization.

import { createPRPDChart, type PRPDDataPoint } from '@rm-graph/core';

// Data format: [phaseAngle, amplitude, count][]
const data: PRPDDataPoint[] = [
  [45, 1500, 10],   // 45° phase, 1500mV amplitude, 10 pulses
  [90, 2200, 25],   // 90° phase, 2200mV amplitude, 25 pulses
  [180, -1800, 15], // 180° phase, -1800mV amplitude, 15 pulses
];

const chart = await createPRPDChart('container', {
  data,
  maxPeak: 5000,
  minPeak: -5000,
  maxPhaseAngle: 360,
  showSineWave: true,
  showColorPalette: true,
});

Surface3DChart

3D surface visualization for continuous data.

import { createSurface3DChart } from '@rm-graph/core';

const chart = await createSurface3DChart('container', {
  yValues: surfaceData, // 2D array of height values
  theme: 'dark',
  colorMin: 0,
  colorMax: 100,
});

Theming

Built-in themes: light, dark, modern, midnight

import { getThemeManager, lightTheme, darkTheme } from '@rm-graph/core';

// Use built-in theme
const chart = await createColumn3DChart('container', {
  theme: 'dark',
  // ...
});

// Register custom theme
getThemeManager().registerTheme({
  name: 'custom',
  backgroundColor: '#1a1a2e',
  textColor: '#ffffff',
  gridLineColor: '#333366',
  colorPalette: ['#ff6b6b', '#4ecdc4', '#45b7d1'],
});

// Use custom theme
chart.setOptions({ theme: 'custom' });

Theme Configuration

interface ThemeConfig {
  name: string;
  backgroundColor: string;
  textColor: string;
  gridLineColor: string;
  axisColor: string;
  colorPalette: string[];
  // ... more options
}

🔑 License Management System

The core package includes a complete license management system for SciChart.js with encrypted storage support.

Overview

SciChart.js requires a valid license key to remove watermarks from charts. The @rm-graph/core package provides:

  • Encrypted Storage: License keys are encrypted before storing in localStorage
  • Multiple Configuration Methods: UI component, programmatic, or environment variables
  • Automatic Loading: Load license on app startup
  • Status Tracking: Check if license is stored and applied

How Licensing Works Internally

┌─────────────────────────────────────────────────────────────────┐
│                    LICENSE FLOW DIAGRAM                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  User enters license key                                        │
│           │                                                     │
│           ▼                                                     │
│  ┌─────────────────┐                                           │
│  │ validateFormat()│ ──── Invalid ───► Show error message      │
│  └────────┬────────┘                                           │
│           │ Valid                                               │
│           ▼                                                     │
│  ┌─────────────────────────────────────────┐                   │
│  │ encryptLicense(key, passphrase)         │                   │
│  │  - Uses AES-256-GCM (Web Crypto API)    │                   │
│  │  - Falls back to Base64 if no HTTPS     │                   │
│  └────────┬────────────────────────────────┘                   │
│           │                                                     │
│           ▼                                                     │
│  ┌─────────────────────────────────────────┐                   │
│  │ localStorage.setItem(                   │                   │
│  │   'RMGRAPH_LICENSE_DATA',               │                   │
│  │   encryptedData                         │                   │
│  │ )                                       │                   │
│  └────────┬────────────────────────────────┘                   │
│           │                                                     │
│           ▼                                                     │
│  ┌─────────────────────────────────────────┐                   │
│  │ SciChartSurface.setRuntimeLicenseKey()  │                   │
│  │  - Applies license to SciChart          │                   │
│  │  - Removes watermark from charts        │                   │
│  └─────────────────────────────────────────┘                   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Encryption Details

The license system uses two-tier encryption:

Primary: AES-256-GCM (Secure Contexts)

When Web Crypto API is available (HTTPS or localhost):

// Encryption process:
1. Derive key from passphrase using PBKDF2 (100,000 iterations, SHA-256)
2. Generate random 12-byte IV (Initialization Vector)
3. Encrypt license key using AES-256-GCM
4. Combine IV + encrypted data
5. Encode as Base64 for storage

// Storage format in localStorage:
"RMGRAPH_LICENSE_DATA": "base64(IV + AES-GCM-encrypted-data)"

Fallback: Base64 Obfuscation (Insecure Contexts)

When Web Crypto API is NOT available (HTTP over IP):

// Simple obfuscation:
1. Prepend "rmgraph:" prefix
2. Encode as Base64

// Storage format:
"RMGRAPH_LICENSE_DATA": "base64('rmgraph:' + licenseKey)"

Security Note: Base64 is NOT encryption - it only provides basic obfuscation. For production, always use HTTPS and combine with SciChart's domain-locking.

License Management API

Core Functions

import {
  // High-level operations
  setLicense,           // Encrypt, store, and apply license
  loadLicense,          // Load from storage and apply
  removeLicense,        // Remove stored license
  applyLicenseKey,      // Apply directly without storing
  
  // Status checks
  hasStoredLicense,     // Check if license exists in storage
  isLicenseApplied,     // Check if license is active in session
  getLicenseStatus,     // Get full status object
  validateLicenseFormat, // Validate key format (basic)
  
  // Configuration
  configureLicenseEncryption, // Set custom passphrase
  
  // Low-level crypto (advanced)
  encryptLicense,
  decryptLicense,
  saveEncryptedLicense,
  loadEncryptedLicense,
  clearStoredLicense,
  getLicenseStorageKey,
  
  // Types
  type LicenseConfig,
  type LicenseStatus,
} from '@rm-graph/core';

Function Reference

setLicense(licenseKey: string): Promise<boolean>

Encrypts and stores a license key, then applies it to SciChart.

const success = await setLicense('your-scichart-license-key');
if (success) {
  console.log('License saved and applied!');
} else {
  console.log('Failed to save license');
}
loadLicense(): Promise<boolean>

Loads license from encrypted storage and applies to SciChart.

// Call on app startup
const loaded = await loadLicense();
if (loaded) {
  console.log('License loaded from storage');
} else {
  console.log('No license found - charts will show watermark');
}
removeLicense(): void

Removes the stored license from localStorage.

removeLicense();
// Note: Page reload required to remove license from SciChart
hasStoredLicense(): boolean

Checks if a license exists in localStorage (without decrypting).

if (hasStoredLicense()) {
  console.log('License found in storage');
}
isLicenseApplied(): boolean

Checks if a license has been applied to SciChart in the current session.

if (isLicenseApplied()) {
  console.log('License is active');
}
getLicenseStatus(): LicenseStatus

Returns complete license status.

const status = getLicenseStatus();
// { hasLicense: true, isApplied: true }
validateLicenseFormat(licenseKey: string): boolean

Basic format validation (length check only - doesn't verify with SciChart).

if (validateLicenseFormat(userInput)) {
  await setLicense(userInput);
}
configureLicenseEncryption(config: LicenseConfig): void

Configure custom passphrase for encryption (optional).

// Call before setLicense/loadLicense if using custom passphrase
configureLicenseEncryption({
  passphrase: 'my-app-secret-key'
});

Usage Examples

Example 1: Basic Setup

import { loadLicense, createColumn3DChart } from '@rm-graph/core';

async function initApp() {
  // Load license on startup
  await loadLicense();
  
  // Create charts (will be watermark-free if license is valid)
  const chart = await createColumn3DChart('container', {
    data: myData,
  });
}

initApp();

Example 2: Programmatic License Configuration

import { setLicense, loadLicense, hasStoredLicense } from '@rm-graph/core';

async function configureLicense(licenseKey: string) {
  // Check if already configured
  if (hasStoredLicense()) {
    console.log('License already stored');
    await loadLicense();
    return;
  }
  
  // Save new license
  const success = await setLicense(licenseKey);
  if (success) {
    console.log('License configured successfully');
  }
}

Example 3: Environment Variable Setup

import { setupSciChartLicense } from '@rm-graph/core';

// .env file:
// VITE_SCICHART_LICENSE_KEY=your-license-key

// In main.ts:
await setupSciChartLicense({
  fromEnv: true,           // Check VITE_SCICHART_LICENSE_KEY
  fromLocalStorage: true,  // Also check encrypted storage
});

Example 4: Custom Passphrase

import { 
  configureLicenseEncryption, 
  setLicense, 
  loadLicense 
} from '@rm-graph/core';

// Use custom passphrase for extra security
configureLicenseEncryption({
  passphrase: 'my-unique-app-identifier-2024'
});

// Now save/load will use this passphrase
await setLicense('your-license-key');
await loadLicense();

Types

interface LicenseConfig {
  /** Custom passphrase for encryption/decryption */
  passphrase?: string;
}

interface LicenseStatus {
  /** Whether a license is stored in localStorage */
  hasLicense: boolean;
  /** Whether the license was successfully applied to SciChart */
  isApplied: boolean;
  /** Error message if license operation failed */
  error?: string;
}

Storage Details

| Key | Value | Description | |-----|-------|-------------| | RMGRAPH_LICENSE_DATA | Base64 encoded encrypted data | Encrypted license key |

Security Considerations

  1. Client-Side Encryption: The encryption happens in the browser. While AES-256-GCM is strong, the decryption key (passphrase) is in the client code.

  2. Domain Locking: For production security, always use SciChart's domain-locking feature. Register your domains at SciChart License Portal.

  3. HTTPS Required: Full AES encryption requires HTTPS or localhost. HTTP over IP will use Base64 fallback.

  4. Don't Commit Keys: Never commit license keys to source control. Use environment variables.


Utilities

import {
  generateId,        // Generate unique IDs
  parseSize,         // Parse CSS size values
  deepMerge,         // Deep merge objects
  debounce,          // Debounce function calls
  throttle,          // Throttle function calls
  hexToRgba,         // Convert hex to RGBA
  formatNumber,      // Format numbers
  clamp,             // Clamp value to range
  lerp,              // Linear interpolation
} from '@rm-graph/core';

WebAssembly Configuration

SciChart uses WebAssembly for high performance. The package auto-configures to use CDN:

import { configureSciChart } from '@rm-graph/core';

// Default: Uses CDN (auto-configured)

// Custom WASM location:
configureSciChart({
  wasmUrl: '/path/to/scichart2d.wasm'
});

Framework Integrations

This core package is framework-agnostic. For framework-specific components:

  • React: @rm-graph/react - React components and hooks
  • Angular: @rm-graph/angular - Angular components

Both packages re-export all core functionality plus framework-specific UI components like LicenseManager.


API Reference

Chart Factory Functions

| Function | Description | |----------|-------------| | createColumn3DChart(container, config) | Create 3D column chart | | createPRPDChart(container, config) | Create PRPD heatmap | | createSurface3DChart(container, config) | Create 3D surface |

Chart Instance Methods

| Method | Description | |--------|-------------| | setData(data) | Update chart data | | setOptions(options) | Update chart options | | destroy() | Cleanup and remove chart |

Theme Functions

| Function | Description | |----------|-------------| | getThemeManager() | Get theme manager instance | | lightTheme | Built-in light theme | | darkTheme | Built-in dark theme | | modernTheme | Built-in modern theme | | midnightTheme | Built-in midnight theme |

License Functions

| Function | Description | |----------|-------------| | setLicense(key) | Save and apply license | | loadLicense() | Load license from storage | | removeLicense() | Remove stored license | | hasStoredLicense() | Check if license exists | | isLicenseApplied() | Check if license is active | | getLicenseStatus() | Get full status |


Troubleshooting

Charts show watermark

  1. Verify license is loaded: console.log(getLicenseStatus())
  2. Check browser console for license errors
  3. Ensure domain is registered in SciChart portal
  4. Try reloading page after setting license

Crypto errors on HTTP

Web Crypto API requires secure context (HTTPS or localhost). The system will fallback to Base64 encoding automatically.

License not persisting

Check if localStorage is available and not blocked by browser settings.


License

MIT


See framework-specific packages for UI components and additional documentation.