Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 0 additions & 92 deletions .eslintrc.cjs

This file was deleted.

7 changes: 0 additions & 7 deletions .prettierrc.json

This file was deleted.

13 changes: 12 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
## Development Workflow

- Use pnpm as the package manager (configured in package.json)
- Run pnpm lint before any commit (and after major edits as well).
- With each commit (and only commit) increment patch version by one. Unless there is a direct instruction to increase minor (or major) version.

## Code Quality Rules

- NEVER fail silently - always log errors and make failures visible to users when appropriate.
- NEVER fail silently - always log errors and make failures visible to users when appropriate.

## Type Safety Requirements

- AVOID using `any` types to mask type checking - this defeats the purpose of TypeScript
- AVOID using `as` casting without proper validation - it bypasses type safety
- DO import types directly from libraries when available
- DO use type guards and runtime validation when interfacing with untyped external systems
- AVOID patterns like `export type WebRInstance = any` - these mask real type safety issues
- AVOID creating type aliases that just re-export types - import directly instead
- ALL functions must have explicit return types - this is enforced by ESLint rules
114 changes: 32 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,100 +1,50 @@
# WebR ggplot2 & dplyr Demo
# WebR ggplot2 Demo

A minimal Vue.js application demonstrating interactive R data visualization and manipulation using WebR, ggplot2, and dplyr in the browser.
Interactive R data visualization in the browser using [WebR](https://webr.r-wasm.org/), [ggplot2](https://ggplot2.tidyverse.org/), and Vue.js.

## Features
## What is it?

- 🎨 **Interactive Code Editor**: Monaco editor with R syntax highlighting
- 📊 **Built-in Examples**: Pre-configured examples for ggplot2 and dplyr
- 📁 **CSV Upload**: Drag-and-drop CSV file upload functionality
- 🖥️ **Real-time Output**: Live R code execution with stdout/stderr display
- 📈 **Plot Visualization**: SVG plot rendering in the browser
- 🎯 **Clean Architecture**: Well-organized Vue 3 components with TypeScript
A web application that runs R code directly in your browser - no server required. Features live code editing, CSV upload, and interactive plots.

## Tech Stack

- **Vue 3** with TypeScript
- **Vite** for build tooling
- **WebR** for R in the browser
- **Monaco Editor** for code editing
- **ESLint** with strict rules
- **Prettier** for code formatting
- **pnpm** for package management

## Quick Start
## License

1. **Install dependencies**:
```bash
pnpm install
```
MIT License

2. **Run development server**:
```bash
pnpm dev
```
## Author

3. **Build for production**:
```bash
pnpm build
```
Developed by [Piotr Migdal](https://p.migdal.pl/) from [Quesma](https://quesma.com/)

## Usage
## Installation

1. **Select Examples**: Choose from pre-built examples in the dropdown
2. **Upload CSV**: Drag and drop CSV files or click to browse
3. **Edit Code**: Use the Monaco editor to write R code
4. **Run Code**: Click "Run Code" to execute R scripts
5. **View Results**: See output, plots, and any errors in the output panel
Prerequisites:
- Node.js 18+
- [pnpm](https://pnpm.io/)

## Example Scripts
```bash
# Clone repository
git clone https://github.com/QuesmaOrg/demo-webr-ggplot.git
cd demo-webr-ggplot

- **Basic ggplot2**: Simple scatter plot with mtcars dataset
- **dplyr filtering**: Data manipulation and summarization
- **Enhanced scatter plot**: Color mapping and trend lines
- **Bar chart**: Grouped bar charts with custom styling
- **CSV template**: Template for working with uploaded data
# Install dependencies
pnpm install

## Project Structure
# Start development server
pnpm dev

# Build for production
pnpm build
```
src/
├── components/ # Vue components
│ ├── CodeEditor.vue # Monaco editor wrapper
│ ├── FileUpload.vue # CSV upload component
│ ├── ExampleSelector.vue # Example dropdown
│ └── OutputDisplay.vue # Results display
├── composables/ # Vue composables
│ └── useWebR.ts # WebR integration logic
├── data/ # Static data
│ └── examples.ts # R code examples
├── types/ # TypeScript types
│ └── index.ts # Type definitions
├── App.vue # Main application
├── main.ts # Application entry point
└── style.css # Global styles
```

## Development

- **Linting**: `pnpm lint`
- **Formatting**: `pnpm format`
- **Type checking**: `pnpm build` (includes vue-tsc)

## WebR Configuration

The application uses WebR with the following packages pre-installed:
- `ggplot2` for data visualization
- `dplyr` for data manipulation

WebR is configured with CORS headers and proper service worker setup for browser compatibility.

## Contributing
## Usage

1. Follow the existing code style (ESLint + Prettier)
2. Use TypeScript for type safety
3. Keep components small and focused
4. Add examples for new R functionality
1. Open http://localhost:5173 in your browser
2. Select an example or write your own R code
3. Upload CSV files via drag & drop
4. Click "Run Code" to execute

## License
## Stack

MIT License - feel free to use this project as a starting point for your own WebR applications.
- [WebR](https://webr.r-wasm.org/) - R in WebAssembly
- [Vue 3](https://vuejs.org/) + TypeScript
- [Vite](https://vitejs.dev/) - Build tool
- [Monaco Editor](https://microsoft.github.io/monaco-editor/) - Code editor
33 changes: 33 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pluginVue from 'eslint-plugin-vue'
import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescript'

export default defineConfigWithVueTs(
{
ignores: ['dist/**', 'node_modules/**', '*.d.ts', 'coverage/**', '.vite/**']
},
pluginVue.configs['flat/recommended'],
vueTsConfigs.recommended,
{
files: ['**/*.{ts,tsx,vue,js,jsx,mjs,cjs}'],
rules: {
'@typescript-eslint/no-unused-vars': ['error', {
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}],
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/explicit-function-return-type': 'error',
'@typescript-eslint/explicit-module-boundary-types': 'error',

'vue/multi-word-component-names': 'off',
'vue/block-order': ['error', {
order: ['script', 'template', 'style']
}],

'no-console': ['warn', { allow: ['warn', 'error'] }],
'no-debugger': 'error',
'prefer-const': 'error',
'no-var': 'error'
}
}
)
34 changes: 14 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,35 +1,29 @@
{
"name": "webr-ggplot2-demo",
"private": true,
"version": "0.1.6",
"version": "0.1.8",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"build": "vite build",
"preview": "vite preview",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
"lint": "eslint . --fix"
},
"dependencies": {
"@monaco-editor/loader": "^1.5.0",
"monaco-editor": "^0.52.2",
"vue": "^3.4.0",
"vue": "^3.5.18",
"webr": "^0.5.4"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.3.3",
"@tsconfig/node18": "^18.2.2",
"@types/node": "^18.19.9",
"@vitejs/plugin-vue": "^4.5.2",
"@vue/eslint-config-prettier": "^8.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/tsconfig": "^0.5.1",
"eslint": "^8.49.0",
"eslint-plugin-vue": "^9.17.0",
"prettier": "^3.0.3",
"typescript": "~5.3.0",
"vite": "^5.0.10",
"vue-tsc": "^1.8.25"
"@types/node": "^24.1.0",
"@typescript-eslint/eslint-plugin": "^8.38.0",
"@typescript-eslint/parser": "^8.38.0",
"@vitejs/plugin-vue": "^6.0.1",
"@vue/eslint-config-typescript": "^14.6.0",
"eslint": "^9.32.0",
"eslint-plugin-vue": "^10.4.0",
"typescript": "~5.9.2",
"vite": "^7.0.6"
},
"packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808"
"packageManager": "pnpm@10.7.1"
}
Loading