Advanced Styling¶
Take your charts to the next level with advanced styling techniques, custom themes, and artistic effects.
Hand-Drawn Effects¶
The signature feature of the Handwritten Graph Library is its authentic hand-drawn aesthetic.
Basic Hand-Drawn Styling¶
const chart = new LineChart('#chart', data, {
handDrawnEffect: true, // Enable hand-drawn look
handDrawnJitter: 2, // Amount of random variation (pixels)
strokeLinecap: 'round', // Rounded line endings
strokeLinejoin: 'round' // Rounded line joins
});
Jitter Control¶
The handDrawnJitter parameter controls how “wobbly” your lines appear:
// Subtle hand-drawn effect
const subtleChart = new LineChart('#subtle', data, {
handDrawnJitter: 1
});
// More pronounced wobble
const wobbyChart = new LineChart('#wobbly', data, {
handDrawnJitter: 4
});
// Extremely sketchy (use sparingly)
const sketchyChart = new LineChart('#sketchy', data, {
handDrawnJitter: 8
});
Note
Higher jitter values (>5) can make charts difficult to read. Use them only for artistic effect.
Line Quality Control¶
For LineCharts, you can control the smoothness of hand-drawn lines:
const chart = new LineChart('#chart', data, {
handDrawnPoints: 50, // Fewer points = more angular
handDrawnPoints: 200 // More points = smoother curves
});
Fill Patterns and Textures¶
Create rich, artistic fill effects with scribble patterns and oil paint textures.
Directional Scribble Fills¶
const chart = new BarChart('#chart', data, {
useScribbleFill: true,
fillStyle: 'directional'
});
The directional fill style creates hatching patterns at various angles:
Different datasets get different hatch directions
Automatic color variation creates depth
Paper-like texture overlay adds authenticity
Oil Paint Textures¶
const chart = new PieChart('#chart', data, {
useScribbleFill: true,
fillStyle: 'oilpaint'
});
Oil paint style creates watercolor-like organic textures:
Multiple layers of color blobs
Natural color variation within each area
Soft, artistic appearance
Custom Color Schemes¶
Professional Color Palettes¶
// Corporate blue theme
const corporateTheme = {
lineColor: '#2c3e50',
barColor: '#3498db',
gridColor: '#ecf0f1',
tooltipBgColor: '#34495e',
tooltipTextColor: '#ffffff'
};
// Warm sunset theme
const sunsetTheme = {
lineColor: '#e74c3c',
barColor: '#f39c12',
gridColor: '#fdf2e9',
tooltipBgColor: '#d35400',
tooltipTextColor: '#ffffff'
};
// Modern minimal theme
const minimalTheme = {
lineColor: '#2d3436',
barColor: '#636e72',
gridColor: '#f8f9fa',
tooltipBgColor: '#ffffff',
tooltipTextColor: '#2d3436',
handDrawnEffect: false // Clean, precise lines
};
Accessibility-First Colors¶
// High contrast theme for accessibility
const accessibleTheme = {
lineColor: '#000000',
barColor: '#0066cc',
gridColor: '#666666',
tooltipBgColor: '#ffffff',
tooltipTextColor: '#000000',
tooltipBorderColor: '#000000',
tooltipBorderWidth: 3
};
// Colorblind-friendly palette
const colorblindFriendly = [
'#1f77b4', '#ff7f0e', '#2ca02c', '#d62728',
'#9467bd', '#8c564b', '#e377c2', '#7f7f7f'
];
Multi-Series Color Management¶
// Automatic color assignment
const data = {
labels: ['Q1', 'Q2', 'Q3', 'Q4'],
datasets: [
{
label: 'Series 1',
data: [10, 20, 30, 25],
lineColor: '#e74c3c' // Explicit color
},
{
label: 'Series 2',
data: [15, 25, 20, 30]
// Color will be auto-assigned from D3's color scheme
}
]
};
Typography and Fonts¶
Custom Font Integration¶
// Using web fonts
const chart = new LineChart('#chart', data, {
fontFamily: '"Roboto", sans-serif'
});
// Using system fonts
const systemFontChart = new BarChart('#chart', data, {
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
});
// Maintaining the hand-drawn aesthetic
const handwrittenChart = new PieChart('#chart', data, {
fontFamily: '"Kalam", "Comic Sans MS", cursive'
});
Note
The library includes the “xkcd” font (Humor Sans) by default. You can override this with any web-safe or custom font.
Font Size Control¶
While the library manages font sizes automatically, you can influence them through CSS:
/* Custom CSS for font sizing */
.handwritten-graph-container {
font-size: 14px; /* Base font size */
}
.handwritten-graph-container .legend text {
font-size: 16px; /* Larger legend text */
}
.handwritten-graph-container .axis text {
font-size: 12px; /* Smaller axis labels */
}
Layout and Spacing¶
Custom Margins¶
// Extra space for long labels
const wideMarginChart = new BarChart('#chart', data, {
margin: { top: 20, right: 200, bottom: 100, left: 100 }
});
// Compact layout
const compactChart = new LineChart('#chart', data, {
margin: { top: 10, right: 10, bottom: 30, left: 40 }
});
Dynamic Sizing¶
// Responsive chart sizing
function createResponsiveChart(selector, data) {
const container = document.querySelector(selector);
const containerWidth = container.clientWidth;
const containerHeight = container.clientHeight;
return new LineChart(selector, data, {
width: Math.min(800, containerWidth * 0.95),
height: Math.min(400, containerHeight * 0.8),
margin: {
top: 20,
right: containerWidth > 600 ? 150 : 50,
bottom: 60,
left: 60
}
});
}
Advanced Visual Effects¶
Combining Effects¶
// Maximum artistic effect
const artisticChart = new PieChart('#chart', data, {
handDrawnEffect: true,
handDrawnJitter: 3,
useScribbleFill: true,
fillStyle: 'oilpaint',
strokeLinecap: 'round',
strokeLinejoin: 'round',
cornerRadius: 8,
padAngle: 0.05
});
Performance vs. Quality¶
// High quality for presentations
const presentationChart = new LineChart('#chart', data, {
handDrawnEffect: true,
handDrawnPoints: 200, // Very smooth
handDrawnJitter: 2,
useScribbleFill: true
});
// Optimized for performance
const performanceChart = new LineChart('#chart', data, {
handDrawnEffect: false, // Fastest rendering
useScribbleFill: false,
handDrawnPoints: 50 // If hand-drawn is needed
});
Custom CSS Integration¶
Overriding Default Styles¶
/* Custom chart container styling */
.my-custom-chart .handwritten-graph-container {
background: linear-gradient(45deg, #f0f8ff, #e6f3ff);
border-radius: 15px;
padding: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
/* Custom tooltip styling */
.my-custom-chart .xkcd-tooltip rect {
fill: #2c3e50 !important;
stroke: #3498db !important;
stroke-width: 3px !important;
}
.my-custom-chart .xkcd-tooltip text {
fill: #ecf0f1 !important;
font-weight: bold !important;
}
Animation and Transitions¶
/* Smooth entrance animation */
.handwritten-graph-container {
opacity: 0;
transform: translateY(20px);
animation: chartFadeIn 0.8s ease-out forwards;
}
@keyframes chartFadeIn {
to {
opacity: 1;
transform: translateY(0);
}
}
/* Hover effects on chart elements */
.handwritten-graph-container .bar:hover {
transform: scale(1.05);
transition: transform 0.2s ease;
}
Theme System¶
Creating Reusable Themes¶
// Theme definition
interface ChartTheme {
colors: {
primary: string;
secondary: string;
accent: string;
background: string;
text: string;
grid: string;
};
effects: {
handDrawn: boolean;
scribbleFill: boolean;
fillStyle: 'directional' | 'oilpaint';
jitter: number;
};
typography: {
fontFamily: string;
};
}
// Light theme
const lightTheme: ChartTheme = {
colors: {
primary: '#3498db',
secondary: '#e74c3c',
accent: '#f39c12',
background: '#ffffff',
text: '#2c3e50',
grid: '#ecf0f1'
},
effects: {
handDrawn: true,
scribbleFill: true,
fillStyle: 'directional',
jitter: 2
},
typography: {
fontFamily: 'xkcd'
}
};
// Dark theme
const darkTheme: ChartTheme = {
colors: {
primary: '#74b9ff',
secondary: '#fd79a8',
accent: '#fdcb6e',
background: '#2d3436',
text: '#ddd',
grid: '#636e72'
},
effects: {
handDrawn: true,
scribbleFill: true,
fillStyle: 'oilpaint',
jitter: 3
},
typography: {
fontFamily: 'xkcd'
}
};
Theme Application Function¶
function applyTheme(chartConfig: any, theme: ChartTheme): any {
return {
...chartConfig,
lineColor: theme.colors.primary,
barColor: theme.colors.primary,
gridColor: theme.colors.grid,
tooltipBgColor: theme.colors.background,
tooltipTextColor: theme.colors.text,
tooltipBorderColor: theme.colors.primary,
handDrawnEffect: theme.effects.handDrawn,
useScribbleFill: theme.effects.scribbleFill,
fillStyle: theme.effects.fillStyle,
handDrawnJitter: theme.effects.jitter,
fontFamily: theme.typography.fontFamily
};
}
// Usage
const themedChart = new LineChart('#chart', data,
applyTheme({ width: 800, height: 400 }, darkTheme)
);
Seasonal and Contextual Styling¶
Holiday Themes¶
// Christmas theme
const christmasTheme = {
lineColor: '#c0392b',
barColor: '#27ae60',
gridColor: '#f8f9fa',
useScribbleFill: true,
fillStyle: 'directional' as const
};
// Halloween theme
const halloweenTheme = {
lineColor: '#f39c12',
barColor: '#d35400',
gridColor: '#2c2c2c',
tooltipBgColor: '#000000',
tooltipTextColor: '#f39c12'
};
Business Context Themes¶
// Financial/corporate theme
const financialTheme = {
lineColor: '#2c3e50',
barColor: '#34495e',
gridColor: '#bdc3c7',
handDrawnEffect: false, // Professional, clean lines
useScribbleFill: false,
fontFamily: '"Roboto", sans-serif'
};
// Creative/agency theme
const creativeTheme = {
lineColor: '#e74c3c',
barColor: '#9b59b6',
handDrawnJitter: 4, // Extra artistic
useScribbleFill: true,
fillStyle: 'oilpaint' as const,
fontFamily: '"Kalam", cursive'
};
Best Practices¶
Consistency: Use the same theme across all charts in a dashboard
Accessibility: Always test with high contrast modes and color blindness simulators
Performance: Balance visual appeal with rendering performance
Context: Choose styling that matches your content and audience
Testing: Verify styles work across different browsers and devices
// Good: Consistent theming across charts
const sharedConfig = {
lineColor: '#3498db',
handDrawnEffect: true,
fontFamily: 'xkcd'
};
const lineChart = new LineChart('#line', lineData, {
...sharedConfig,
showArea: true
});
const barChart = new BarChart('#bar', barData, {
...sharedConfig,
barColor: sharedConfig.lineColor
});
See Also¶
Configuration API Reference - Complete configuration reference