File size: 5,491 Bytes
ab59545
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { getSpectrumColor } from './wavelengthUtils.js';

export class SpectrumDisplayComponent {
    constructor(dataManager) {
        this.dataManager = dataManager;
        this.infoPanel = document.getElementById('info-panel');
        this.elementName = document.getElementById('element-name');
        this.elementDetails = document.getElementById('element-details');
        this.spectrumContainer = document.getElementById('spectrum-container');
    }

    showSpectrum(symbol) {
        const elementData = this.dataManager.getElementData(symbol);
        
        if (!elementData) {
            this.showNoData(symbol);
            return;
        }

        // Update element info
        this.elementName.textContent = elementData.name;
        this.elementDetails.textContent = `Symbol: ${elementData.symbol} | Atomic Number: ${elementData.atomicNumber}`;

        // Create spectrum visualization
        this.createSpectralLines(elementData.spectralLines);

        // Show panel
        this.infoPanel.classList.remove('hidden');
    }

    hideSpectrum() {
        this.infoPanel.classList.add('hidden');
        this.spectrumContainer.innerHTML = '';
    }

    createSpectralLines(lines) {
        this.spectrumContainer.innerHTML = '';

        if (!lines || lines.length === 0) {
            this.spectrumContainer.innerHTML = '<p>No spectral data available</p>';
            return;
        }

        // Sort by intensity and limit to top 20
        const sortedLines = [...lines].sort((a, b) => (b.intensity || 0) - (a.intensity || 0));
        const displayLines = sortedLines.slice(0, 20);

        // Create canvas for spectrum
        const canvas = document.createElement('canvas');
        canvas.width = 360;
        canvas.height = 200;
        canvas.style.width = '100%';
        canvas.style.border = '1px solid rgba(255, 255, 255, 0.2)';
        canvas.style.borderRadius = '5px';
        
        const ctx = canvas.getContext('2d');
        
        // Draw background
        ctx.fillStyle = '#000';
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        // Find wavelength range
        const wavelengths = displayLines.map(l => l.wavelength);
        const minWave = Math.min(...wavelengths, 380);
        const maxWave = Math.max(...wavelengths, 750);
        const range = maxWave - minWave;

        // Draw wavelength scale
        ctx.fillStyle = '#666';
        ctx.font = '10px Arial';
        ctx.textAlign = 'center';
        for (let w = Math.ceil(minWave / 50) * 50; w <= maxWave; w += 50) {
            const x = ((w - minWave) / range) * (canvas.width - 40) + 20;
            ctx.fillRect(x, canvas.height - 20, 1, 10);
            ctx.fillText(w + 'nm', x, canvas.height - 5);
        }

        // Draw spectral lines
        displayLines.forEach(line => {
            const { color, opacity } = getSpectrumColor(line.wavelength);
            const x = ((line.wavelength - minWave) / range) * (canvas.width - 40) + 20;
            const height = (line.intensity || 0.5) * 140;

            ctx.fillStyle = `rgba(${Math.floor(color.r * 255)}, ${Math.floor(color.g * 255)}, ${Math.floor(color.b * 255)}, ${opacity})`;
            ctx.fillRect(x - 2, canvas.height - 30 - height, 4, height);

            // Draw wavelength label for prominent lines
            if (line.intensity > 0.5) {
                ctx.fillStyle = '#fff';
                ctx.font = '9px Arial';
                ctx.save();
                ctx.translate(x, canvas.height - 35 - height);
                ctx.rotate(-Math.PI / 2);
                ctx.fillText(line.wavelength.toFixed(1), 0, 0);
                ctx.restore();
            }
        });

        this.spectrumContainer.appendChild(canvas);

        // Add line details
        const detailsDiv = document.createElement('div');
        detailsDiv.style.marginTop = '10px';
        detailsDiv.style.fontSize = '12px';
        detailsDiv.style.maxHeight = '200px';
        detailsDiv.style.overflowY = 'auto';
        
        detailsDiv.innerHTML = '<h3 style="margin-bottom: 10px;">Spectral Lines:</h3>';
        
        displayLines.forEach(line => {
            const lineDiv = document.createElement('div');
            lineDiv.style.marginBottom = '5px';
            lineDiv.style.padding = '5px';
            lineDiv.style.background = 'rgba(255, 255, 255, 0.05)';
            lineDiv.style.borderRadius = '3px';
            
            const { color } = getSpectrumColor(line.wavelength);
            const colorBox = `<span style="display: inline-block; width: 12px; height: 12px; background: rgb(${Math.floor(color.r * 255)}, ${Math.floor(color.g * 255)}, ${Math.floor(color.b * 255)}); border: 1px solid #fff; margin-right: 5px;"></span>`;
            
            lineDiv.innerHTML = `${colorBox}${line.wavelength.toFixed(1)} nm (Intensity: ${(line.intensity || 0).toFixed(2)})${line.transition ? ' - ' + line.transition : ''}`;
            detailsDiv.appendChild(lineDiv);
        });

        this.spectrumContainer.appendChild(detailsDiv);
    }

    showNoData(symbol) {
        this.elementName.textContent = symbol;
        this.elementDetails.textContent = 'Element information';
        this.spectrumContainer.innerHTML = '<p>Spectral data not available for this element</p>';
        this.infoPanel.classList.remove('hidden');
    }
}