На этом веб-сайте отображается статистика по четырем темам: COVID, занятость в сельском хозяйстве, население и температура. Я знаю, кажется очень случайным да? хорошо это. Честно говоря, моей главной целью было показать использование четырех различных типов API с пятью типами HighCharts. Если вы не знаете, что такое API, ознакомьтесь с этой статьей.

Если мы рассмотрели API, что такое highcharts?

Highcharts — это библиотека диаграмм JavaScript, которая упрощает создание интерактивных, адаптивных и доступных диаграмм для ваших веб-приложений. Это бесплатная библиотека с открытым исходным кодом, но есть и платная версия с дополнительными функциями. Он поддерживает широкий спектр типов диаграмм, включая линейные диаграммы, гистограммы, круговые диаграммы, диаграммы с областями и многие другие.

Обратите внимание: для корректного отображения диаграмм в вашем браузере должна быть установлена ​​библиотека Highcharts. Вы можете сделать это, либо загрузив библиотеку на свой компьютер, если вы хотите работать в автономном режиме, либо используя приведенные ниже ссылки CDN, если у вас всегда есть подключение к Интернету.

<script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <script src="https://code.highcharts.com/modules/export-data.js"></script>
    <script src="https://code.highcharts.com/modules/accessibility.js"></script>
    <script src="http://code.highcharts.com/maps/modules/map.js"></script>

Для получения дополнительной информации посетите их веб-сайт и, в частности, их документы на HighCharts.

Вернемся к нашей точке зрения. То, что делает этот веб-сайт, очень просто. Он извлекает статистические данные из API и передает эти данные на диаграммы highcharts, чтобы их можно было отображать с использованием различных типов диаграмм.

Как видно из скриншота сайта, существует пять видов диаграмм. Первый рандомизирует отображаемые состояния. Из 56 штатов США он показывает пять данных о COVID за раз, а при нажатии кнопки рандомизации он меняет отображаемые штаты и соответствующие им данные.

Вторая диаграмма обеспечивает возможность поиска данных определенного штата по его кодовому названию штата USPS. Здесь следует отметить, что все диаграммы на этом сайте сделаны для демонстрации использования API и высоких диаграмм. Они полны описательных диаграмм с большим количеством данных.

Третий график позволяет сравнить уровень занятости в сельском хозяйстве любых двух стран за последнее десятилетие, используя их кодовые названия ISO Alpha 3.

Четвертая диаграмма отображает численность населения страны за последние шесть десятилетий. Здесь страну можно переключить на четыре варианта: Эфиопия, Кения, Уганда и Судан. Я выбрал эти страны, потому что они географические соседи, а я живу в Эфиопии (немного предвзято :) ).

Пятая и последняя диаграмма показывает мгновенную температуру в крупных городах Эфиопии.

Чтобы показать вам реализацию API и highcharts, позвольте мне показать вам, как я сделал первую, вторую и последнюю диаграмму.

