Da die Regierung Taiwan meteorologische und Katastropheninformationen auf jeder Webseite gemäß Monat/Jahr oder einer Katastrophe legt, tritt dies zur gleichen Katastrophe auf, und es kann 24 Seiten (eine HTML -Datei pro Monat) von 2014 bis 2015 auftreten, was sehr unangemessen ist. Daher verwenden wir die Kinomo -API, um die Informationen dieser Seiten zu extrahieren und zu filtern
Und in die gleiche JSON -Datei integrieren
Wenn Sie jedoch die integrierte API-Integrationsfunktion von Kinomo nicht verwenden, sind Ihre AJAX-Quellen sehr übertrieben und viele Quellen müssen gleichzeitig verarbeitet werden. Wenn der Benutzer Niederschlagsinformationen wählt, wird er hoffen, die Informationen von 20xx bis 2015 zu sehen. Auf diese Weise müssen Sie wahrscheinlich 2015-20xx ausführen, um 12 AJAX zu multiplizieren. Dies ist nicht nur ein gültiges Problem, sondern auch ein Syntaxfehler der Variablen undefinierten. Der Grund ist, dass Ajax asynchron ist, aber der JavaScript -Compiler wird zuerst den Code ausführen. Zu diesem Zeitpunkt wurden einige Variablen ursprünglich verwendet, um die Antwort von Ajax zu erhalten, aber weil sie noch nicht läuft, ist es noch nicht zurückgekehrt. Zu diesem Zeitpunkt wird die Variable null oder undefiniert sein, und es wird Probleme mit der anschließenden Verarbeitung geben. Zu diesem Zeitpunkt müssen Sie JQuery's WOS () und dann () Funktionen verwenden. Die Verwendung ist wie folgt:
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 Die Regierung veröffentlichte drei Informationen auf der offiziellen Website offener Daten:
-Borders der Verwaltungsbezirke des Landkreises (Stadt)
-Die administrative Grenze der Gemeinde (Stadt, Stadt, Bezirk)
-National Village Grenzkarte
Aufgrund der in der Regierung verwendeten Systeme sind die veröffentlichten Formate alle SHP -Dateiformate. Dank Mike, dem Autor von D3.JS, hatte er kürzlich ein neues Projekt "Shapefile" auf Github eröffnet, sodass wir SHP -Dateien lesen und in das Geojson -Format ausgeben können. Tatsächlich hat Mike Shapefile in ein anderes "Topojson" integriert, sodass wir Topojson -Dateien aus den SHP -Dateien direkt generieren können. (PS Wenn Sie interessiert sind, gehen Sie bitte auf diese Website)
Da Topojson ein Modul von NodeJs ist, muss zuerst NodeJs installiert werden. NodeJS ist in einem anderen Artikel "Daten Crawler -Praxis - mit NodeJs" installiert. Sie können die Installationsdatei unter https://nodejs.org/download/ unter dem Fenster und in Linux- oder Mac -Umgebungen auf die von dieser Webseite bereitgestellten Methoden finden, die auf dieser Webseite bereitgestellt werden sollen. Nachdem wir bestätigt haben, dass NodeJS installiert ist, dekomprimieren wir die von der Regierung bereitgestellte Download -Datei und lesen sie mit Topojson (die Grenzkarte der Grenze für die Grafschaft und der Stadt als Beispiel):
npm install -g topojson topojson -S 0.0000001 -o County.json -p -shapeFile -codierende Big5 County.shp
Eine Datei County.json wird generiert, die die Topojson -Datei ist, die wir benötigen. Wir können API auch programmgesteuert verwenden, aber die Dinge werden komplizierter, daher werde ich hier nicht darüber sprechen. Es ist besonders wichtig zu beachten, dass sich die Originaldaten im Big5-Format befinden. Daher müssen wir den Parameter "-Shapefile-Codierung" verwenden, um die Shapefile zur Verwendung der richtigen Codierung zum Konvertieren zu erinnern. Nachdem die Verarbeitung und Zeichnung von Topojson eine Topojson -Datei generiert, verwenden wir die vom Topojson -Modul bereitgestellten Funktionen, um die Datei zu lesen:
< 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 >Verwenden Sie dann D3.Geo.Path mit D3.GEO.Mercator, um zu zeichnen:
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 ) ;Das Ziehenergebnis lautet wie folgt: Jetzt können wir die Karte weiter verarbeiten, und die Verarbeitung lautet wie folgt:
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( {
d : path ,
name : function ( d ) {
return d . properties [ Cname ] ;
} ,
fill : '#55AA00'
} ) ;Das Endergebnis ist wie folgt:
Referenz von http://bost.ocks.org/mike/map/ Der Autor schrieb eine Funktion, mit der Informationen, Stadt-, Verwaltungsbezirksinformationen in der JSON -Datei lesen und eine Zeile zeichnen können
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" ) ;Gleichzeitig ist jedes Pfadetikett mit einer Klasse angehängt, damit die Grenzlinien wie folgt mit Farben und Stilen in den nachfolgenden CSS bedeckt werden können:
. subunit-boundary {
fill : none;
stroke : # 000 ;
stroke-dasharray : 2 , 2 ;
stroke-linejoin : round;
}Darüber hinaus können wir MouseNter und Mouseout verwenden, und der Name jedes Landkreises und jeder Stadt wird angezeigt und die Farbe wird wie folgt geändert:
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' ) ;
} ) ;Hier kommt die Mühe. Da die Regierung in der SHP-Datei keinen Breitengrad und Längengrad bietet und einige Katastrophen wie Erdbeben in der Breite und Länge des Erdbebens befinden, aber unsere Webseite ist nur eine einfache SVG-Vektorkarte ohne sogenannte Koordinaten. Meine Methode ist daher, Google Map einzuschalten und die Länge von Taiwan mit einem Lineal zu messen. Nach der Messung der taiwanesischen Länge meiner eigenen Webseite und der Konvertierung der Skala können Sie einführen, wo sich die SVG -Grenzposition auf meiner Webseite in Google Map befindet. Nehmen Sie seine Länge und Länge, schreiben Sie zwei Funktionen, um seine Länge und Breite zu berechnen, und konvertieren sie dorthin, wo der Punkt in der SVG sein sollte (diese Methode ist sehr dumm. Ich weiß ... Ich hoffe, jemand kann mir einen Rat geben, wie man diese Funktion besser schreibt. Ich bin mir dankbar.> <).
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 ;
} Gemäß den Anweisungen im vorherigen Abschnitt "Multi-Source-Datenverarbeitung" wird am Ende des Codes die Datenverarbeitung verarbeitet und die folgende Funktion kann aufgerufen werden, und alle Ajax-Daten können in ein Array gedrückt und in Parameterform an diese Funktion übergeben werden, und das Diagramm wird gestartet:
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 ( ) ;
} Das obige ist die Projekteinführung dieses Projekts, das etwas einfach ist. Wenn es noch unklar ist, senden Sie bitte eine E -Mail an [email protected]. Ich habe alle Archivcodes auf GitHub hochgeladen und auch GitHub -Seite generiert. Diejenigen, die die Demo sehen wollen, können auch sie testen. Wenn es Fehler gibt, können Sie es gerne melden (die Produktionszeit ist kurz, es sollte viele Fehler geben, bitte verzeihen Sie XD). Zum Schluss danke, dass Sie den letzten gesehen haben. Vielen Dank für Ihre Unterstützung und Unterstützung, haha
-http: //blog.infographics.tw/2015/04/visualize-geographics-with-d3js/
-http: //bost.ocks.org/mike/map/
-http: //canvasjs.com/