Étant donné que le gouvernement de Taiwan place les informations météorologiques et en cas de catastrophe sur chaque page Web selon le mois / l'année ou le type de catastrophe, il provoque la même catastrophe, et il peut y avoir 24 pages (un fichier HTML par mois) de 2014 à 2015, ce qui est très gênant à traiter. Par conséquent, nous utilisons l'API Kinomo pour extraire et filtrer les informations de ces pages
Et intégrer dans le même fichier JSON
Mais si vous n'utilisez pas la fonction d'intégration API intégrée de Kinomo, vos sources Ajax seront très exagérées et de nombreuses sources doivent être traitées en même temps. Si l'utilisateur choisit des informations sur les précipitations, il espère voir les informations de 20xx à 2015. De cette manière, vous devrez probablement exécuter 2015-20xx pour multiplier 12 Ajax. Ce sera non seulement un problème valide, mais aussi une erreur de syntaxe de la variable non définie. La raison en est qu'Ajax est asynchrone, mais le compilateur JavaScript exécutera d'abord le code. À l'heure actuelle, certaines variables étaient à l'origine utilisées pour recevoir la réponse d'Ajax, mais comme elle n'a pas fini de fonctionner, elle n'est pas encore revenue. À l'heure actuelle, la variable sera nulle ou non définie, et il y aura des problèmes avec le traitement ultérieur. À l'heure actuelle, vous devez utiliser les fonctions de jQuery quand () et puis (). L'utilisation est la suivante:
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 Le gouvernement a publié trois niveaux d'informations sur le site officiel des données ouvertes:
-Borders des districts administratifs du comté (ville)
-La frontière administrative du canton (ville, ville, district)
-Parpe aux limites du village national
En raison des systèmes utilisés au sein du gouvernement, les formats libérés sont tous des formats de fichiers SHP. Grâce à Mike, l'auteur de D3.JS, il a récemment ouvert un nouveau projet "ShapeFile" sur GitHub, nous permettant de lire les fichiers SHP et de les publier au format Geojson; En fait, Mike a intégré ShapeFile dans un autre projet "Topojson", nous permettant de générer directement des fichiers topojson à partir des fichiers SHP. (PS Si vous êtes intéressé, veuillez consulter ce site)
Étant donné que Topojson est un module de NodeJS, NodeJS doit être installé en premier; NodeJS est installé dans un autre article "Data Crawler Practice - Utilisation de NodeJS". Vous pouvez télécharger le fichier d'installation sur https://nodejs.org/download/ Under Window, et dans les environnements Linux ou Mac, vous pouvez vous référer aux méthodes fournies par cette page Web à installer. Après avoir confirmé que NodeJS est installé, nous décompressons le fichier de téléchargement fourni par le gouvernement et le lisons à l'aide de Topojson (en prenant la carte des limites du comté et de la ville):
NPM Installer -g Topojson Topojson -S 0,0000001 -o comté.json -p - codant le codage de big5 comté.shp
Un fichier comté.json est généré, qui est le fichier topojson dont nous avons besoin. Nous pouvons également utiliser l'API pour programmer, mais les choses deviendront plus compliquées, donc je n'en parlerai pas ici. Il est particulièrement important de noter que les données d'origine sont au format BIG5, nous devons donc utiliser le paramètre "-shapefile-coding" pour rappeler au fichier de forme pour utiliser le codage correct pour convertir. Après que le traitement et le dessin de topojson ont généré un fichier topojson, nous utilisons les fonctions fournies par le module topojson pour lire le fichier:
< 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 >Ensuite, utilisez d3.geo.path avec d3.geo.mercator pour dessiner:
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 ) ;Le résultat du dessin est le suivant: Nous pouvons maintenant traiter davantage la carte, et le traitement est le suivant:
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( {
d : path ,
name : function ( d ) {
return d . properties [ Cname ] ;
} ,
fill : '#55AA00'
} ) ;Le résultat final est le suivant:
Référence de http://bost.ocks.org/mike/map/ L'auteur a écrit une fonction qui peut lire les informations du comté, de la ville, du district administratif dans le fichier JSON et tracer une ligne
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" ) ;Dans le même temps, chaque balise de chemin est attachée avec une classe, afin que les lignes limites puissent être recouvertes de couleurs et de styles dans le CSS suivant, comme suit:
. subunit-boundary {
fill : none;
stroke : # 000 ;
stroke-dasharray : 2 , 2 ;
stroke-linejoin : round;
}De plus, nous pouvons utiliser MouseEnter et Mouseout, et le nom de chaque comté et ville sera affiché et la couleur sera modifiée comme suit:
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' ) ;
} ) ;Voici le problème. Étant donné que le gouvernement ne fournit pas de latitude et de longitude dans le fichier SHP, et certaines catastrophes telles que les tremblements de terre sont situées dans la latitude et la longitude du tremblement de terre, mais notre page Web n'est qu'une simple carte vectorielle SVG, sans coordonnées dites. Par conséquent, ma méthode consiste à activer Google Map et à mesurer la longueur de Taiwan avec une règle. Après avoir mesuré la longueur de Taiwan de ma propre page Web et converti la balance, vous pouvez introduire où se trouve la position limite SVG dans ma page Web dans Google Map. En prenant sa longitude et sa longitude, écrivez deux funcitons pour calculer respectivement sa longitude et sa latitude, et le convertir à l'endroit où le point devrait être dans le SVG (cette méthode est très stupide. J'espère ... J'espère que quelqu'un pourra me donner quelques conseils sur la façon d'écrire cette fonction. Je suis reconnaissant à moi> <)::
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 ;
} Selon les instructions de la section précédente "Traitement de données multi-sources", à la fin du code, le traitement des données est traité et la fonction suivante peut être appelée, et toutes les données AJAX peuvent être poussées dans un tableau et transmise à cette fonction sous forme de paramètre, et le graphique est démarré:
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 ( ) ;
} Ce qui précède est l'introduction du projet de ce projet, ce qui est un peu simple. S'il n'y a pas encore de partie, veuillez envoyer un courriel à [email protected]. J'ai téléchargé tous les codes d'archives sur GitHub, et également généré la page GitHub. Ceux qui veulent voir la démo peuvent également aller le tester. S'il y a des bogues, vous êtes invités à le signaler (le temps de production est court, il devrait y avoir de nombreux bogues, veuillez pardonner XD). Enfin, merci d'avoir vu le dernier, merci pour votre soutien et votre soutien haha
-http: //blog.infographics.tw/2015/04/visualize-geographics-with-d3js/
-http: //bost.ocks.org/mike/map/
-http: //canvasjs.com/