Первая диаграмма

    
 async function getcharts ()  {
    let loading=document.getElementById('loading')
    loading.innerHTML=`<div class="d-flex justify-content-center">
    <div class="spinner-grow" role="status">
      <span class="visually-hidden">Loading...</span>
    </div>
  </div>`
    
                
            const response = await fetch(`https://api.covidtracking.com/v1/states/current.json`);
            if(!response.ok) {
                console.log('Error retrieving data');
                return;
            }
            const reponseData = await response.json();
            loading.innerHTML=``
            console.log(reponseData)

            let arr=[]
            let arr2=[]
            let arr3=[]
            let arr4=[]
            
            
            for(i=0;i<reponseData.length;i++){
                
                
                 arr[i]=[reponseData[i].hospitalized]
                 arr2[i]=[reponseData[i].death]
                 arr3[i]=[reponseData[i].hospitalizedCurrently]
                 arr4[i]=[reponseData[i].state]
                 
            }
               
                console.log(arr2[22])

            Highcharts.chart('container', {
    chart: {
        type: 'bar'
    },
    title: {
        text: 'CoronVirus Data US',
        align: 'left'
    },
    subtitle: {
        text: 'Source: The COVID Tracking Project',
        align: 'left'
    },
    xAxis: {
        categories: [arr4[0], arr4[1], arr4[2], arr4[5],arr4[4]],
        title: {
            text: 'Sates '
        },
        gridLineWidth: 1,
        lineWidth: 0
    },
    yAxis: {
        min: 0,
        title: {
            text: 'Population (millions)',
            align: 'high'
        },
        labels: {
            overflow: 'justify'
        },
        gridLineWidth: 0
    },
    tooltip: {
        valueSuffix: ' thousand'
    },
    plotOptions: {
        bar: {
            borderRadius: '50%',
            dataLabels: {
                enabled: true
            },
            groupPadding: 0.1
        }
    },colors: [
        'yellow',
        'black',
        'red'
        ],
    legend: {
        layout: 'vertical',
        align: 'right',
        verticalAlign: 'top',
        x: -40,
        y: 80,
        floating: true,
        borderWidth: 1,
        backgroundColor:
            Highcharts.defaultOptions.legend.backgroundColor || '#FFFFFF',
        shadow: true
    },
    credits: {
        enabled: false
    },
    series: [{
            name: 'Hospitalized',
            data:  [arr[0],arr[1],arr[2],arr[5],arr[4]]
        }, {
            name: 'Deaths',
            data: [arr2[0],arr2[1],arr2[2],arr2[5],arr2[4]]
        }, {
            name: 'Hospitalized Currently',
            data: [arr3[0],arr3[1],arr3[2],arr3[5],arr3[4]]
        }]
});
let firstChart = Highcharts.charts[0];
let btn = document.getElementById('randomize');

function changedata(){
    let rand1=Math.floor(Math.random() * 56)
    let rand2=Math.floor(Math.random() * 56)
    let rand3=Math.floor(Math.random() * 56)
    let rand4=Math.floor(Math.random() * 56)
    let rand5=Math.floor(Math.random() * 56)
    firstChart.xAxis[0].update({categories: [arr4[rand1], arr4[rand2], arr4[rand3], arr4[rand4],arr4[rand5]]})

    firstChart.series[0].update({ 
    name: 'Hospitalized',
    data:  [arr[rand1],arr[rand2],arr[rand3],arr[rand4],arr[rand5]]
})
firstChart.series[1].update({
    name: 'Deaths',
    data: [arr2[rand1],arr2[rand2],arr2[rand3],arr2[rand4],arr2[rand5]]
}) 
firstChart.series[2].update({
    name: 'Hospitalized Currently',
    data: [arr3[rand1],arr3[rand2],arr3[rand3],arr3[rand4],arr3[rand5]]
})
}

        btn.addEventListener('click', changedata)

Сначала код определяет функцию с именем getcharts(). Эта функция делает асинхронный запрос к API отслеживания COVID, чтобы получить последние данные для всех 56 штатов. Затем данные сохраняются в трех массивах: arr, arr2 и arr3. Массив arr хранит количество госпитализированных людей в каждом штате, массив arr2 хранит количество смертей в каждом штате, а массив arr3 хранит количество людей, которые в настоящее время госпитализированы в каждом штате.

Затем функция getcharts() создает гистограмму с использованием библиотеки Highcharts. Гистограмма настроена для отображения количества госпитализированных людей, смертей и людей, которые в настоящее время госпитализированы в каждом штате. Также указаны цвета полос.

load — это элемент div, который содержит загрузчик. Этот счетчик отображается во время выборки данных. Он немедленно очищается после успешного извлечения данных с помощью « loading.innerHTML = `` »

Функция getcharts() вызывается один раз в начале кода. Однако есть также кнопка с именем randomize, при нажатии которой вызывается функция changedata(). Функция changedata() случайным образом выбирает пять состояний из массива arr4 и обновляет гистограмму, чтобы показать данные для этих пяти состояний. Функция Math.floor(Math.random() * 56) возвращает случайное число от 0 до 55.

Код также определяет переменную с именем firstChart. В этой переменной хранится ссылка на первую созданную диаграмму. Затем переменная firstChart используется для вызова метода update() на гистограмме. Метод update() позволяет обновлять данные, отображаемые на гистограмме. Метод update() на гистограмме принимает два аргумента: имя ряда, который вы хотите обновить, и новые данные для ряда.

Наконец, код добавляет прослушиватель событий к кнопке randomize. Прослушиватель событий вызывает функцию changedata() при нажатии кнопки. Метод addEventListener() на кнопке принимает два аргумента: событие, которое вы хотите прослушать, и функцию, которую вы хотите вызвать, когда событие произойдет.

Вторая диаграмма

Посмотрим, как работает код,

let actualTerm='sc'
        async function generatePieChart(){
          
              const response2 = await fetch(` https://api.covidtracking.com/v1/states/${actualTerm}/current.json`);
                  if(!response2.ok) {
                      console.log('Error retrieving data');
                      return;
                  }
                  const reponseData2 = await response2.json();
                  console.log(reponseData2)
                  
                  let arrs=reponseData2
                  Highcharts.chart('container2',{
                      chart: {
                          renderTo: 'container2',
                          plotBackgroundColor: null,
                          plotBorderWidth: null,
                          plotShadow: false,
                          type: 'pie'
                      },
                      title: {
                          text: `COVID Data of the state of  ${actualTerm.toUpperCase()}`,
                          align: 'left'
                      },
                      tooltip: {
                          pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
                      },
                      accessibility: {
                          point: {
                              valueSuffix: '%'
                          }
                      },
                      plotOptions: {
                          pie: {
                              allowPointSelect: true,
                              cursor: 'pointer',
                              dataLabels: {
                                  enabled: false
                              },
                              showInLegend: true
                          }
                      },
                      colors: [
                        'blue',
                        'red',
                        'yellow',
                        'black'
                        ],
                      series: [{
                          name: 'Status',
                          colorByPoint: true,
                          data: [{
                              name: 'Hospitalized',
                              y: arrs.hospitalized
                          },  {
                              name: 'In ICU',
                              y: arrs.inIcuCurrently
                          },  {
                              name: 'On Ventilator',
                              y: arrs.onVentilatorCurrently
                          }, {
                              name: 'Deaths',
                              y: arrs.death
                          }]
                      }]
                  });
                  
            }

generatePieChart();
let searchbtn=document.getElementById('searchbtn');
        
        searchbtn.addEventListener('click',changePieChart)
function changePieChart(){
    let searchterm=document.querySelector('#searchTerm').value.toLowerCase();
    actualTerm=searchterm
generatePieChart() ;
}

Код сначала определяет переменную с именем actualTerm и инициализирует ее значением sc. Эта переменная будет использоваться для хранения имени состояния, о котором будет построена круговая диаграмма.

Следующая функция называется generatePieChart(). Эта функция делает асинхронный запрос к API отслеживания COVID, чтобы получить последние данные для состояния, указанного actualTerm. Затем данные сохраняются в переменной с именем arrs.

Затем функция generatePieChart() создает круговую диаграмму с использованием библиотеки Highcharts. Круговая диаграмма настроена так, чтобы отображать процент людей в штате, которые относятся к каждой из следующих категорий: госпитализированы, находятся в отделении интенсивной терапии, подключены к аппарату искусственной вентиляции легких и умерли. Цвета кусочков пирога также указаны.

Функция generatePieChart() вызывается один раз в начале кода. Однако есть также кнопка с именем searchbtn, при нажатии которой вызывается функция changePieChart(). Функция changePieChart() изменяет значение actualTerm на значение поля ввода текста с идентификатором searchTerm. Затем снова вызывается функция generatePieChart() для создания новой круговой диаграммы с обновленными данными.

Последняя диаграмма

Температурную диаграмму было довольно просто сделать, потому что уже была живая демонстрация карт highcharts, показывающих температуру в городах Европы. Одной из полезных функций highcharts является то, что у него есть API, который рисует карты любой страны или континента в мире, поэтому все, что мне нужно было сделать, это изменить ссылку API в демонстрации с Европы на Эфиопию и соответствующим образом изменить ряд данных.

Давайте посмотрим на код,

       (async () => {

            const topology = await fetch(
                'http://code.highcharts.com/mapdata/countries/et/et-all.topo.json'
            ).then(response => response.json());
            
            console.log(topology)
            // Data structure: [region_code, latitude, longitude, city]
            const newData = [
                ['et-2837', 9.005401, 38.763611, 'Addis Ababa'],
                ['et-ti', 13.492668, 39.479163, 'Mekelle'],
                ['et-ti', 14.12109, 38.72337, 'Aksum'],
                ['et-am', 12.600000, 37.466667, 'Gondar'],
                ['et-am', 11.6, 37.38333299999999, 'Bahir Dar'],
                ['et-am',  9.6833, 39.5333, 'Debre Berhan'],
                ['et-am',  10.35, 37.73333, 'Debre Markos'],
                ['et-be',  10.061983, 34.547301, 'Asosa'],
                ['et-ha',  9.31387, 42.11815, 'Harar'],
                ['et-aa',  7.666664, 36.83333, 'Jimma'],
                ['et-aa',   8.514477, 39.269257, 'Adama'],
                ['et-sn', 7.06205, 38.47635, 'Hawassa'],
                ['et-sn', 6.03333, 37.55, 'Arba Minch'],
                ['et-so', 9.3499986, 42.7999968, 'Jigiga'],
                ['et-so', 8.2166658, 43.5666644, 'Degehabur'],
                ['et-so', 6.7333304, 44.2666656, 'Kebri Dahar'],
                ['et-af',  11.788663512, 41.005166646, 'Semera'],
                ['et-dd', 9.6008747, 41.850142000000005, 'Dire Dawa'],
                ['et-ga', 8.5333312, 34.7999968, 'Dembidollo']
                
            ];
            // Get temperature for specific localization, and add it to the chart. It
            // takes point as first argument, regions series as second and citys
            // series as third. Cities series have to be the 'mappoint' series type,
            // and it should be defined before in the series array.
            async function getTemp(point, regionCodes, cities) {
                const json = await fetch(
                    `https://api.openweathermap.org/data/2.5/weather?lat=${point[1]}&lon=${point[2]}&APPID=8c0f84c9b29134db9870a3128a83baa5`
                ).then(response => response.json());
                console.log(json)
            
                const temp = json.main.temp
                    let valueinKelvin = parseInt(temp, 10);
                    value=valueinKelvin-273;
                
            
                const regionCode = {
                    'hc-key': point[0],
                    value
                };
                const city = {
                    name: point[3],
                    lat: point[1],
                    lon: point[2],
                    colorKey: 'y',
                    y: Number.isInteger(value) ? value : null,
                    custom: {
                        label: Number.isInteger(value) ?
                            `${value}℃` :
                            '<span style="font-weight: normal; opacity: 0.5">N/A</span>'
                    },
                };
            
                regionCodes.addPoint(regionCode);
                cities.addPoint(city);
            }
            
            // Create the chart
            Highcharts.mapChart('container5', {
                chart: {
                    map: topology,
                    events: {
                        load: function () {
                            const regionCodes = this.series[0],
                                cities = this.series[1];
                            newData.forEach(elem => getTemp(elem, regionCodes, cities));
                            this.mapZoom(1, 1000,-7500);
                        }
                    },
                    height:600,
                    style: {
                    fontSize:'12',
                    color: "#f00"
                    }

                },
            
                title: {
                    text: 'Current temperatures of Major cities in Ethiopia',
                    align: 'left'
                },
            
                subtitle: {
                    text: 'Data source: <a href="https://openweathermap.org/api">https://openweathermap.org/api</a>',
                    align: 'left'
                },
            
                mapNavigation: {
                    enabled: true,
                    buttonOptions: {
                        verticalAlign: 'bottom'
                    }
                },
            
                colorAxis: {
                    min: -25,
                    max: 40,
                    labels: {
                        format: '{value}°C'
                    },
                    stops: [
                        [0, '#0000ff'],
                        [0.3, '#6da5ff'],
                        [0.6, '#ffff00'],
                        [1, '#ff0000']
                    ]
                },
                exporting: {
                    buttons: {
                        contextButton: {
                            menuItems: ["viewFullscreen", "printChart", "downloadPNG", "downloadJPEG", "downloadPDF", "downloadSVG"],
                        }
                    }
                },
                legend: {
                    title: {
                        text: 'Degrees Celsius'
                    }
                },
            
                tooltip: {
                    headerFormat: '<span style="color:{point.color}">\u25CF</span> {point.key}:<br/>',
                    pointFormat: 'Temperature: <b>{point.custom.label}</b>'
                },
                series: [{
                    allAreas: true,
                    name: 'Temperatures in Celsius',
                    dataLabels: {
                        enabled: false
                    },
                    enableMouseTracking: false,
                    accessibility: {
                        point: {
                            valueDescriptionFormat: '{xDescription}, {point.value}°C.'
                        }
                    }
                }, {
                    name: 'Cities',
                    type: 'mappoint',
                    showInLegend: false,
                    marker: {
                        lineWidth: 2,
                        lineColor: '#000'
                    },
                    dataLabels: {
                        crop: true,
                        format: '<span>{key}</span><br><span>{point.custom.label}</span>'
                    },
                    accessibility: {
                        point: {
                            valueDescriptionFormat: '{xDescription}, {point.temp}°C.'
                        }
                    }
                }]
            });
            })();

}

