{"id":23254,"date":"2025-08-12T19:55:55","date_gmt":"2025-08-12T11:55:55","guid":{"rendered":"https:\/\/www.odychina.com\/?page_id=23254"},"modified":"2025-09-09T19:42:10","modified_gmt":"2025-09-09T11:42:10","slug":"china-weather","status":"publish","type":"page","link":"https:\/\/www.odychina.com\/ja\/china-weather","title":{"rendered":"\u4e2d\u56fd\u306e14\u65e5\u9593\u306e\u73fe\u5730\u5929\u6c17\u4e88\u5831 | \u5b89\u5fc3\u3057\u3066\u65c5\u884c\u3092\u8a08\u753b\u3057\u307e\u3057\u3087\u3046"},"content":{"rendered":"<div id=\"weather-dashboard\">\n    <p>\u5f53\u793e\u306f\u3001\u30bf\u30a4\u30e0\u30ea\u30fc\u3067\u73fe\u5730\u306b\u5408\u308f\u305b\u305f\u4e88\u5831\u3092\u63d0\u4f9b\u3059\u308b\u3053\u3068\u3067\u3001\u304a\u5ba2\u69d8\u306e\u4e2d\u56fd\u65c5\u884c\u304c\u3088\u308a\u30b9\u30e0\u30fc\u30ba\u3067\u697d\u3057\u3044\u3082\u306e\u3068\u306a\u308b\u3088\u3046\u52aa\u3081\u3066\u3044\u307e\u3059\u3002<\/p>\n    <label>\u4eba\u6c17\u306e\u90fd\u5e02:<\/label>\n    <div id=\"quickCities\" style=\"background:#f9f9f9;padding:5px;margin-bottom:10px;display:grid;grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));gap:3px;border-radius:5px;\">\n        <span class=\"quick-city\" data-city=\"101020100\">\u4e0a\u6d77<\/span>\n        <span class=\"quick-city\" data-city=\"101210101\">\u676d\u5dde<\/span>\n        <span class=\"quick-city\" data-city=\"101190401\">\u8607\u5dde<\/span>\n        <span class=\"quick-city\" data-city=\"101010100\">\u5317\u4eac<\/span>\n        <span class=\"quick-city\" data-city=\"101110101\">\u897f\u5b89<\/span>\n        <span class=\"quick-city\" data-city=\"101120201\">\u9752\u5cf6<\/span>\n        <span class=\"quick-city\" data-city=\"101280101\">\u5e83\u5dde<\/span>\n        <span class=\"quick-city\" data-city=\"101280601\">\u6df1\u5733<\/span>\n        <span class=\"quick-city\" data-city=\"101320101\">\u9999\u6e2f<\/span>\n        <span class=\"quick-city\" data-city=\"101270101\">\u6210\u90fd<\/span>\n        <span class=\"quick-city\" data-city=\"101040100\">\u91cd\u6176<\/span> \n        <span class=\"quick-city\" data-city=\"101290101\">\u6606\u660e<\/span> \n    <\/div>\n\n        <style>\n            #quickCities .quick-city {padding:5px 12px;cursor:pointer;background:#eee;color:#000;border-radius:4px;transition: background 0.2s, color 0.2s;font-weight:500;}\n            #quickCities .quick-city:hover,#quickCities .quick-city.active{background:#333;color:#fff;}\n            .cell-line { display:block; line-height:1.2; }\n        <\/style>\n\n        <form id=\"cityForm\" style=\"display:flex; align-items:center; gap:10px; margin-bottom:10px;\">\n            <label>\u884c\u304d\u5148:<\/label>\n            <select name=\"city_id\" id=\"citySelect\">\n                <option value=\"101020100\">\u4e0a\u6d77<\/option>\n                <option value=\"101010100\">\u5317\u4eac<\/option>\n                <option value=\"101060101\">\u9577\u6625<\/option>\n                <option value=\"101250101\">\u9577\u6c99<\/option>\n                <option value=\"101270101\">\u6210\u90fd<\/option>\n                <option value=\"101040100\">\u91cd\u6176<\/option>\n                <option value=\"101290201\">\u5927\u7406<\/option>\n                <option value=\"101070201\">\u5927\u9023<\/option>\n                <option value=\"101100201\">\u5927\u540c<\/option>\n                <option value=\"101160808\">\u6566\u714c<\/option>\n                <option value=\"101280800\">\u4ecf\u5c71<\/option>\n                <option value=\"101230101\">\u798f\u5dde<\/option>\n                <option value=\"101340201\">\u9ad8\u96c4<\/option>\n                <option value=\"101280101\">\u5e83\u5dde<\/option>\n                <option value=\"101260101\">\u8cb4\u967d<\/option>\n                <option value=\"101310101\">\u6d77\u53e3<\/option>\n                <option value=\"101210101\">\u676d\u5dde<\/option>\n                <option value=\"101050101\">\u30cf\u30eb\u30d3\u30f3<\/option>\n                <option value=\"101220101\">\u5408\u80a5<\/option>\n                <option value=\"101080101\">\u30d5\u30d5\u30db\u30c8<\/option>\n                <option value=\"101320101\">\u9999\u6e2f<\/option>\n                <option value=\"101221002\">\u9ec4\u5c71<\/option>\n                <option value=\"101210201\">\u6e56\u5dde<\/option>\n                <option value=\"101120101\">\u6e08\u5357<\/option>\n                <option value=\"101271906\">\u4e5d\u5be8\u6e9d<\/option>\n                <option value=\"101290101\">\u6606\u660e<\/option>\n                <option value=\"101160101\">\u862d\u5dde<\/option>\n                <option value=\"101140101\">\u30e9\u30b5<\/option>\n                <option value=\"101291401\">\u9e97\u6c5f<\/option>\n                <option value=\"101180901\">\u6d1b\u967d<\/option>\n                <option value=\"101330101\">\u30de\u30ab\u30aa<\/option>\n                <option value=\"101120801\">\u6cf0\u5c71<\/option>\n                <option value=\"101240101\">\u5357\u660c<\/option>\n                <option value=\"101190101\">\u5357\u4eac<\/option>\n                <option value=\"101210401\">\u5be7\u6ce2<\/option>\n                <option value=\"101100410\">\u5e73\u9065<\/option>\n                <option value=\"101120201\">\u9752\u5cf6<\/option>\n                <option value=\"101230501\">\u6cc9\u5dde<\/option>\n                <option value=\"101310201\">\u4e09\u4e9c<\/option>\n                <option value=\"101070101\">\u700b\u967d<\/option>\n                <option value=\"101280601\">\u6df1\u5733<\/option>\n                <option value=\"101090101\">\u77f3\u5bb6\u8358<\/option>\n                <option value=\"101190401\">\u8607\u5dde<\/option>\n                <option value=\"101340102\">\u53f0\u5317<\/option>\n                <option value=\"101100101\">\u592a\u539f<\/option>\n                <option value=\"101200901\">\u4e09\u5ce1<\/option>\n                <option value=\"101030100\">\u5929\u6d25<\/option>\n                <option value=\"101130101\">\u30a6\u30eb\u30e0\u30c1<\/option>\n                <option value=\"101121301\">\u5a01\u6d77<\/option>\n                <option value=\"101210701\">\u6e29\u5dde<\/option>\n                <option value=\"101200101\">\u6b66\u6f22<\/option>\n                <option value=\"101190201\"> \u7121\u932b<\/option>\n                <option value=\"101110101\">\u897f\u5b89<\/option>\n                <option value=\"101230201\">\u53a6\u9580<\/option>\n                <option value=\"101150101\">\u897f\u5be7<\/option>\n                <option value=\"101300510\">\u967d\u6714<\/option>\n                <option value=\"101190601\">\u63da\u5dde<\/option>\n                <option value=\"101120501\"> \u7159\u53f0<\/option>\n                <option value=\"101170101\">\u9280\u5ddd<\/option>\n                <option value=\"101210904\">\u7fa9\u70cf<\/option>\n                <option value=\"101251101\">\u5f35\u5bb6\u754c<\/option>\n                <option value=\"101180101\">\u912d\u5dde<\/option>\n                <option value=\"101281701\">\u4e2d\u5c71<\/option>\n                <option value=\"101280701\">\u73e0\u6d77<\/option>\n            <\/select>\n\n            <label>\u6e29\u5ea6:<\/label>\n            <select id=\"unitSelect\">\n                <option value=\"\u00b0C\" selected>\u00b0C<\/option>\n                <option value=\"\u00b0F\">\u00b0F<\/option>\n            <\/select>\n        <\/form>\n\n        <h3 id=\"chartTitle\"><\/h3>\n        <canvas id=\"weatherChart\" style=\"height:300px;\"><\/canvas>\n        <hr style=\"border: none; border-top: 1px solid #e0e0e0; margin: 10px 0;\">\n        <p style=\"font-size:0.9em; color:#999;\">\n        \u3053\u306e\u9577\u671f\u4e88\u6e2c\u306f\u5168\u4f53\u7684\u306a\u50be\u5411\u3092\u793a\u3057\u3066\u3044\u307e\u3059\u3002<br>\u65e5\u3005\u306e\u5929\u6c17\u306f\u5909\u5316\u3059\u308b\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u306e\u3067\u3001\u4e0b\u8a18\u306e14\u65e5\u9593\u306e\u8a73\u7d30\u306a\u4e88\u5831\u3092\u3054\u78ba\u8a8d\u304f\u3060\u3055\u3044\u3002<br>Odychina.com\u63d0\u4f9b\n        <\/p>\n\n        <h3 id=\"tableTitle\"><\/h3>\n        <table border=\"1\" cellpadding=\"2\" cellspacing=\"0\" style=\"border-collapse: collapse;width:100%;font-size:14px; line-height:1.4;\" id=\"weatherTable\">\n            <tr>\n                <th>\ud83d\udcc5 <br>\u65e5\u4ed8\u2002\u2002<\/th>\n                <th>\ud83c\udf24\ufe0f <br>\u5929\u6c17<\/th>\n                <th>\ud83c\udf21\ufe0f\u6e29\u5ea6<br><span style=\"color:#d62828\">\u25b2 <\/span>\/<span style=\"color:#f77f00\">\u25bc <\/span><\/th>\n                <th>\ud83d\udca7 \u6e7f\u5ea6(RH)\u2002\u2002<br><span style=\"color:#1d3557\">\u25b2 <\/span>\/<span style=\"color:#a8dadc\">\u25bc <\/span><\/th>\n                <th>\ud83d\udd05 \u592a\u967d<br><span style=\"color:red\">\ud83c\udf05<\/span>\/<span style=\"color:black\">\ud83c\udf07 <\/span><\/th>\n                <th>\ud83d\ude37 AQI <br>\ud83c\udf00 \u98a8\u529b<\/th>\n            <\/tr>\n        <\/table>\n\n        <hr style=\"border: none; border-top: 1px solid #e0e0e0; margin: 10px 0;\">\n        <p style=\"font-size:0.9em; color:#999;\">\n        14\u65e5\u9593\u306e\u5929\u6c17\u4e88\u5831\u3092\u6d3b\u7528\u3057\u3066\u3001\u5192\u967a\u306e\u8a08\u753b\u3092\u7acb\u3066\u307e\u3057\u3087\u3046\uff01\n7\u65e5\u3092\u8d85\u3048\u308b\u4e88\u6e2c\u306f\u4e0d\u78ba\u5b9f\u6027\u304c\u751f\u3058\u308b\u5834\u5408\u304c\u3042\u308a\u307e\u3059\u3002\n\u5929\u6c17\u4e88\u5831\u306f\u53c2\u8003\u60c5\u5831\u3068\u3057\u3066\u306e\u307f\u63d0\u4f9b\u3055\u308c\u3066\u304a\u308a\u3001\u3044\u304b\u306a\u308b\u7d50\u679c\u306b\u3064\u3044\u3066\u3082\u8cac\u4efb\u3092\u8ca0\u3044\u307e\u305b\u3093\u3002\n        <\/p>\n    <\/div>\n<style>\n#weatherChart {\n  width: 100% !important;\n}\n<\/style>\n\n  <script>\n(function($){\n    let chart = null;\n    let rawTempMaxValues = [], rawTempMinValues = [], rawHumMaxValues = [], rawHumMinValues = [];\n    let _rawTempMin = null, _rawTempMax = null;\n\n    function cToF(c){ return Number((c * 9\/5 + 32).toFixed(1)); }\n\n    \/\/ \u6839\u636e\u6d4f\u89c8\u5668\u672c\u5730\u5316\u683c\u5f0f\u5316\u65e5\u671f\n    function formatDate(d){\n        const dateObj = new Date(d);\n        const locale = navigator.language || 'en-US';\n        return dateObj.toLocaleDateString(locale, {\n            weekday: 'short',\n            month: 'short',\n            day: 'numeric'\n        });\n    }\n\n    function renderTable(data, unit){\n        const table = $(\"#weatherTable\");\n        table.find(\"tr:gt(0)\").remove();\n\n        data.forEach(d => {\n            const formattedDate = formatDate(d.date);\n            const hi = unit === '\u00b0F' ? cToF(d.tempMax) : d.tempMax;\n            const lo = unit === '\u00b0F' ? cToF(d.tempMin) : d.tempMin;\n\n            table.append(`<tr>\n                <td><span class=\"cell-line\">${formattedDate}<\/span><\/td>\n                <td>${d.condition}<\/td>\n                <td class=\"temp-cell\">\n                    <span class=\"cell-line\">${hi}${unit}<\/span>\n                    <span class=\"cell-line\">${lo}${unit}<\/span>\n                <\/td>\n                <td>\n                    <span class=\"cell-line\">${d.humidityMax}%<\/span>\n                    <span class=\"cell-line\">${d.humidityMin}%<\/span>\n                <\/td>\n                <td>\n                    <span class=\"cell-line\">${d.sunrise}<\/span>\n                    <span class=\"cell-line\">${d.sunset}<\/span>\n                <\/td>\n                <td>\n                    <span class=\"cell-line\">${d.aqi}<\/span>\n                    <span class=\"cell-line\">${d.wind}<\/span>\n                <\/td>\n            <\/tr>`);\n        });\n    }\n\n    function normalizePair(maxArray, minArray, targetMin, targetMax){\n        const combined = maxArray.concat(minArray).map(Number);\n        const rawMin = Math.min(...combined);\n        const rawMax = Math.max(...combined);\n        _rawTempMin = rawMin;\n        _rawTempMax = rawMax;\n\n        if (rawMax === rawMin) {\n            const mid = (targetMin + targetMax) \/ 2;\n            return { max: maxArray.map(()=>mid), min: minArray.map(()=>mid), rawMin, rawMax };\n        }\n\n        const range = rawMax - rawMin;\n        const mapVal = v => targetMin + ((Number(v) - rawMin) \/ range) * (targetMax - targetMin);\n        return { max: maxArray.map(mapVal), min: minArray.map(mapVal), rawMin, rawMax };\n    }\n\n    function renderChart(data, unit){\n        const labels = data.map(d => formatDate(d.date));\n\n        rawTempMaxValues = unit === '\u00b0F' ? data.map(d => cToF(d.tempMax)) : data.map(d => Number(d.tempMax));\n        rawTempMinValues = unit === '\u00b0F' ? data.map(d => cToF(d.tempMin)) : data.map(d => Number(d.tempMin));\n        rawHumMaxValues = data.map(d => Number(d.humidityMax));\n        rawHumMinValues = data.map(d => Number(d.humidityMin));\n\n        const normTempPair = normalizePair(rawTempMaxValues, rawTempMinValues, 50, 100);\n        const normTempsMax = normTempPair.max;\n        const normTempsMin = normTempPair.min;\n\n        const normHumMax = rawHumMaxValues.map(v => Number(v)\/2);\n        const normHumMin = rawHumMinValues.map(v => Number(v)\/2);\n\n        const ctx = document.getElementById('weatherChart').getContext('2d');\n\n        if(chart){\n            chart.destroy();\n            chart = null;\n        }\n\n        chart = new Chart(ctx, {\n            type: 'line',\n            data: {\n                labels: labels,\n                datasets: [\n                    { \n                            label: \"\u6700\u9ad8\u6c17\u6e29 (\" + unit + \")\", \n                            data: normTempsMax, borderColor:'#d62828', backgroundColor:'#d62828', fill:false, tension:0.3, pointRadius:3, yAxisID:'yMain' \n                        },\n                        { \n                            label: \"\u6700\u4f4e\u6c17\u6e29 (\" + unit + \")\", \n                            data: normTempsMin, borderColor:'#f77f00', backgroundColor:'#f77f00', fill:false, tension:0.3, pointRadius:3, yAxisID:'yMain' \n                        },\n                        { \n                            label: \"\u6700\u9ad8\u6e7f\u5ea6 (%)\", \n                            data: normHumMax, borderColor:'#1d3557', backgroundColor:'#1d3557', fill:false, borderDash:[5,5], tension:0.3, pointRadius:3, yAxisID:'yMain' \n                        },\n                        { \n                            label: \"\u6700\u4f4e\u6e7f\u5ea6 (%)\", \n                            data: normHumMin, borderColor:'#a8dadc', backgroundColor:'#a8dadc', fill:false, borderDash:[5,5], tension:0.3, pointRadius:3, yAxisID:'yMain' \n                        }\n                ]\n            },\n            options: {\n                responsive: true,\n                maintainAspectRatio: true,\n                aspectRatio: 1.5,\n                plugins: {\n                    legend: { position: 'top', labels: { boxWidth: 45, padding: 10, font:{size:12}, maxWidth:120 } },\n                    tooltip: {\n                        callbacks: {\n                            label: function(context){\n                                const ds = context.datasetIndex;\n                                const idx = context.dataIndex;\n                                if(ds===0) return \"\u6700\u9ad8\u6c17\u6e29: \" + rawTempMaxValues[idx] + \" \" + unit;\n                                if(ds===1) return \"\u6700\u4f4e\u6c17\u6e29: \" + rawTempMinValues[idx] + \" \" + unit;\n                                if(ds===2) return \"\u6700\u9ad8\u6e7f\u5ea6: \" + rawHumMaxValues[idx] + \"%\";\n                                if(ds===3) return \"\u6700\u4f4e\u6e7f\u5ea6: \" + rawHumMinValues[idx] + \"%\";\n                                return '';\n                            }\n                        }\n                    }\n                },\n                scales: {\n                    x: { ticks:{ maxRotation:45, minRotation:45 } },\n                    yMain: {\n                        type:'linear', min:0, max:100,\n                        ticks:{\n                            stepSize:10,\n                            callback: function(value){\n                                if(value>=50){\n                                    if(_rawTempMax===null||_rawTempMin===null) return '';\n                                    if(_rawTempMax===_rawTempMin) return _rawTempMax+' '+unit;\n                                    const frac = (value-50)\/50;\n                                    const tempVal = _rawTempMin + frac*(_rawTempMax-_rawTempMin);\n                                    return Math.round(tempVal*10)\/10+' '+unit;\n                                }else{\n                                    return Math.round(value*2)+'%';\n                                }\n                            },\n                            color:function(context){ return context.tick.value>=50?'#d62828':'#1d3557'; }\n                        },\n                        grid:{\n                            color:function(context){ return context.tick && context.tick.value===50?'rgba(0,0,0,0.25)':'rgba(0,0,0,0.08)'; }\n                        },\n                        title:{ display:true, text:\"\u4e0b\u6bb5: \u6e7f\u5ea6 (%) \u00b7 \u4e0a\u6bb5: \u6e29\u5ea6 (\" + unit + \")\",   color:'#333' \n                        }\n\n                    }\n                }\n            }\n        });\n\n        function adjustChartWidth(){\n            const containerWidth = $(\"#weatherChart\").parent().width();\n            chart.canvas.style.width = containerWidth + 'px';\n            chart.update();\n        }\n        adjustChartWidth();\n        window.addEventListener('resize', adjustChartWidth);\n    }\n\n    function loadWeather(city_id, unit='\u00b0C'){\n        $.post('https:\/\/www.odychina.com\/wp-admin\/admin-ajax.php',{action:'get_weather_data',city_id:city_id},function(res){\n            if(res.success){\n                $(\"#chartTitle\").text($(\"#citySelect option:selected\").text()+\" 14\u65e5\u9593\u5929\u6c17\u4e88\u5831\");\n                $(\"#tableTitle\").text($(\"#citySelect option:selected\").text()+\" 14\u65e5\u9593\u4e88\u5831\");\n                renderTable(res.data, unit);\n                renderChart(res.data, unit);\n                $(\"#quickCities .quick-city\").removeClass(\"active\");\n                $(`#quickCities .quick-city[data-city=\"${city_id}\"]`).addClass(\"active\");\n            } else alert(res.data);\n        });\n    }\n\n    \/\/ init\n    loadWeather($(\"#citySelect\").val());\n    $(\"#citySelect\").on(\"change\",function(){loadWeather($(this).val(),$(\"#unitSelect\").val());});\n    $(\"#unitSelect\").on(\"change\",function(){loadWeather($(\"#citySelect\").val(),$(\"#unitSelect\").val());});\n    $(\"#quickCities .quick-city\").on(\"click\",function(){\n        const city_id=$(this).data(\"city\");\n        $(\"#citySelect\").val(city_id);\n        loadWeather(city_id,$(\"#unitSelect\").val());\n    });\n})(jQuery);\n<\/script>\n\n\n    \n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"page-planning.php","meta":{"footnotes":""},"class_list":["post-23254","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/pages\/23254","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/comments?post=23254"}],"version-history":[{"count":2,"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/pages\/23254\/revisions"}],"predecessor-version":[{"id":23260,"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/pages\/23254\/revisions\/23260"}],"wp:attachment":[{"href":"https:\/\/www.odychina.com\/ja\/wp-json\/wp\/v2\/media?parent=23254"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}