diff --git a/index.html b/index.html index dd95cea..b5a6cfe 100644 --- a/index.html +++ b/index.html @@ -11,9 +11,8 @@ - - - + +
@@ -88,12 +87,13 @@Breach ID | Breach Date | Company Name | +Industry | Employee Count | Affected Customers | Data Type | @@ -142,7 +142,7 @@${entry.breach_id} | +${entry.breach_data} | +${entry.company_name} | +${entry.industry} | +${entry.employee_count} | +${entry.affected_customers} | +${entry.data_type} | +${entry.data_stolen} | +${entry.attack_type} | +${entry.attack_vector} | +${entry.response_time} | +${entry.response_cost} | +${entry.notification_method} | +${entry.investigation_status} | +${entry.breach_location} | +${entry.breach_country} | + `; + tableBody.appendChild(row); + }); + + const prevBtn = document.getElementById('prevBtn'); + const nextBtn = document.getElementById('nextBtn'); + + prevBtn.disabled = page === 1; + nextBtn.disabled = endIndex >= data.length; + }; + + const createStackedBarChart = () => { + const breachesByIndustry = {}; + + data.forEach(entry => { + const industry = entry.industry; + const breachType = entry.breach_type; + + if (!breachesByIndustry[industry]) { + breachesByIndustry[industry] = {}; + } + + if (!breachesByIndustry[industry][breachType]) { + breachesByIndustry[industry][breachType] = 1; + } else { + breachesByIndustry[industry][breachType]++; + } + }); + + const labels = Object.keys(breachesByIndustry); + const datasets = Object.keys(data.reduce((acc, entry) => ({ ...acc, [entry.breach_type]: true }), {})).map(breachType => ({ + label: breachType, + data: labels.map(industry => breachesByIndustry[industry][breachType] || 0), + })); + + const ctx = document.getElementById('stackedBarChart').getContext('2d'); + + new Chart(ctx, { + type: 'bar', + data: { + labels: labels, + datasets: datasets.map((dataset, index) => ({ + label: dataset.label, + data: dataset.data, + backgroundColor: `hsla(${(index * 50) % 360}, 70%, 50%, 0.8)`, // Adjust color as needed + })), + }, + options: { + scales: { + x: { stacked: true }, + y: { stacked: true }, + }, + }, + }); + }; + + const renderPieChart = () => { + const breachTypeCounts = countBreachTypes(data); + const labels = Object.keys(breachTypeCounts); + const counts = Object.values(breachTypeCounts); + + const ctx = document.getElementById('breachPieChart').getContext('2d'); + new Chart(ctx, { + type: 'pie', + data: { + labels: labels, + datasets: [{ + label: 'Breach Types', + data: counts, + backgroundColor: [ + 'rgba(255, 99, 132, 0.8)', + 'rgba(54, 162, 235, 0.8)', + 'rgba(255, 206, 86, 0.8)', + 'rgba(75, 192, 192, 0.8)', + ], + }], + }, + }); + }; + + const countBreachTypes = (data) => { + const counts = {}; + data.forEach(entry => { + const type = entry.attack_type; + if (counts[type]) { + counts[type]++; + } else { + counts[type] = 1; + } + }); + return counts; + }; + + document.getElementById('prevBtn').addEventListener('click', () => { + if (currentPage > 1) { + currentPage--; + displayData(currentPage); + } + }); + + document.getElementById('nextBtn').addEventListener('click', () => { + const totalPages = Math.ceil(data.length / perPage); + if (currentPage < totalPages) { + currentPage++; + displayData(currentPage); + } + }); + const renderMap = async () => { + mapboxgl.accessToken = 'pk.eyJ1Ijoia3VibG8iLCJhIjoiY2xyMTdsNzB5MG1hbzJscG5iamd3ejBmaSJ9.0UcVFIoilWiDqg52khwJxQ'; // Replace with your Mapbox access token + + const map = new mapboxgl.Map({ + container: 'map', + style: 'mapbox://styles/mapbox/streets-v11', // Choose a map style + center: [0, 0], // Initial map center coordinates [longitude, latitude] + zoom: 1, // Initial zoom level + }); + + + + map.on('load', async () => { + // Loop through data to plot breach locations + for (const entry of data) { + if (entry.breach_location && entry.breach_country) { + try { + // Log data before geocoding request + console.log('Geocoding:', entry.breach_location, entry.breach_country); + const countryCode = await getCountryCode(entry.breach_country); + + if (!countryCode) { + console.error('Unknown country code for:', entry.breach_country); + continue; // Skip geocoding if country code is unknown + } + + const response = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(entry.breach_location)}.json?country=${entry.breach_country}&access_token=${mapboxgl.accessToken}`); + const geoData = await response.json(); + + if (geoData.features && geoData.features.length > 0) { + const coordinates = geoData.features[0].center; + const popupText = `${entry.breach_location}, ${entry.breach_country}`; + + // Add marker at the geocoded coordinates + new mapboxgl.Marker() + .setLngLat(coordinates) + .setPopup(new mapboxgl.Popup().setText(popupText)) + .addTo(map); + } else { + console.error('No coordinates found for:', entry.breach_location); + } + } catch (error) { + console.error('Error geocoding:', error); + } + } + } + }); + }; + + fetchAndDisplayData(); + renderMap(); // Call the renderMap function after fetching the data +}); \ No newline at end of file diff --git a/script/fetchv6.js b/script/fetchv6.js index 83072a6..bf28eb0 100644 --- a/script/fetchv6.js +++ b/script/fetchv6.js @@ -1,27 +1,3 @@ -// Function to fetch country codes from JSON file -const fetchCountryCodes = async () => { - try { - const response = await fetch('countries.json'); - const countryCodes = await response.json(); - return countryCodes; - } catch (error) { - console.error('Error fetching country codes:', error); - return {}; - } -}; - -// Function to convert country name to country code -const getCountryCode = async (countryName) => { - const countryCodes = await fetchCountryCodes(); - - const countryCode = countryCodes[countryName]; - if (!countryCode) { - console.error('Unknown country code for:', countryName); - } - - return countryCode; -}; - document.addEventListener('DOMContentLoaded', async () => { let data = []; let currentPage = 1; @@ -29,7 +5,7 @@ document.addEventListener('DOMContentLoaded', async () => { const fetchAndDisplayData = async () => { try { - const response = await fetch('https://my.api.mockaroo.com/ewd.json?key=c528a930'); + const response = await fetch('https://my.api.mockaroo.com/EWD.json?key=f8ab4540'); data = await response.json(); displayData(currentPage); renderPieChart(); @@ -54,6 +30,7 @@ document.addEventListener('DOMContentLoaded', async () => {${entry.breach_id} | ${entry.breach_data} | ${entry.company_name} | +${entry.industry} | ${entry.employee_count} | ${entry.affected_customers} | ${entry.data_type} | @@ -108,7 +85,7 @@ document.addEventListener('DOMContentLoaded', async () => { data: { labels: labels, datasets: datasets.map((dataset, index) => ({ - label: dataset.label, + label: "Breaches", data: dataset.data, backgroundColor: `hsla(${(index * 50) % 360}, 70%, 50%, 0.8)`, // Adjust color as needed })), @@ -173,55 +150,30 @@ document.addEventListener('DOMContentLoaded', async () => { displayData(currentPage); } }); - const renderMap = async () => { - mapboxgl.accessToken = 'pk.eyJ1Ijoia3VibG8iLCJhIjoiY2xyMTdsNzB5MG1hbzJscG5iamd3ejBmaSJ9.0UcVFIoilWiDqg52khwJxQ'; // Replace with your Mapbox access token - const map = new mapboxgl.Map({ - container: 'map', - style: 'mapbox://styles/mapbox/streets-v11', // Choose a map style - center: [0, 0], // Initial map center coordinates [longitude, latitude] - zoom: 1, // Initial zoom level - }); - - - - map.on('load', async () => { - // Loop through data to plot breach locations - for (const entry of data) { - if (entry.breach_location && entry.breach_country) { - try { - // Log data before geocoding request - console.log('Geocoding:', entry.breach_location, entry.breach_country); - const countryCode = await getCountryCode(entry.breach_country); - - if (!countryCode) { - console.error('Unknown country code for:', entry.breach_country); - continue; // Skip geocoding if country code is unknown - } + const renderMap = async () => { + const myMap = L.map('map').setView([0, 0], 2); + L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(myMap); - const response = await fetch(`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(entry.breach_location)}.json?country=${entry.breach_country}&access_token=${mapboxgl.accessToken}`); - const geoData = await response.json(); + const attackCities = data.filter(entry => entry.breach_location && entry.breach_country); - if (geoData.features && geoData.features.length > 0) { - const coordinates = geoData.features[0].center; - const popupText = `${entry.breach_location}, ${entry.breach_country}`; + for (const entry of attackCities) { + const { breach_location: city, breach_country: country } = entry; - // Add marker at the geocoded coordinates - new mapboxgl.Marker() - .setLngLat(coordinates) - .setPopup(new mapboxgl.Popup().setText(popupText)) - .addTo(map); - } else { - console.error('No coordinates found for:', entry.breach_location); - } - } catch (error) { - console.error('Error geocoding:', error); - } + try { + const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${city},${country}&limit=1`); + const data = await response.json(); + + if (data && data.length > 0) { + const { lat, lon } = data[0]; + const marker = L.marker([lat, lon]).addTo(myMap).bindPopup(`${city}, ${country}`); } + } catch (error) { + console.error('Error fetching coordinates:', error); } - }); + } }; + fetchAndDisplayData(); - renderMap(); // Call the renderMap function after fetching the data }); \ No newline at end of file diff --git a/script/pop-up.js b/script/pop-up.js deleted file mode 100644 index ffc97ff..0000000 --- a/script/pop-up.js +++ /dev/null @@ -1,7 +0,0 @@ -$(document).ready(function(){ - // Handle button clicks - $(".read-more-btn").click(function(){ - var contentBlock = $(this).siblings(".card-body").html(); - $("#modalBody").html(contentBlock); - }); - }); \ No newline at end of file diff --git a/style.css b/style.css index 5e52b74..51a72b6 100644 --- a/style.css +++ b/style.css @@ -48,12 +48,3 @@ nav > a{ left: 50%; transform: translate(-50%, -50%); } -#map { - width: 100%; - height: 400px; -} - -.enlarged-modal .modal-dialog { - max-width: 90%; - margin: 30px auto; - } \ No newline at end of file
---|