Dado que el gobierno de Taiwán coloca información meteorológica y de desastre en cada página web de acuerdo con el mes/año o el tipo de desastre, hace que ocurra el mismo desastre, y puede haber 24 páginas (un archivo HTML por mes) desde 2014 hasta 2015, lo que es muy inconveniente para procesar. Por lo tanto, usamos la API Kinomo para extraer y filtrar la información de estas páginas
E integrarse en el mismo archivo json
Pero si no usa la función integrada de integración de API de Kinomo, sus fuentes AJAX serán muy exageradas, y muchas fuentes deben procesarse al mismo tiempo. Si el usuario elige información de lluvia, esperará ver la información de 20XX a 2015. De esta manera, probablemente necesite ejecutar 2015-20xx para multiplicar 12 AJAX. Este no solo será un problema válido, sino también un error de sintaxis de variable indefinida. La razón es que Ajax es asíncrono, pero el compilador JavaScript ejecutará el código primero. En este momento, algunas variables se usaron originalmente para recibir la respuesta de Ajax, pero debido a que no ha terminado de funcionar, aún no ha regresado. En este momento, la variable será nula o indefinida, y habrá problemas con el procesamiento posterior. En este momento, debe usar las funciones de JQuery When () y luego (). El uso es el siguiente:
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 El gobierno publicó tres niveles de información en el sitio web oficial de datos abiertos:
-Borders of County (City) Distritos administrativos
-El límite administrativo del municipio (ciudad, ciudad, distrito)
-La mapa de límite de la aldea nacional
Debido a los sistemas utilizados dentro del gobierno, los formatos publicados son todos los formatos de archivo SHP. Gracias a Mike, el autor de D3.JS, estaba abrido un nuevo proyecto "ShapeFile" en GitHub recientemente, lo que nos permite leer los archivos SHP y generarlos en formato Geojson; De hecho, Mike ha integrado ShapFile en otro proyecto "Topojson", lo que nos permite generar directamente los archivos Topojson a partir de los archivos SHP. (PD, si está interesado, vaya a este sitio web)
Dado que Topojson es un módulo de NodeJS, NodeJS debe instalarse primero; NodeJS se instala en otro artículo "Práctica de rastreadores de datos, utilizando NodeJS". Puede descargar el archivo de instalación en https://nodejs.org/download/ en la ventana, y en entornos de Linux o Mac, puede consultar los métodos proporcionados por esta página web para instalar. Después de confirmar que NodeJS está instalado, descomprimimos el archivo de descarga proporcionado por el gobierno y lo leemos usando Topojson (tomando el mapa de límites del condado y la ciudad como ejemplo):
NPM Install -G TopOJson TopOjson -S 0.0000001 -O County.json -P --Shapefile -Ending Big5 County.shp
Se genera un archivo condado.json, que es el archivo TopOjson que necesitamos. También podemos usar API para programar, pero las cosas se volverán más complicadas, por lo que no hablaré de eso aquí. Es particularmente importante tener en cuenta que los datos originales están en formato Big5, por lo que debemos usar el parámetro "-Shapefile-Encaring" para recordarle al archivo de forma que use la codificación correcta para convertir. Después de que el procesamiento y el dibujo de Topojson genera un archivo Topojson, utilizamos las funciones proporcionadas por el módulo Topojson para leer el archivo:
< 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 >Luego use d3.geo.path con d3.geo.mercator para dibujar:
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 ) ;El resultado del dibujo es el siguiente: ahora podemos procesar más el mapa, y el procesamiento es el siguiente:
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( {
d : path ,
name : function ( d ) {
return d . properties [ Cname ] ;
} ,
fill : '#55AA00'
} ) ;El resultado final es el siguiente:
Referencia de http://bost.ocks.org/mike/map/ El autor escribió una función que puede leer la información del condado, la ciudad, el distrito administrativo en el archivo JSON y dibujar una línea
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" ) ;Al mismo tiempo, cada etiqueta de ruta se adjunta con una clase, de modo que las líneas límite se puedan cubrir con colores y estilos en el CSS posterior, como sigue:
. subunit-boundary {
fill : none;
stroke : # 000 ;
stroke-dasharray : 2 , 2 ;
stroke-linejoin : round;
}Además, podemos usar mouseenter y mouseut, y se mostrará el nombre de cada condado y ciudad y el color se cambiará de la siguiente manera:
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' ) ;
} ) ;Aquí viene el problema. Dado que el gobierno no proporciona la latitud y la longitud en el archivo SHP, y algunos desastres, como los terremotos, se encuentran en la latitud y la longitud del terremoto, pero nuestra página web es solo un mapa de vector SVG simple, sin las llamadas coordenadas. Por lo tanto, mi método es encender el mapa de Google y medir la longitud de Taiwán con una regla. Después de medir la longitud de Taiwán de mi propia página web y convertir la escala, puede introducir dónde está la posición de límite SVG en mi página web en Google Map. Tomando su longitud y longitud, escriba dos funciones para calcular su longitud y latitud respectivamente, y conviértalo en donde debería estar el punto en el SVG (este método es muy estúpido. Lo sé ... espero que alguien pueda darme algunos consejos sobre cómo escribir esta función mejor. Estoy agradecido de mí> <):
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 ;
} De acuerdo con las instrucciones en la sección anterior, "procesamiento de datos de múltiples fuentes", al final del código, se procesa el procesamiento de datos y se puede llamar a la siguiente función, y todos los datos de AJAX se pueden impulsar a una matriz y pasar a esta función en forma de parámetro, y se inicia el cuadro:
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 ( ) ;
} Lo anterior es la introducción del proyecto de este proyecto, que es un poco simple. Si todavía no hay parte clara, envíe un correo electrónico a [email protected]. He subido todos los códigos de archivo a GitHub, y también generé la página de GitHub. Aquellos que quieran ver la demostración también pueden ir a probarla. Si hay algún error, puede informarlo (el tiempo de producción es corto, debe haber muchos errores, perdona XD). Finalmente, gracias por ver el último, gracias por su apoyo y apoyo jaja
-http: //blog.infographics.tw/2015/04/visualize-geogramics-with-d3js/
-http: //bost.ocks.org/mike/map/
-http: //canvasjs.com/