Код сначала определяет функцию с именем getTemp(). Эта функция принимает три аргумента: точку, ряд regionCodes и ряд городов. Точка представляет собой массив, содержащий код региона, широту, долготу и название города для определенного местоположения. Серия regionCodes — это серия Highcharts, которая используется для отображения температуры в каждом регионе Эфиопии. Серия городов — это серия Highcharts, которая используется для отображения местоположения каждого города в Эфиопии. Массив series используется для определения серий, отображаемых на диаграмме карты.

Массив newData содержит массив точек. Каждая точка в массиве содержит код региона, широту, долготу и название города для определенного местоположения.

Функция getTemp() использует API OpenWeatherMap, чтобы получить текущую температуру для местоположения, указанного аргументом точки. Функция fetch() используется для выполнения асинхронного запроса к API OpenWeatherMap. Затем температура добавляется в ряды regionCodes и в ряды городов.

Затем код создает диаграмму карты Highcharts. Функция Highcharts.mapChart() используется для создания диаграммы карты Highcharts. Диаграмма настроена так, чтобы показывать температуру в каждом регионе Эфиопии и расположение каждого города в Эфиопии. На диаграмме также есть легенда, указывающая диапазон температур для каждого цвета.

Наконец, код вызывает функцию getTemp() для каждой точки массива newData. Это гарантирует, что температура для каждого города в Эфиопии отображается на карте.

Я попытался показать простой фрагмент того, как работает веб-сайт, если вы хотите получить более подробную информацию, перейдите по ссылке на мой репозиторий GitHub.