نظرًا لأن حكومة تايوان تضع معلومات الأرصاد الجوية والكوارث على كل صفحة ويب وفقًا لشهر/سنة أو نوع من الكوارث ، فإنها تتسبب في حدوث نفس الكارثة ، وقد يكون هناك 24 صفحة (ملف HTML واحد شهريًا) من 2014 إلى 2015 ، وهو أمر غير مريح للغاية للمعالجة. لذلك ، نستخدم API Kinomo لاستخراج وتصفية معلومات هذه الصفحات
والاندماج في نفس ملف JSON
ولكن إذا لم تستخدم وظيفة تكامل API المدمجة في Kinomo ، فستكون مصادر Ajax مبالغ فيها للغاية ، ويجب معالجة العديد من المصادر في نفس الوقت. إذا اختار المستخدم معلومات هطول الأمطار ، فسيأمل أن يرى المعلومات من 20xx إلى 2015. وبهذه الطريقة ، ستحتاج على الأرجح إلى تشغيل 2015-20xx لضرب 12 Ajax. لن يكون هذا مجرد مشكلة صالحة ، ولكن أيضًا خطأ في بناء الجملة من المتغير غير المحدد. والسبب هو أن Ajax غير متزامن ، لكن برنامج التحويل البرمجي JavaScript سيقوم بتشغيل الرمز أولاً. في هذا الوقت ، تم استخدام بعض المتغيرات في الأصل لتلقي استجابة Ajax ، ولكن نظرًا لأنه لم ينته من الجري ، لم يعود بعد. في هذا الوقت ، سيكون المتغير فارغًا أو غير محدد ، وستكون هناك مشاكل في المعالجة اللاحقة. في هذا الوقت ، يجب عليك استخدام jQuery's when () ثم () وظائف. الاستخدام كما يلي:
function taipei_rain ( type , button ) {
var deferreds = [ ] ;
var taipei_dataset = [ ] ;
var data_url = [
{
'title' : '2002_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/b5pnx91i?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2003_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/9kj2hkik?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2004_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/59qturr2?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2005_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/dmuknjqm?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2006_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/8d5ddt9u?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2007_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/ciszlrhw?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2008_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/746pie88?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2009_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/8z3bx1nq?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2010_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/crjccgkc?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2011_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/afoernpw?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2012_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/7spnhan2?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2013_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/c2lpv54u?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2014_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/c8593u62?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
} , {
'title' : '2015_taipei_rain' ,
'url' : 'https://www.kimonolabs.com/api/26rh5uwq?apikey=x3C3wO491D2hBEkPXsPJ9CgRJXzlEN8V'
}
]
var deferreds = [ ] ;
$ . each ( data_url , function ( index , stat ) {
deferreds . push (
//跑迴圈將所有的Ajax response status 存入deferred陣列之中,並當作之後when() function的參數
$ . ajax ( {
type : 'GET' ,
dataType : 'jsonp' ,
url : this . url
} )
) ;
} ) ;
// 無法把一整個陣列作為參數,因此使用apply
$ . when . apply ( $ , deferreds ) . then ( function ( ) {
// 將儲存所有Ajax response的陣列deferreds放進when()當中,當所有的Ajax皆跑完的時候,他才會跑then()中的程式碼,有效避免AJax非同步的例外狀況
for ( var j = 0 ; j < arguments . length ; j ++ ) {
var title = arguments [ j ] [ 0 ] . name ;
var data = arguments [ j ] [ 0 ] . results . collection1 ;
// 接下來就可以做自己想要的data process أصدرت الحكومة ثلاثة مستويات من المعلومات على الموقع الرسمي للبيانات المفتوحة:
حدود المقاطعة (المدينة) المناطق الإدارية
-الحدود الإدارية للبلدة (المدينة ، المدينة ، المنطقة)
خريطة حدود القرية الوطنية
بسبب الأنظمة المستخدمة داخل الحكومة ، فإن التنسيقات التي تم إصدارها كلها تنسيقات ملفات SHP. بفضل Mike ، مؤلف D3.JS ، صادف أنه فتح مشروعًا جديدًا "FormFile" على Github مؤخرًا ، مما يسمح لنا بقراءة ملفات SHP وإخراجها في تنسيق Geojson ؛ في الواقع ، قام Mike بدمج Formfile في مشروع آخر "Topojson" ، مما يسمح لنا بإنشاء ملفات Topojson مباشرة من ملفات SHP. (PS إذا كنت مهتمًا ، يرجى الانتقال إلى هذا الموقع)
نظرًا لأن Topojson عبارة عن وحدة من NodeJs ، يجب تثبيت NodeJs أولاً ؛ تم تثبيت Nodejs في مقالة أخرى "ممارسة زاحف البيانات - باستخدام Nodejs". يمكنك تنزيل ملف التثبيت على https://nodejs.org/download/ ضمن النافذة ، وفي بيئات Linux أو Mac ، يمكنك الرجوع إلى الأساليب التي توفرها صفحة الويب هذه للتثبيت. بعد التأكيد على أنه تم تثبيت NodeJS ، نقوم بإلغاء ضغط ملف التنزيل المقدم من الحكومة ونقرأه باستخدام Topojson (مع أخذ خريطة حدود المقاطعة والمدينة كمثال):
NPM Install -G Topojson Topojson -S 0.0000001 -O County.json -P -shapefile -encoding Big5 County.shp
يتم إنشاء ملف County.json ، وهو ملف Topojson الذي نحتاجه. يمكننا أيضًا استخدام API لبرمجي ، لكن الأمور ستصبح أكثر تعقيدًا ، لذلك لن أتحدث عنها هنا. من المهم بشكل خاص ملاحظة أن البيانات الأصلية هي بتنسيق Big5 ، لذلك نحن بحاجة إلى استخدام المعلمة "-sphapefile-ending" لتذكير FASEFILE باستخدام الترميز الصحيح للتحويل. بعد أن تقوم معالجة ورسم Topojson بإنشاء ملف Topojson ، نستخدم الوظائف التي توفرها وحدة Topojson لقراءة الملف:
< svg width =" 800px " height =" 600px " viewBox =" 0 0 800 600 " > </ svg >
< script type =" text/javascript " src =" http://d3js.org/topojson.v1.min.js " > </ script >
< script >
d3 . json ( "county.json" , function ( topodata ) {
var features = topojson . feature ( topodata , topodata . objects [ "county" ] ) . features ;
// 這裡要注意的是 topodata.objects["county"] 中的 "county" 為原本 shp 的檔名
</ script >ثم استخدم d3.geo.path مع d3.geo.mercator لرسم:
var path = d3 . geo . path ( ) . projection ( // 路徑產生器
d3 . geo . mercator ( ) . center ( [ 121 , 24 ] ) . scale ( 6000 ) // 座標變換函式
) ;
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( "d" , path ) ;نتيجة الرسم هي كما يلي: الآن يمكننا معالجة الخريطة ، والمعالجة هي كما يلي:
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( {
d : path ,
name : function ( d ) {
return d . properties [ Cname ] ;
} ,
fill : '#55AA00'
} ) ;النتيجة النهائية هي على النحو التالي:
مرجع من http://bost.ocks.org/mike/map/ كتب المؤلف وظيفة يمكنها قراءة المقاطعة والمدينة ومعلومات المقاطعة الإدارية في ملف JSON ورسم خط
d3 . select ( "#pathCanvas" ) . append ( "path" ) //縣市/行政區界線
. datum ( topojson . mesh ( topodata , topodata . objects [ type ] , function ( a , b ) { return a !== b ; } ) )
. attr ( "d" , path )
. attr ( "class" , "subunit-boundary" ) ;في الوقت نفسه ، يتم إرفاق كل علامة مسار بفئة ، بحيث يمكن تغطية خطوط الحدود بالألوان والأنماط في CSS اللاحقة ، على النحو التالي:
. subunit-boundary {
fill : none;
stroke : # 000 ;
stroke-dasharray : 2 , 2 ;
stroke-linejoin : round;
}علاوة على ذلك ، يمكننا استخدام Mouseenter و Mouseout ، وسيتم عرض اسم كل مقاطعة ومدينة وسيتم تغيير اللون على النحو التالي:
d3 . select ( "svg" ) . selectAll ( "path" ) . on ( "mouseenter" , function ( ) { // title div 顯示滑鼠所指向的縣市/行政區
fill = $ ( this ) . attr ( "fill" ) ;
$ ( this ) . attr ( "fill" , '#00DD77' ) ;
$ ( '#title' ) . html ( $ ( this ) . attr ( "name" ) ) ;
$ ( '#panel' ) . css ( { "height" : "20px" , "width" : "50px" } ) ;
} ) . on ( "mouseout" , function ( ) {
$ ( this ) . attr ( "fill" , fill ) ;
} ) ;
$ ( "path" ) . mouseover ( function ( ) { //panel 區塊跟隨滑鼠移動
$ ( "path" ) . mousemove ( function ( e ) {
mouseX = e . pageX ;
mouseY = e . pageY ;
} ) ;
$ ( '#panel' ) . css ( { 'top' : mouseY , 'left' : mouseX } ) . fadeIn ( 'slow' ) ;
} ) ;هنا تأتي المشكلة. نظرًا لأن الحكومة لا توفر شيئًا مثل Latitude و Latteritude في ملف SHP ، وبعض الكوارث مثل الزلازل موجودة في خطوط الطول وخط الطول ، ولكن صفحة الويب الخاصة بنا هي مجرد خريطة متجهة SVG بسيطة ، دون الإحداثيات المزعومة. لذلك ، فإن طريقتي هي تشغيل خريطة Google وقياس طول تايوان مع حاكم. بعد قياس طول تايوان لصفحة الويب الخاصة بي وتحويل المقياس ، يمكنك تقديم المكان الذي يوجد فيه موضع حدود SVG في صفحة الويب الخاصة بي في خريطة Google. مع أخذ خط الطول وعطول الطول ، اكتب اثنين من funcitons لحساب خط الطول وخط العرض على التوالي ، وتحويله إلى المكان الذي يجب أن تكون فيه النقطة في SVG (هذه الطريقة غبية للغاية. أعرف ... آمل أن يقدم لي أحد النصائح حول كيفية كتابة هذه الوظيفة بشكل أفضل. أنا ممتن لي> <):
function mapTopixelX ( x ) {
var originX = 118.802981 , endX = 122.469668 ;
var webOriginX = 0 , webEndX = 800 ;
var resultX = ( x - originX ) * ( ( webEndX - webOriginX ) / ( endX - originX ) ) ;
return resultX ;
}
function mapTopixelY ( y ) {
var originY = 21.510473 , endY = 25.357116 ;
var webOriginY = 0 , webEndY = 900 ;
var resultY = 900 - ( y - originY ) * ( ( webEndY - webOriginY ) / ( endY - originY ) ) ;
return resultY ;
} وفقًا للإرشادات الواردة في القسم السابق "معالجة البيانات متعددة المصادر" ، في نهاية الكود ، تتم معالجة معالجة البيانات ، ويمكن استدعاء الوظيفة التالية ، ويمكن دفع جميع بيانات AJAX إلى صفيف ، وتم نقلها إلى هذه الوظيفة في شكل المعلمة ، وتبدأ الرسم البياني:
function historyRain ( data , place ) {
reset ( ) ;
var rain_dataset = [ ] ;
for ( var i = 0 ; i < data . length ; i ++ ) {
rain_dataset . push ( { 'x' : ( 91 + i ) , 'y' : data [ i ] } ) ;
}
chart = new CanvasJS . Chart ( "chart" ,
{
theme : "theme1" ,
title : {
text : "台北各年份年雨量趨勢圖" ,
fontFamily : "微軟正黑體"
} ,
animationEnabled : true ,
axisX : {
interval : 1 ,
intervalType : "year" ,
labelFontColor : "black" ,
labelFontFamily : "微軟正黑體" ,
suffix : "年"
} ,
axisY : {
includeZero : false ,
title : "雨量數值 (單位mm)" ,
labelFontColor : "black" ,
labelFontFamily : "微軟正黑體"
} ,
toolTip : {
shared : true ,
content : "<span style='"'color: {color};'"'><strong>{name} : </strong></span> <span style='"'color: dimgrey;'"'>{y} (mm)</span> "
} ,
data : [
{
name : place ,
type : "area" ,
color : "rgba(0,255,0,0.6)" ,
indexLabelFontFamily : "微軟正黑體" ,
indexLabelFontColor : "black" ,
dataPoints : rain_dataset //將所有的data匯入canvas圖表當中
}
] ,
backgroundColor : 'rgba(0,0,0,0)' ,
} ) ;
chart . render ( ) ;
} ما سبق هو مقدمة المشروع لهذا المشروع ، وهو بسيط بعض الشيء. إذا كان لا يزال هناك جزء غير واضح ، فيرجى إرسال بريد إلكتروني إلى [email protected]. لقد قمت بتحميل جميع رموز الأرشيف إلى github ، وكذلك أنشأت صفحة github. أولئك الذين يريدون رؤية العرض التوضيحي يمكنهم أيضًا الذهاب لاختباره. إذا كان هناك أي أخطاء ، فنحن نرحب بك للإبلاغ عنها (وقت الإنتاج قصير ، يجب أن يكون هناك العديد من الأخطاء ، يرجى مسامحة XD). أخيرًا ، شكرًا لك على رؤية آخرها ، شكرًا لك على دعمكم ودعمك هاها
-http: //blog.infographics.tw/2015/04/visualize-geogrics-with-d3js/
-http: //bost.ocks.org/mike/map/
-http: //canvasjs.com/