|
|
|
|
|
|
|
|
|
|
|
const EMPTY_DOT_DARK = "#374151"; |
|
|
const EMPTY_DOT_LIGHT = "#d1d5db"; |
|
|
|
|
|
export const getHeatmapTheme = (primaryColor: string) => ({ |
|
|
dark: [EMPTY_DOT_DARK, primaryColor], |
|
|
light: [EMPTY_DOT_LIGHT, primaryColor], |
|
|
}); |
|
|
|
|
|
export const getHeatmapColorIntensity = (level: number, primaryColor: string, isDarkMode: boolean = false) => { |
|
|
if (level === 0) { |
|
|
return null; |
|
|
} |
|
|
|
|
|
|
|
|
const hexToRgb = (hex: string) => { |
|
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); |
|
|
return result ? { |
|
|
r: parseInt(result[1], 16), |
|
|
g: parseInt(result[2], 16), |
|
|
b: parseInt(result[3], 16) |
|
|
} : null; |
|
|
}; |
|
|
|
|
|
const rgbToHex = (r: number, g: number, b: number) => { |
|
|
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); |
|
|
}; |
|
|
|
|
|
const rgb = hexToRgb(primaryColor); |
|
|
if (!rgb) { |
|
|
|
|
|
const greenIntensities = ['#0e4429', '#006d32', '#26a641', '#39d353']; |
|
|
return greenIntensities[Math.min(level - 1, 3)]; |
|
|
} |
|
|
|
|
|
|
|
|
let intensityMultipliers: number[]; |
|
|
|
|
|
if (isDarkMode) { |
|
|
|
|
|
intensityMultipliers = [0.4, 0.6, 0.8, 1.0]; |
|
|
} else { |
|
|
|
|
|
intensityMultipliers = [1.0, 0.8, 0.6, 0.4]; |
|
|
} |
|
|
|
|
|
const multiplier = intensityMultipliers[Math.min(level - 1, 3)]; |
|
|
|
|
|
const adjustedR = Math.round(rgb.r * multiplier); |
|
|
const adjustedG = Math.round(rgb.g * multiplier); |
|
|
const adjustedB = Math.round(rgb.b * multiplier); |
|
|
|
|
|
return rgbToHex(adjustedR, adjustedG, adjustedB); |
|
|
}; |
|
|
|
|
|
export const getEmptyDotColors = () => ({ |
|
|
dark: EMPTY_DOT_DARK, |
|
|
light: EMPTY_DOT_LIGHT, |
|
|
}); |
|
|
|
|
|
export const getEmptyDotClasses = () => "bg-[#d1d5db] dark:bg-[#374151]"; |