Como o governo de Taiwan coloca informações meteorológicas e de desastres em cada página da web de acordo com o mês/ano ou o tipo de desastre, isso faz com que o mesmo desastre ocorra e pode haver 24 páginas (um arquivo HTML por mês) de 2014 a 2015, o que é muito inconveniente para processar. Portanto, usamos a API Kinomo para extrair e filtrar as informações dessas páginas
E integrar -se ao mesmo arquivo JSON
Mas se você não usar a função de integração da API interna do Kinomo, suas fontes de Ajax serão muito exageradas e muitas fontes precisam ser processadas ao mesmo tempo. Se o usuário escolher informações de precipitação, ele esperará ver as informações de 20xx a 2015. Este não apenas será um problema válido, mas também um erro de sintaxe da variável indefinida. O motivo é que o Ajax é assíncrono, mas o compilador JavaScript executará o código primeiro. No momento, algumas variáveis foram originalmente usadas para receber a resposta do Ajax, mas como não terminou de executar, ainda não retornou. No momento, a variável será nula ou indefinida e haverá problemas com o processamento subsequente. Neste momento, você deve usar as funções do jQuery quando () e depois (). O uso é o seguinte:
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 O governo divulgou três níveis de informação no site oficial de dados abertos:
-Borders de distritos administrativos do condado (cidade)
-O limite administrativo do município (cidade, cidade, distrito)
-Nacional mapa de fronteira da vila
Devido aos sistemas usados no governo, os formatos liberados são todos formatos de arquivo SHP. Graças a Mike, o autor do D3.JS, ele abriu recentemente um novo projeto "Shapefile" no Github, permitindo -nos ler arquivos SHP e gerá -los no formato Geojson; De fato, Mike integrou o ShapFile a outro projeto "Topojson", permitindo -nos gerar diretamente arquivos todojson a partir dos arquivos shp. (PS se você estiver interessado, vá para este site)
Como o Topojson é um módulo de NodeJS, o NodeJS precisa ser instalado primeiro; O NodeJS está instalado em outro artigo "Prática de rastreador de dados - usando o NodeJS". Você pode baixar o arquivo de instalação em https://nodejs.org/download/ em Window e nos ambientes Linux ou Mac, você pode consultar os métodos fornecidos nesta página da web para instalar. Depois de confirmar que o NodeJS está instalado, descomprimimos o arquivo de download fornecido pelo governo e o lemos usando Topojson (levando o mapa de limites do condado e da cidade como exemplo):
NPM Install -g topojson topojson -s 0.0000001 -o County.json -P -Shapefile -codificador BIG5 County.shp
Um File County.json é gerado, que é o arquivo topojson que precisamos. Também podemos usar a API para programaticamente, mas as coisas se tornarão mais complicadas, então não vou falar sobre isso aqui. É particularmente importante observar que os dados originais estão no formato BIG5, por isso precisamos usar o parâmetro "-Shapefile-codificador" para lembrar o ShapFile para usar a codificação correta para converter. Após o processamento e desenho do Topojson gera um arquivo todojson, usamos as funções fornecidas pelo módulo Topojson para ler o arquivo:
< 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 >Em seguida, use d3.geo.path com d3.geo.mercator para desenhar:
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 ) ;O resultado do desenho é o seguinte: agora podemos processar ainda mais o mapa, e o processamento é o seguinte:
d3 . select ( "svg" ) . selectAll ( "path" ) . data ( features ) . enter ( ) . append ( "path" ) . attr ( {
d : path ,
name : function ( d ) {
return d . properties [ Cname ] ;
} ,
fill : '#55AA00'
} ) ;O resultado final é o seguinte:
Referência de http://bost.ocks.org/mike/map/ O autor escreveu uma função que pode ler as informações do distrito administrativo do município, cidade, no arquivo json e desenhar uma linha
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" ) ;Ao mesmo tempo, cada etiqueta de caminho é anexada a uma classe, para que as linhas de limite possam ser cobertas com cores e estilos no CSS subsequente, como segue:
. subunit-boundary {
fill : none;
stroke : # 000 ;
stroke-dasharray : 2 , 2 ;
stroke-linejoin : round;
}Além disso, podemos usar o MouseEnter e o MouseOut, e o nome de cada condado e cidade será exibido e a cor será alterada da seguinte forma:
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' ) ;
} ) ;Aí vem o problema. Como o governo não fornece latitude e longitude no arquivo SHP, e alguns desastres como terremotos estão localizados na latitude e longitude do terremoto, mas nossa página da web é apenas um mapa de vetor SVG simples, sem as chamadas coordenadas. Portanto, meu método é ativar o mapa do Google e medir o comprimento de Taiwan com uma régua. Depois de medir o comprimento de Taiwan da minha própria página da web e converter a escala, você pode introduzir onde a posição de limite SVG na minha página da web está no mapa do Google. Tomando sua longitude e longitude, escreva duas funções para calcular sua longitude e latitude, respectivamente, e converta -a para onde o ponto deve estar no SVG (esse método é muito estúpido. Eu sei ... Espero que alguém possa me dar alguns conselhos sobre como escrever essa função melhor. Agradeço a mim> <):
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 acordo com as instruções na seção anterior "Processamento de dados de várias fontes", no final do código, o processamento de dados é processado e a seguinte função pode ser chamada, e todos os dados do AJAX podem ser pressionados para uma matriz e transmitidos para esta função em forma de parâmetro, e o gráfico é iniciado:
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 ( ) ;
} O exposto acima é a introdução do projeto deste projeto, o que é um pouco simples. Se ainda não houver parte, envie um email para [email protected]. Carreguei todos os códigos de arquivo para o Github e também gerei a página do GitHub. Aqueles que querem ver a demonstração também podem testá -lo. Se houver bugs, você poderá denunciá -lo (o tempo de produção é curto, deve haver muitos bugs, perdoe o XD). Finalmente, obrigado por ver o último, obrigado pelo seu apoio e apoio haha
-http: //blog.infographics.tw/2015/04/visualize-geographics-with-d3js/
-http: //bost.ocks.org/mike/map/
-http: //canvasjs.com/