├── .Rbuildignore ├── .gitignore ├── data ├── city.rda ├── geo.rda ├── heat.rda ├── demoC.rda ├── demoE.rda ├── subway.rda ├── mapCData.rda ├── chinaIphone.rda └── REmapCityGeo.rda ├── REmapExamples └── Nanchang │ └── baiduMapFileDrawer │ └── 115.893527545836;28.6895780001411.png ├── DESCRIPTION ├── man ├── remap.init.Rd ├── mapNames.Rd ├── REmapOutput.Rd ├── knitrREmap.Rd ├── plot.remap.Rd ├── get_city_coord.Rd ├── remap.Rd ├── get_geo_position.Rd ├── markPointControl.Rd ├── remapH.Rd ├── markLineControl.Rd ├── remapC.Rd ├── remapB.Rd └── get_theme.Rd ├── inst ├── shiny │ ├── remapWidget.html │ └── shinyBmap │ │ ├── server.R │ │ ├── style.css │ │ └── ui.R └── JS │ ├── main.js │ └── chart │ ├── heatmap.js │ ├── k.js │ ├── eventRiver.js │ └── gauge.js ├── REmap.Rproj ├── NAMESPACE ├── demo ├── remapThemeDemo.r ├── remapDemo.r ├── remapCDemo.R └── remapBDemo.R ├── R ├── remap.init.R ├── get_city_coord.R ├── markPointControl.R ├── mapNames.R ├── reGG.R ├── zzz.r ├── get_geo_position.R ├── plot.remap.R ├── markLineControl.R ├── knitrREmap.R ├── renderREmap.R ├── get_theme.R ├── markPointStr.R ├── markLineStr.R ├── remap.r ├── remapC.R ├── remapH.R └── remapB.R ├── README.md ├── ID_20191206165920_22851.html └── ID_20191206170358_13612.html /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | REmap.Rproj -------------------------------------------------------------------------------- /data/city.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/city.rda -------------------------------------------------------------------------------- /data/geo.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/geo.rda -------------------------------------------------------------------------------- /data/heat.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/heat.rda -------------------------------------------------------------------------------- /data/demoC.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/demoC.rda -------------------------------------------------------------------------------- /data/demoE.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/demoE.rda -------------------------------------------------------------------------------- /data/subway.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/subway.rda -------------------------------------------------------------------------------- /data/mapCData.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/mapCData.rda -------------------------------------------------------------------------------- /data/chinaIphone.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/chinaIphone.rda -------------------------------------------------------------------------------- /data/REmapCityGeo.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/data/REmapCityGeo.rda -------------------------------------------------------------------------------- /REmapExamples/Nanchang/baiduMapFileDrawer/115.893527545836;28.6895780001411.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lchiffon/REmap/master/REmapExamples/Nanchang/baiduMapFileDrawer/115.893527545836;28.6895780001411.png -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: REmap 2 | Title: Create html maps by Echarts 3 | Version: 0.3.2 4 | Authors@R: "Dawei Lang [aut, cre]" 5 | Description: Provides an R interface to the JavaScript library ECharts for 6 | interactive map data visualization. 7 | Depends: R (>= 3.1.0) 8 | LazyData: true 9 | Imports: 10 | XML, 11 | rjson, 12 | htmltools 13 | License: MIT + file LICENSE 14 | -------------------------------------------------------------------------------- /man/remap.init.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/remap.init.R 3 | \name{remap.init} 4 | \alias{remap.init} 5 | \title{Remap initial for knitr} 6 | \usage{ 7 | recharts.init() 8 | } 9 | \description{ 10 | An shell function for initializing knitr for remap packages 11 | } 12 | \details{ 13 | Only the first chuck of recharts plot needs this function, 14 | the rest chuck mustn't include this function. 15 | } 16 | 17 | -------------------------------------------------------------------------------- /inst/shiny/remapWidget.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /REmap.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /man/mapNames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/mapNames.R 3 | \name{mapNames} 4 | \alias{mapNames} 5 | \title{Get the names of a choropleth map for remapC} 6 | \usage{ 7 | mapNames(mapType) 8 | } 9 | \arguments{ 10 | \item{mapType}{one of "china", "world" or the name of 11 | province in China} 12 | } 13 | \value{ 14 | mapNames returns a vec of map names 15 | } 16 | \description{ 17 | mapNames show what kind of map names is needed for remapC 18 | } 19 | \examples{ 20 | ## get the province names: 21 | mapNames('china') 22 | } 23 | 24 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | export(get_city_coord) 2 | export(get_geo_position) 3 | export(get_theme) 4 | export(remap) 5 | export(remapC) 6 | export(remapB) 7 | export(markLineControl) 8 | export(markPointControl) 9 | export(mapNames) 10 | export(plot.remap) 11 | export(remap.init) 12 | export(remapH) 13 | export(sampleData) 14 | export(knitrREmap) 15 | export(renderREmap) 16 | export(REmapOutput) 17 | importFrom(XML,"htmlParse") 18 | importFrom(XML,"xmlRoot") 19 | importFrom(XML,"xpathSApply") 20 | importFrom(XML,"xmlValue") 21 | importFrom(rjson,"fromJSON") 22 | importFrom(htmltools,"tagList") 23 | importFrom(htmltools,"tag") 24 | -------------------------------------------------------------------------------- /man/REmapOutput.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/renderREmap.R 3 | \name{REmapOutput} 4 | \alias{REmapOutput} 5 | \title{Plot REmap in shiny} 6 | \usage{ 7 | REmapOutput(outputId, inline = FALSE, container,...) 8 | renderREmap(expr, env = parent.frame(),height = "800px", 9 | width = "100\%", quoted = FALSE, func = NULL) 10 | } 11 | \description{ 12 | Function for plotting REmap in shiny 13 | } 14 | \details{ 15 | USe renderREmap render an REmap object and use REmapOutput 16 | output an REmap object. See more details in shiny package. 17 | } 18 | \examples{ 19 | library(REmap) 20 | library(shiny) 21 | runApp(system.file("shiny","shinyBmap", package = "REmap")) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /man/knitrREmap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/knitrREmap.R 3 | \name{knitrREmap} 4 | \alias{knitrREmap} 5 | \title{Plot REmap in knitr} 6 | \usage{ 7 | knitrREmap(object, height = "300px", width = "100\%", local = F) 8 | } 9 | \arguments{ 10 | \item{height}{height for the DOM of REmap} 11 | 12 | \item{width}{width for the DOM of REmap} 13 | 14 | \item{objct}{an REmap object for plotting} 15 | } 16 | \description{ 17 | Function for plotting REmap in knitr 18 | } 19 | \details{ 20 | After using the remap.init function, you can use this function 21 | for plotting REmap in knitr in any chuck 22 | } 23 | \examples{ 24 | library(REmap) 25 | out = remap(demoC) 26 | knitrREmap(out) 27 | } 28 | 29 | -------------------------------------------------------------------------------- /man/plot.remap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/plot.remap.R 3 | \name{plot.remap} 4 | \alias{plot.remap} 5 | \title{plot the remap object} 6 | \usage{ 7 | \method{plot}{remap}(object, path = "") 8 | } 9 | \arguments{ 10 | \item{object}{an remap object} 11 | 12 | \item{path}{the path for saving REmap object} 13 | } 14 | \value{ 15 | Create a html file according to the id of the object 16 | } 17 | \description{ 18 | plot.remap is a function to create the htmlfile 19 | and open it by browser 20 | } 21 | \examples{ 22 | set.seed(125) 23 | out = remap(demoC,title = "REmap: Demo DATA", 24 | subtitle = "theme:Dark") 25 | plot(out) 26 | } 27 | \author{ 28 | Chiffon <\url{http://lchiffon.github.io}> 29 | } 30 | 31 | -------------------------------------------------------------------------------- /demo/remapThemeDemo.r: -------------------------------------------------------------------------------- 1 | ## ---- REmap demo ---- 2 | ## ---- remapThemeDemo ---- 3 | ## ---- pauseFunction ---- 4 | pause <- function(){ 5 | invisible(readline("\nPress to continue: ")) 6 | } 7 | data(demoE) 8 | ## ---- pause ---- 9 | pause() 10 | demoE 11 | 12 | ## ---- pause ---- 13 | pause() 14 | set.seed(125) 15 | out = remap(demoE,title = "REmap Sample Data",subtitle = "theme:Dark") 16 | plot(out) 17 | summary(out) 18 | 19 | 20 | ## ---- pause ---- 21 | pause() 22 | set.seed(125) 23 | out = remap(demoE,title = "REmap Sample Data",subtitle = "theme:Bright", 24 | theme = get_theme("Bright")) 25 | plot(out) 26 | 27 | 28 | ## ---- pause ---- 29 | pause() 30 | set.seed(125) 31 | out = remap(demoE,title = "REmap Sample Data",subtitle = "theme:Sky", 32 | theme = get_theme("Sky")) 33 | plot(out) 34 | -------------------------------------------------------------------------------- /inst/shiny/shinyBmap/server.R: -------------------------------------------------------------------------------- 1 | 2 | # This is the server logic for a Shiny web application. 3 | # You can find out more about building applications with Shiny here: 4 | # 5 | # http://shiny.rstudio.com 6 | # 7 | 8 | library(shiny) 9 | library(REmap) 10 | 11 | shinyServer(function(input, output) { 12 | 13 | output$remap <- renderREmap({ 14 | geoData = get_geo_position(unique(demoC[demoC==demoC])) 15 | # this may take some time,be patient~ 16 | remapB(center = c(input$lon,input$lat), 17 | zoom = input$zoom, 18 | color = input$color, 19 | title = input$title, 20 | subtitle = input$subtitle, 21 | markLineData = demoC, 22 | markPointData = demoC[,2], 23 | markLineTheme = markLineControl(), 24 | markPointTheme = markPointControl(), 25 | geoData = geoData) 26 | 27 | },height='900px') 28 | }) 29 | -------------------------------------------------------------------------------- /man/get_city_coord.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/get_city_coord.R 3 | \name{get_city_coord} 4 | \alias{get_city_coord} 5 | \title{Get the location information of the city} 6 | \usage{ 7 | get_city_coord(city) 8 | } 9 | \arguments{ 10 | \item{city}{a character object of the name of Chinese city,} 11 | } 12 | \value{ 13 | a vecctor of longtitude and latitude 14 | } 15 | \description{ 16 | get_city_coord use Baidu API <\url{http://developer.baidu.com/map/}> 17 | to get the longtitude and latitude of the city 18 | } 19 | \details{ 20 | This function can transform the name of Chinese city Which 21 | can be a Chinese string or an English name,like Shanghai. 22 | This function is used BaiduAPI to get the geo information. 23 | } 24 | \examples{ 25 | get_city_coord("Shanghai") 26 | } 27 | \author{ 28 | Chiffon <\url{http://lchiffon.github.io}> 29 | } 30 | 31 | -------------------------------------------------------------------------------- /demo/remapDemo.r: -------------------------------------------------------------------------------- 1 | ## ---- REmap demo ---- 2 | ## ---- remapDemo ---- 3 | ## ---- pauseFunction ---- 4 | pause <- function(){ 5 | invisible(readline("\nPress to continue: ")) 6 | } 7 | 8 | 9 | ## ---- Create Data ---- 10 | data(demoC) 11 | demoC[,1] 12 | demoC[,2] 13 | 14 | ## ---- pause ---- 15 | pause() 16 | 17 | ## ---- Dark Theme ---- 18 | set.seed(125) 19 | out = remap(demoC,title = "REmap Demo Data",subtitle = "theme:Dark") 20 | plot(out) 21 | summary(out) 22 | 23 | 24 | ## ---- pause ---- 25 | pause() 26 | 27 | ## ---- Bright Theme ---- 28 | 29 | set.seed(125) 30 | out = remap(demoC,title = "REmap Demo Data",subtitle = "theme:Bright", 31 | theme = get_theme("Bright")) 32 | plot(out) 33 | 34 | ## ---- pause ---- 35 | pause() 36 | 37 | 38 | ## ---- Sky Theme ---- 39 | set.seed(125) 40 | out = remap(demoC,title = "REmap Demo Data",subtitle = "theme:Sky", 41 | theme = get_theme("Sky")) 42 | plot(out) 43 | -------------------------------------------------------------------------------- /inst/shiny/shinyBmap/style.css: -------------------------------------------------------------------------------- 1 | input[type="number"] { 2 | max-width: 80%; 3 | } 4 | 5 | div.outer { 6 | position: fixed; 7 | top: 41px; 8 | left: 0; 9 | right: 0; 10 | bottom: 0; 11 | overflow: hidden; 12 | padding: 0; 13 | } 14 | 15 | /* Customize fonts */ 16 | body, label, input, button, select { 17 | font-family: 'Helvetica Neue', Helvetica; 18 | font-weight: 200; 19 | } 20 | h1, h2, h3, h4 { font-weight: 400; } 21 | 22 | #controls { 23 | /* Appearance */ 24 | background-color: white; 25 | padding: 0 20px 20px 20px; 26 | cursor: move; 27 | /* Fade out while not hovering */ 28 | opacity: 0.65; 29 | zoom: 0.9; 30 | transition: opacity 500ms 1s; 31 | } 32 | #controls:hover { 33 | /* Fade in while hovering */ 34 | opacity: 0.95; 35 | transition-delay: 0; 36 | } 37 | 38 | /* Position and style citation */ 39 | #cite { 40 | position: absolute; 41 | bottom: 10px; 42 | left: 10px; 43 | font-size: 12px; 44 | } 45 | 46 | /* If not using map tiles, show a white background */ 47 | .leaflet-container { 48 | background-color: white !important; 49 | } 50 | -------------------------------------------------------------------------------- /man/remap.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/remap.r 3 | \name{remap} 4 | \alias{remap} 5 | \title{Create an remap object} 6 | \usage{ 7 | remap(mapdata, title = "", subtitle = "", theme = get_theme("Dark")) 8 | } 9 | \arguments{ 10 | \item{mapdata}{a data frame including depart and destination 11 | in each column} 12 | 13 | \item{title}{a character string of the title} 14 | 15 | \item{subtitle}{a character string of the subtitle} 16 | 17 | \item{theme}{a list object created by get_theme,control 18 | the color of the map.} 19 | } 20 | \value{ 21 | An remap object 22 | } 23 | \description{ 24 | remap use a data frame create a remap object 25 | which can be used by plot to see the map by browser 26 | } 27 | \details{ 28 | mapdata should be a dataframe which including two columns, 29 | the first column is depart, second column is destination. 30 | } 31 | \examples{ 32 | set.seed(125) 33 | out = remap(demoC,title = "REmap",subtitle = "theme:Dark") 34 | plot(out) 35 | summary(out) 36 | } 37 | \author{ 38 | Chiffon <\url{http://lchiffon.github.io}> 39 | } 40 | 41 | -------------------------------------------------------------------------------- /R/remap.init.R: -------------------------------------------------------------------------------- 1 | ##' Remap initial for knitr 2 | ##' 3 | ##' @description 4 | ##' An shell function for initializing knitr for remap packages 5 | ##' 6 | ##' @usage recharts.init() 7 | ##' 8 | ##' @details 9 | ##' Only the first chuck of recharts plot needs this function, 10 | ##' the rest chuck mustn't include this function. 11 | ## 12 | 13 | 14 | 15 | 16 | remap.init = function(){ 17 | 18 | htmltools::tagList( 19 | ### initial for echarts svg 20 | htmltools::tag("script",list( 21 | src = "http://echarts.baidu.com/build/dist/echarts.js")), 22 | 23 | htmltools::tag("script",list( 24 | src = "http://echarts.baidu.com/build/dist/echarts-all.js")), 25 | 26 | 27 | 28 | ### initial for echarts Bmap 29 | htmltools::tag("script",list( 30 | type='text/javascript', 31 | src = 'http://lchiffon.github.io/reveal_slidify/echarts/require/main.js')), 32 | 33 | htmltools::tag("script",list( 34 | type='text/javascript', 35 | src = 'http://api.map.baidu.com/api?v=2.0&ak=q9U1lWgCK1aBGVC1DVWrgWa7')), 36 | 37 | 38 | 39 | ### initial for echarts 40 | htmltools::tag("script",list( 41 | type='text/javascript', 42 | src='http://echarts.baidu.com/doc/asset/js/jquery.min.js' 43 | )) 44 | ) 45 | 46 | } 47 | -------------------------------------------------------------------------------- /man/get_geo_position.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/get_geo_position.R 3 | \name{get_geo_position} 4 | \alias{get_geo_position} 5 | \title{Get the location information of the city vector} 6 | \usage{ 7 | get_geo_position(city_vec, cache_data = "city", ...) 8 | } 9 | \arguments{ 10 | \item{city_vec}{a character object of the name of Chinese city,} 11 | 12 | \item{cache_data}{c('city','airport','none') city for city geo_position, 13 | airport for the geo_position in that city, none for nothing for cache} 14 | } 15 | \value{ 16 | A dataframe of longtitude and latitude and city name 17 | } 18 | \description{ 19 | get_geo_position use the function of get_city_coord according 20 | to Baidu API <\url{http://developer.baidu.com/map/}>to get the longtitude and latitude of the city 21 | vector 22 | } 23 | \details{ 24 | This function can transform the name of Chinese city ve tor 25 | Which can be a Chinese string or an English name,like Shanghai. 26 | This function is used BaiduAPI to get the geo information.\\ 27 | It's recomendece to use Chinese city name because of the API 28 | we use is Baidu, which will performs better in Chiese\\ 29 | Please make sure your bowser can open developer.baidu.com/map/ to get the data. 30 | } 31 | \examples{ 32 | city_vec1 = c("Beijing","Shanghai","Guangzhou") 33 | get_geo_position (city_vec1) 34 | } 35 | \author{ 36 | Dawei.Lang Chiffon <\url{http://lchiffon.github.io}> 37 | } 38 | 39 | -------------------------------------------------------------------------------- /R/get_city_coord.R: -------------------------------------------------------------------------------- 1 | ##' Get the location information of the city 2 | ##' 3 | ##' get_city_coord use Baidu API <\url{http://developer.baidu.com/map/}> 4 | ##' to get the longtitude and latitude of the city 5 | ##' 6 | ##' This function can transform the name of Chinese city Which 7 | ##' can be a Chinese string or an English name,like Shanghai. 8 | ##' This function is used BaiduAPI to get the geo information. 9 | ##' 10 | ##' @param city a character object of the name of Chinese city, 11 | ##' @return a vecctor of longtitude and latitude 12 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 13 | ##' @examples 14 | ##' get_city_coord("Shanghai") 15 | 16 | get_city_coord = function(city, ak = getOption("remap.ak")){ 17 | ## Get geodata by Baidu API 18 | if(ak == "q9U1lWgCK1aBGVC1DVWrgWa7"){ 19 | warning("Please use your own baidu API!\nSet it using: options(remap.ak = \"XXXXX\")\nhttp://lbsyun.baidu.com") 20 | } 21 | city = paste0(c("",charToRaw(city)),collapse="%") 22 | url = paste0("http://api.map.baidu.com/place/v2/search?q=",city, 23 | "®ion=",city, 24 | "&output=json&ak=", ak) 25 | doc = XML::htmlParse(url) 26 | # options(warn=-1) 27 | # doc = XML::htmlParse(readLines(url,encoding = 'UTf-8')) 28 | # options(warn=0) 29 | rootNode <- XML::xmlRoot(doc) 30 | list = rjson::fromJSON(XML::xpathSApply(rootNode,"//p", 31 | XML::xmlValue)) 32 | 33 | if(length(list$results) ==0){ 34 | return(c(NA,NA)) 35 | } 36 | output = c(list$results[[1]]$location$lng, 37 | list$results[[1]]$location$lat) 38 | 39 | if(is.null(output)){ 40 | output = c(NA,NA) 41 | } 42 | 43 | return(output) 44 | } 45 | -------------------------------------------------------------------------------- /man/markPointControl.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/markPointControl.R 3 | \name{markPointControl} 4 | \alias{markPointControl} 5 | \title{Control the theme of mark Point} 6 | \usage{ 7 | markPointControl(symbol = 'emptyCircle', 8 | symbolSize = "Random", 9 | effect = T, 10 | effectType = 'scale', 11 | color = "Random") 12 | } 13 | \arguments{ 14 | \item{symbol}{the symbol of the point 15 | default:'pin', can be one of the 'circle','rectangle', 16 | 'triangle','diamond','emptyCircle','emptyRectangle', 17 | 'emptyTriangle','emptyDiamond','heart','droplet','pin','arrow' 18 | 'tar' or the filepath to a fingure file(e.g. 19 | "'image://http://echarts.baidu.com/doc//asset/ico/favicon.png'")} 20 | 21 | \item{symbolSize}{the size of the symbol, default is 10} 22 | 23 | \item{effect}{whether to show glow effect for markPoint symbol} 24 | 25 | \item{effectType}{'scale' or 'bounce'} 26 | 27 | \item{color}{control the color of the markPoint} 28 | } 29 | \description{ 30 | markPointControl is a function for the themes of 31 | mark Point, which can be set as a element in remapC and 32 | remapB 33 | } 34 | \examples{ 35 | mapdata = chinaIphone 36 | geoData = get_geo_position(unique(demoC[demoC==demoC])) 37 | out = remapC(data = mapdata, 38 | color = c("white","white"), 39 | theme=get_theme("none","white","white","white",'white'), 40 | markPointData = demoC[,2], 41 | markPointTheme = markPointControl( 42 | symbol = "image://http://lchiffon.github.io/reveal_slidify/pic/ghost.png", 43 | symbolSize = 50, 44 | effectType = 'bounce' ), 45 | geoData = geoData) 46 | out 47 | } 48 | 49 | -------------------------------------------------------------------------------- /inst/shiny/shinyBmap/ui.R: -------------------------------------------------------------------------------- 1 | 2 | # This is the user-interface definition of a Shiny web application. 3 | # You can find out more about building applications with Shiny here: 4 | # 5 | # http://shiny.rstudio.com 6 | # 7 | 8 | library(shiny) 9 | library(REmap) 10 | shinyUI(fluidPage( 11 | tags$head( 12 | # Include our custom CSS 13 | includeCSS("style.css") 14 | ), 15 | REmapOutput("remap"), 16 | # Application title 17 | 18 | 19 | # Sidebar with a slider input for number of bins 20 | absolutePanel(id = "controls", class = "panel panel-default", fixed = TRUE, 21 | draggable = TRUE, top = 60, left = "auto", right = 20, bottom = "auto", 22 | width = 330, height = "auto", 23 | numericInput("lon", 24 | "Longitude of Center:", 25 | 104.114129, 26 | min = -180, max = 180), 27 | numericInput("lat", 28 | "Latitude of Center:", 29 | 37.550339, 30 | min = -90, max = 90), 31 | numericInput("zoom", 32 | "Zoom Control(larger for more details):", 33 | 5, 34 | min = 1, max = 12), 35 | selectInput("color", "Color of remapB", 36 | c("Bright", "Blue", "light", 37 | "dark", "redalert", "googlelite", 38 | "grassgreen", "midnight", "pink", 39 | "darkgreen", "bluish", "grayscale", 40 | "hardedge"), selected = "Bright"), 41 | textInput("title", "Title of the plot:", value = ""), 42 | textInput("subtitle", "Subtitle of the plot:"), 43 | submitButton(text = "Apply Changes", icon = NULL, width = NULL) 44 | 45 | ) 46 | 47 | # Show a plot of the generated distribution 48 | 49 | 50 | )) 51 | -------------------------------------------------------------------------------- /man/remapH.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/remapH.R 3 | \name{remapH} 4 | \alias{remapH} 5 | \title{Create a heat map} 6 | \usage{ 7 | remapH(data, 8 | maptype = 'china', 9 | theme = get_theme("Dark"), 10 | blurSize = 30, 11 | color = c('blue', 'cyan', 'lime', 'yellow', 'red'), 12 | minAlpha = 0.05, 13 | opacity = 1, 14 | ...) 15 | } 16 | \arguments{ 17 | \item{data}{a data frame including lontitude, latitude and density} 18 | 19 | \item{maptype}{the type of the map. For exameple,'china', 20 | 'world' or other names of province in China.} 21 | 22 | \item{theme}{a list object created by get_theme,control 23 | the color of the map.} 24 | 25 | \item{blurSize}{blur size of the data point, default is 30.} 26 | 27 | \item{color}{a vector of strings like 28 | ['blue', 'cyan', 'lime', 'yellow', 'red'], 29 | with which the color will transform evenly.} 30 | 31 | \item{minAlpha}{If the unified value is less than minAlpha, 32 | remapH will be set to minAlpha to ensure 33 | small data value can also be visible on the chart.} 34 | 35 | \item{opacity}{Opacity of the heatmap. Default is 1} 36 | 37 | \item{...}{other paramters like title, subtitle,data for mark line} 38 | } 39 | \value{ 40 | An remap object of heat map 41 | } 42 | \description{ 43 | remapH uses a data frame create a heat remap object 44 | which can be used by plot to see the map by browser 45 | } 46 | \details{ 47 | data should be a dataframe which including three columns, 48 | the first column is lontitude, second column is latitude, 49 | third column is the density. 50 | } 51 | \examples{ 52 | heatmap = sampleData() 53 | ## This is a function to create sample data as 54 | ## http://echarts.baidu.com/doc/example/heatmap_map.html 55 | 56 | remapH(heatmap,minAlpha = 0.1,title = "Heat Map from REmap") 57 | } 58 | \author{ 59 | Chiffon <\url{http://lchiffon.github.io}> 60 | } 61 | 62 | -------------------------------------------------------------------------------- /man/markLineControl.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/markLineControl.R 3 | \name{markLineControl} 4 | \alias{markLineControl} 5 | \title{Control the theme of mark line} 6 | \usage{ 7 | markLineControl(symbol = c('none', 'arrow'), 8 | symbolSize = c(2,4), 9 | smooth = T, 10 | smoothness = 0.2, 11 | effect = T, 12 | lineWidth = 1, 13 | lineType = 'solid', 14 | color = "Random") 15 | } 16 | \arguments{ 17 | \item{symbol}{the symbol of the point 18 | default:'pin', can be one of the 'circle','rectangle', 19 | 'triangle','diamond','emptyCircle','emptyRectangle', 20 | 'emptyTriangle','emptyDiamond','heart','droplet','pin','arrow' 21 | 'tar' or the filepath to a fingure file(e.g. 22 | "'image://http://echarts.baidu.com/doc//asset/ico/favicon.png'")} 23 | 24 | \item{symbolSize}{the size of the symbol, default is 10} 25 | 26 | \item{smooth}{smoothed line, logical object, default is T, 27 | while smooth is true, lineType can not be dashed.} 28 | 29 | \item{smoothness}{Line smoothness. Only available when smooth is true} 30 | 31 | \item{effect}{whether to show glow effect for markLine symbol} 32 | 33 | \item{lineWidth}{width of the line} 34 | 35 | \item{lineType}{type of the line can be 'solid', 'dotted' 36 | or 'dashed'.} 37 | 38 | \item{color}{Color of the line} 39 | } 40 | \value{ 41 | A list of line control object, which can be used for 42 | } 43 | \description{ 44 | markLineControl is a function for the themes of 45 | mark line, which can be set as a element in remapC and 46 | remapB 47 | } 48 | \examples{ 49 | mapdata = read.csv("demo/chinaIphone.csv") 50 | out = remapC(data = mapdata, 51 | color = c("white","white"), 52 | theme=get_theme("none","white","white","white",'white'), 53 | markPointData = demoC[,2], 54 | markPointTheme = markPointControl( 55 | symbol = "image://demo/1.png", 56 | symbolSize = 50, 57 | effectType = 'bounce' ), 58 | geoData = geoData) 59 | } 60 | 61 | -------------------------------------------------------------------------------- /R/markPointControl.R: -------------------------------------------------------------------------------- 1 | ##' Control the theme of mark Point 2 | ##' 3 | ##' markPointControl is a function for the themes of 4 | ##' mark Point, which can be set as a element in remapC and 5 | ##' remapB 6 | ##' 7 | ##' @usage 8 | ##' markPointControl(symbol = 'emptyCircle', 9 | ##' symbolSize = "Random", 10 | ##' effect = T, 11 | ##' effectType = 'scale', 12 | ##' color = "Random") 13 | ##' 14 | ##' @param symbol the symbol of the point 15 | ##' default:'pin', can be one of the 'circle','rectangle', 16 | ##' 'triangle','diamond','emptyCircle','emptyRectangle', 17 | ##' 'emptyTriangle','emptyDiamond','heart','droplet','pin','arrow' 18 | ##' 'tar' or the filepath to a fingure file(e.g. 19 | ##' "'image://http://echarts.baidu.com/doc//asset/ico/favicon.png'") 20 | ##' @param symbolSize the size of the symbol, default is 10 21 | ##' @param effect whether to show glow effect for markPoint symbol 22 | ##' @param effectType 'scale' or 'bounce' 23 | ##' @param color control the color of the markPoint 24 | ##' @examples 25 | ##' mapdata = chinaIphone 26 | ##' geoData = get_geo_position(unique(demoC[demoC==demoC])) 27 | ##' out = remapC(data = mapdata, 28 | ##' color = c("white","white"), 29 | ##' theme=get_theme("none","white","white","white",'white'), 30 | ##' markPointData = demoC[,2], 31 | ##' markPointTheme = markPointControl( 32 | ##' symbol = "image://http://lchiffon.github.io/reveal_slidify/pic/ghost.png", 33 | ##' symbolSize = 50, 34 | ##' effectType = 'bounce' ), 35 | ##' geoData = geoData) 36 | ##' out 37 | 38 | 39 | 40 | 41 | 42 | markPointControl = function(symbol = 'emptyCircle', 43 | symbolSize = "Random", 44 | effect = T, 45 | effectType = 'scale', 46 | color = "Random"){ 47 | markPointTheme = list() 48 | 49 | markPointTheme$symbol = symbol 50 | markPointTheme$symbolSize = symbolSize 51 | markPointTheme$effect = effect 52 | markPointTheme$effectType = effectType 53 | markPointTheme$color = color 54 | 55 | 56 | return(markPointTheme) 57 | } -------------------------------------------------------------------------------- /R/mapNames.R: -------------------------------------------------------------------------------- 1 | #' Get the names of a choropleth map for remapC 2 | #' 3 | #' mapNames show what kind of map names is needed for remapC 4 | #' 5 | #' @param mapType one of "china", "world" or the name of 6 | #' province in China 7 | #' 8 | #' @return mapNames returns a vec of map names 9 | #' @examples 10 | #' ## get the province names: 11 | #' mapNames('china') 12 | 13 | 14 | mapNames = function(mapType){ 15 | 16 | ## Judge the object type 17 | if(length(mapType)!=1 | class(mapType)!="character") 18 | stop("mapType should be a character object with length 1!") 19 | 20 | ## Find the num of the type 21 | logiVec = (mapType == mapCList[[37]]) 22 | if(sum(logiVec) == 0){ 23 | stop(paste("No map names are found for",mapType)) 24 | } 25 | 26 | index = which(logiVec) 27 | 28 | return(mapCList[[index]]) 29 | } 30 | 31 | 32 | 33 | # 34 | # for(i in 1:36){ 35 | # mapCList[[i]]->mapCList[[i+37]] 36 | # } 37 | # names(mapCList)[38] = "anhui" 38 | # names(mapCList)[39] = "aomen" 39 | # names(mapCList)[40] = "beijing" 40 | # names(mapCList)[41] = "chinaa" 41 | # names(mapCList)[42] = "chongqing" 42 | # names(mapCList)[43] = "fujian" 43 | # names(mapCList)[44] = "gansu" 44 | # names(mapCList)[45] = "guangdong" 45 | # names(mapCList)[46] = "guangxi" 46 | # names(mapCList)[47] = "guizhou" 47 | # names(mapCList)[48] = "hainan" 48 | # names(mapCList)[49] = "heilongjiang" 49 | # names(mapCList)[50] = "hebei" 50 | # names(mapCList)[51] = "henan" 51 | # names(mapCList)[52] = "hubei" 52 | # names(mapCList)[53] = "hunan" 53 | # names(mapCList)[54] = "jiangsu" 54 | # names(mapCList)[55] = "jiangxi" 55 | # names(mapCList)[56] = "jilin" 56 | # names(mapCList)[57] = "liaoning" 57 | # names(mapCList)[58] = "neimenggu" 58 | # names(mapCList)[59] = "ningxia" 59 | # names(mapCList)[60] = "qinghai" 60 | # names(mapCList)[61] = "shanghai" 61 | # names(mapCList)[62] = "shandong" 62 | # names(mapCList)[63] = "shanxi1" 63 | # names(mapCList)[64] = "shanxi2" 64 | # names(mapCList)[65] = "sichuan" 65 | # names(mapCList)[66] = "taiwan" 66 | # names(mapCList)[67] = "tianjin" 67 | # names(mapCList)[68] = "xianggang" 68 | # names(mapCList)[69] = "xinjiang" 69 | # names(mapCList)[70] = "xizang" 70 | # names(mapCList)[71] = "yunnan" 71 | # names(mapCList)[72] = "zhejiang" 72 | -------------------------------------------------------------------------------- /man/remapC.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/remapC.R 3 | \name{remapC} 4 | \alias{remapC} 5 | \title{Create a choropleth map object} 6 | \usage{ 7 | remapC(data, 8 | maptype = 'china', 9 | markLineData = NULL, 10 | markPointData = NULL, 11 | color = c('#1e90ff','#f0ffff'), 12 | theme = get_theme("Bright"), 13 | title = "", 14 | subtitle = "", 15 | markLineTheme = markLineControl(), 16 | markPointTheme = markPointControl(), 17 | geoData = NA, 18 | mindata = NA, 19 | maxdata = NA) 20 | } 21 | \arguments{ 22 | \item{data}{a data frame including place names and values} 23 | 24 | \item{maptype}{the type of the map. For example,'china', 25 | 'world' or other names of province in China.} 26 | 27 | \item{markLineData}{data for mark line} 28 | 29 | \item{markPointData}{data for mark point} 30 | 31 | \item{color}{vector of the color, if the length of color is 32 | 1, white will be added to the color.} 33 | 34 | \item{theme}{a list object created by get_theme,control 35 | the color of the map.} 36 | 37 | \item{title}{a character string of the title} 38 | 39 | \item{subtitle}{a character string of the subtitle} 40 | 41 | \item{markLineTheme}{theme for mark line} 42 | 43 | \item{geoData}{geoData for markLine and markPoint format is 44 | similar as get_geo_position()} 45 | 46 | \item{mindata}{mindata for legend} 47 | 48 | \item{maxdata}{maxdata for legend} 49 | 50 | \item{markLineTheme}{theme for mark point} 51 | } 52 | \value{ 53 | An remap object 54 | } 55 | \description{ 56 | remapC uses a data frame create a remap object 57 | which can be used by plot to see the map by browser 58 | } 59 | \details{ 60 | mapdata should be a dataframe which including two columns, 61 | the first column is the names of places, 62 | second column is value. 63 | } 64 | \examples{ 65 | data = data.frame(country = mapNames("world"), 66 | value = 5*sample(178)+200) 67 | head(data) 68 | out = remapC(data,maptype = "world",color = 'skyblue') 69 | plot(out) 70 | 71 | remapC(chinaIphone, 72 | markLineData = demoC, 73 | markPointData = demoC[,2]) 74 | } 75 | \author{ 76 | Chiffon <\url{http://lchiffon.github.io}> 77 | } 78 | 79 | -------------------------------------------------------------------------------- /R/reGG.R: -------------------------------------------------------------------------------- 1 | 2 | ## New object 3 | setClass("remapgg", 4 | representation ( 5 | mapdata = "data.frame", 6 | maptype = "character", 7 | print = "logical", 8 | argument = "list" 9 | )) 10 | 11 | 12 | 13 | ## show object 14 | setMethod("show", 15 | signature = "remapgg", 16 | definition = function(object){ 17 | if(object@print){ 18 | plot.remap(do.call(remap,object@argument)) 19 | }else{ 20 | print(object@argument) 21 | } 22 | 23 | }) 24 | 25 | ## basic function 26 | newmap = function(mapdata){ 27 | object = new("remapgg") 28 | object@print = TRUE 29 | object@argument$mapdata = mapdata 30 | object@argument$title = "" 31 | object@argument$subtitle = "" 32 | object 33 | } 34 | 35 | 36 | ## add title 37 | reTitle = function(title){ 38 | output = new("remapgg") 39 | output@print = F 40 | output@argument$title = title 41 | output 42 | } 43 | 44 | 45 | reSubtitle = function(subtitle){ 46 | output = new("remapgg") 47 | output@print = F 48 | output@argument$subtitle = subtitle 49 | output 50 | } 51 | 52 | reTheme = function(...){ 53 | output = new("remapgg") 54 | output@print = F 55 | output@argument$theme = get_theme(...) 56 | output 57 | } 58 | 59 | 60 | `+.remapgg` = function(object1,object2){ 61 | if(class(object2)!= "remapgg"){ 62 | stop("object2 should be a remapgg object") 63 | } 64 | 65 | if(!is.null(object2@argument$title)){ 66 | object1@argument$title = object2@argument$title 67 | } 68 | 69 | if(!is.null(object2@argument$subtitle)){ 70 | object1@argument$subtitle = object2@argument$subtitle 71 | } 72 | 73 | 74 | if(!is.null(object2@argument$theme)){ 75 | object1@argument$theme = object2@argument$theme 76 | } 77 | 78 | 79 | # theme notfound 80 | # if(!is.null(object2@argument$title)){ 81 | # object1@argument@title = object2@argument@title 82 | # } 83 | object1 84 | } 85 | 86 | # 87 | # 88 | # p = newmap(demoC) 89 | # 90 | # p + reTitle("remapGG") 91 | # 92 | # p + reTitle("remapGG") + reSubtitle("remapGG subtitle") 93 | # 94 | # p + reTheme(theme = "Bright",lineColor = "Random") + 95 | # reTitle("TryTryTry") -------------------------------------------------------------------------------- /R/zzz.r: -------------------------------------------------------------------------------- 1 | .onAttach <- function(libname, pkgname ){ 2 | path = tempdir() 3 | 4 | # if(!dir.exists(paste0(path,"/js"))){ 5 | # dir.create(paste0(path,"/js")) 6 | # } 7 | dir.create(paste0(path,"/js")) 8 | 9 | ## save echarts.js 10 | if(!file.exists(paste0(path,"/js/echart.js"))){ 11 | file.copy(from = system.file("JS/echarts.js",package = 'REmap'), 12 | to = paste0(path,"/js")) 13 | } 14 | 15 | 16 | ## Save echarts-all.js 17 | if(!file.exists(paste0(path,"/js/echarts-all.js"))){ 18 | file.copy(from = system.file("JS/echarts-all.js",package = 'REmap'), 19 | to = paste0(path,"/js")) 20 | } 21 | 22 | ## Save main.js 23 | if(!file.exists(paste0(path,"/js/main.js"))){ 24 | file.copy(from = system.file("JS/main.js",package = 'REmap'), 25 | to = paste0(path,"/js")) 26 | } 27 | 28 | ## Save map.js 29 | if(!file.exists(paste0(path,"/js/chart/map.js"))){ 30 | file.copy(from = system.file("JS/chart",package = 'REmap'), 31 | to = paste0(path,"/js"), 32 | recursive = T) 33 | } 34 | 35 | ## Save juqery.min.js 36 | if(!file.exists(paste0(path,"/js/jquery.min.js"))){ 37 | file.copy(from = system.file("JS/jquery.min.js",package = 'REmap'), 38 | to = paste0(path,"/js")) 39 | } 40 | 41 | options(remap.js.dir = "./js") 42 | options(remap.js.web = FALSE) 43 | options(remap.ak = "q9U1lWgCK1aBGVC1DVWrgWa7") 44 | 45 | } 46 | 47 | 48 | setClass("remap", 49 | representation ( 50 | id = "character", 51 | maptype = "character", 52 | option = "character", 53 | theme = "list", 54 | content = "character" 55 | )) 56 | 57 | 58 | setMethod("show", 59 | signature = "remap", 60 | definition = function(object){ 61 | 62 | plot.remap(object,path = "") 63 | }) 64 | 65 | 66 | 67 | setMethod("summary", 68 | signature = "remap", 69 | definition = function(object){ 70 | cat("Object ID:\n") 71 | cat(object@id) 72 | cat("\nMap Type:\n") 73 | cat(object@maptype) 74 | cat("\nFile Position:\n") 75 | cat(file_name = paste0("~/",object@id,".html")) 76 | cat("\nLength of Content:\n") 77 | cat(length(strsplit(out@content,"\\n")[[1]])) 78 | }) 79 | -------------------------------------------------------------------------------- /R/get_geo_position.R: -------------------------------------------------------------------------------- 1 | ##' Get the location information of the city vector 2 | ##' 3 | ##' get_geo_position use the function of get_city_coord according 4 | ##' to Baidu API <\url{http://developer.baidu.com/map/}>to get the longtitude and latitude of the city 5 | ##' vector 6 | ##' 7 | ##' This function can transform the name of Chinese city ve tor 8 | ##' Which can be a Chinese string or an English name,like Shanghai. 9 | ##' This function is used BaiduAPI to get the geo information.\\ 10 | ##' It's recomendece to use Chinese city name because of the API 11 | ##' we use is Baidu, which will performs better in Chiese\\ 12 | ##' Please make sure your bowser can open developer.baidu.com/map/ to get the data. 13 | ##' 14 | ##' @param city_vec a character object of the name of Chinese city, 15 | ##' @param cache_data c('city','airport','none') city for city geo_position, 16 | ##' airport for the geo_position in that city, none for nothing for cache 17 | ##' @return A dataframe of longtitude and latitude and city name 18 | ##' @author Dawei.Lang Chiffon <\url{http://lchiffon.github.io}> 19 | ##' @examples 20 | ##' city_vec1 = c("Beijing","Shanghai","Guangzhou") 21 | ##' get_geo_position (city_vec1) 22 | 23 | 24 | 25 | 26 | get_geo_position = function(city_vec,cache_data = 'city',...){ 27 | #city data load("data/city.Rdata") 28 | 29 | if(cache_data == 'city'){ 30 | cache = REmapCityGeo 31 | }else if(cache_data == 'airport'){ 32 | cache = airport 33 | }else if(cache_data == 'none'){ 34 | cache = data.frame(city = 'nooooo') 35 | }else{ 36 | warning("There's no cache data called",cache_data,",use city instead") 37 | } 38 | 39 | lab_list = sapply(city_vec, function(x) which(x == cache$city)) 40 | 41 | index = sapply(lab_list,function(x) length(x)==0) 42 | 43 | in_list = lab_list[!index] 44 | 45 | if(length(in_list)!=length(city_vec)){ 46 | 47 | in_list = do.call(c,in_list) 48 | out_list = names(lab_list)[index] 49 | 50 | OutputData = data.frame(lon = 0, 51 | lat = 0) 52 | 53 | for ( i in 1:length(out_list)){ 54 | OutputData[i,] = get_city_coord(out_list[i],...) 55 | } 56 | OutputData$city = out_list 57 | 58 | OutputData = rbind(OutputData,cache[in_list,]) 59 | }else{ 60 | OutputData = cache[in_list,] 61 | } 62 | 63 | naData = OutputData[!complete.cases(OutputData),] 64 | if(nrow(naData)!=0){ 65 | warning(paste(paste(naData$city),"not found.")) 66 | OutputData = na.omit(OutputData) 67 | } 68 | 69 | 70 | OutputData 71 | } 72 | -------------------------------------------------------------------------------- /demo/remapCDemo.R: -------------------------------------------------------------------------------- 1 | ## ---- REmap demo ---- 2 | ## ---- remapCDemo ---- 3 | ## ---- pauseFunction ---- 4 | pause <- function(){ 5 | invisible(readline("\nPress to continue: ")) 6 | } 7 | data(demoC) 8 | 9 | 10 | ## default theme:"Dark" 11 | set.seed(125) 12 | out = remap(demoC,title = "REmap Sample Data",subtitle = "theme:Bright", 13 | theme = get_theme("Bright")) 14 | plot(out) 15 | 16 | ## ---- pause ---- 17 | pause() 18 | 19 | ## set Line color as 'orange' 20 | set.seed(125) 21 | out = remap(demoC,title = "REmap Sample Data",subtitle = "theme:Bright", 22 | theme = get_theme("None", 23 | lineColor = "orange")) 24 | plot(out) 25 | ## ---- pause ---- 26 | pause() 27 | 28 | 29 | ## Set backgroundColor as 'red'(#FF0000) 30 | 31 | out = remap(demoC,title = "REmap Sample Data",subtitle = "theme:Bright", 32 | theme = get_theme("None", 33 | lineColor = "orange", 34 | backgroundColor = "#FF0000")) 35 | plot(out) 36 | ## ---- pause ---- 37 | pause() 38 | 39 | 40 | 41 | ## Set TitleColor 42 | out = remap(demoC,title = "REmap Sample Data",subtitle = "theme:Bright", 43 | theme = get_theme("None", 44 | lineColor = "orange", 45 | backgroundColor = "#FFC1C1", 46 | titleColor = "#1b1b1b")) 47 | plot(out) 48 | ## ---- pause ---- 49 | pause() 50 | 51 | 52 | 53 | ## Set Region Color 54 | out = remap(demoC,title = "REmap Sample Data",subtitle = "theme:Bright", 55 | theme = get_theme("None", 56 | lineColor = "orange", 57 | backgroundColor = "#FFC1C1", 58 | titleColor = "#1b1b1b", 59 | regionColor = '#ADD8E6')) 60 | plot(out) 61 | 62 | ## ---- pause ---- 63 | pause() 64 | 65 | out = remapC(data = mapdata,title = "REmap Choropleth Map", 66 | maxdata= 2500) 67 | out 68 | 69 | ## ---- pause ---- 70 | pause() 71 | data(mapdata) 72 | out = remapC(data = mapdata,theme = get_theme("Dark"), 73 | color = c('skyblue','darkblue'), 74 | title = "REmap Choropleth Map") 75 | out 76 | 77 | 78 | ## ---- pause ---- 79 | pause() 80 | data = data.frame(country = mapNames("world"), 81 | value = 5*sample(178)+200) 82 | head(data) 83 | 84 | ## ---- pause ---- 85 | pause() 86 | out = remapC(data,maptype = "world",color = 'skyblue') 87 | plot(out) 88 | -------------------------------------------------------------------------------- /demo/remapBDemo.R: -------------------------------------------------------------------------------- 1 | ## ---- REmap demo ---- 2 | ## ---- remapBDemo ---- 3 | ## ---- pauseFunction ---- 4 | pause <- function(){ 5 | invisible(readline("\nPress to continue: ")) 6 | } 7 | data(demoC) 8 | ## Test for Bmap 9 | 10 | 11 | geoData = get_geo_position(unique(demoC[demoC==demoC])) 12 | # this may take some time,be patient~ 13 | 14 | remapB(markLineData = demoC,geoData = geoData) 15 | ## ---- pause ---- 16 | pause() 17 | 18 | 19 | remapB(markLineData = demoC,geoData = geoData, 20 | markLineTheme = markLineControl(color = 'red')) 21 | ## ---- pause ---- 22 | pause() 23 | 24 | 25 | data(demoC) 26 | demoC$tooltip = sample(letters,nrow(demoC)) 27 | remapB(markLineData = demoC,geoData = geoData, 28 | markLineTheme = markLineControl(color = 'red')) 29 | 30 | ## ---- pause ---- 31 | pause() 32 | 33 | demoC$linewidth = sample(5,nrow(demoC),replace = T) 34 | remapB(markLineData = demoC,geoData = geoData, 35 | markLineTheme = markLineControl(color = 'red')) 36 | ## ---- pause ---- 37 | pause() 38 | 39 | 40 | 41 | remapB(markLineData = demoC,color = "Blue",geoData = geoData) 42 | ## ---- pause ---- 43 | pause() 44 | 45 | 46 | 47 | remapB(markLineData = demoC,markPointData = demoC[,2], 48 | color = "Blue",geoData = geoData) 49 | ## ---- pause ---- 50 | pause() 51 | 52 | 53 | remapB(markPointData = demoC[,2], 54 | color = "Blue",geoData = geoData) 55 | ## ---- pause ---- 56 | pause() 57 | 58 | 59 | newdata = data.frame(a = demoC[,2], 60 | color = c(rep("blue",5),rep("red",5))) 61 | remapB(markPointData = newdata, 62 | color = "Blue",geoData = geoData) 63 | ## ---- pause ---- 64 | pause() 65 | 66 | 67 | 68 | newdata$symbolSize = 1:10 69 | remapB(markPointData = newdata, 70 | color = "Blue",geoData = geoData) 71 | ## ---- pause ---- 72 | pause() 73 | 74 | 75 | 76 | newdata$tooltip = paste(newdata$a,newdata$symbolSize,sep = ":") 77 | remapB(markPointData = newdata, 78 | color = "Blue",geoData = geoData) 79 | ## ---- pause ---- 80 | pause() 81 | 82 | data(chinaIphone) 83 | ## markLineControl 84 | mapdata = chinaIphone 85 | geoData = get_geo_position(unique(demoC[demoC==demoC])) 86 | out = remapC(data = mapdata, 87 | color = c("white","white"), 88 | theme=get_theme("none","white","white","white",'white'), 89 | markPointData = demoC[,2], 90 | markPointTheme = markPointControl( 91 | symbol = "image://http://lchiffon.github.io/reveal_slidify/pic/ghost.png", 92 | symbolSize = 50, 93 | effectType = 'bounce' ), 94 | geoData = geoData) 95 | out 96 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## REmap 2 | ### Create html maps by Echarts 3 | 4 | - Version: 0.3 5 | - Authors@R: "Dawei Lang [aut, cre]" 6 | - Description: Provides an R interface to the JavaScript library ECharts for 7 | interactive map data visualization. 8 | - Depends: R (>= 3.1.2) 9 | - License: MIT + file LICENS 10 | 11 | - [REmap Tutorial](http://lchiffon.github.io/REmap) 12 | 13 | ``` 14 | library(devtools) 15 | install_github('lchiffon/REmap') 16 | ``` 17 | 18 | 19 | 20 | 21 | 22 | ---- 23 | ### 更新日志 24 | 25 | #### V0.3.2 26 | - remapB函数添加11个新主题 27 | 28 | ![](http://lchiffon.github.io/reveal_slidify/echarts/all.png) 29 | 30 | - 修复Bug 31 | 32 | 33 | #### V0.3.1 34 | - 新生成的图片将存储在R的临时文件夹中,并在退出R后删除 35 | - 可以使用`options(remap.js.web = T)`来切换保存到工作目录的模式 36 | 37 | #### V0.3 38 | - 修复remapC的warning bugs 39 | - 新增remapH热力图效果 40 | 41 | #### V0.2.2 42 | 43 | - 调整demo的文档,可以用demo函数来调用 44 | - `get_geo_postion`把原始的机场经纬度chche改为城市经纬度 45 | - fix bugs 46 | 47 | #### V0.2.1 48 | 49 | - 在调用remapC与remapB时,可以设置line和point的tooltip 50 | - 调用markPoint可以在数据中设置symbolSize来控制点的大小 51 | - 增加knitr的支持 52 | 53 | #### V0.2 54 | 55 | - 增加分级统计图(Choropleth Map): remapC 56 | - 增加Bmap(百度地图与Echarts的结合): remapB 57 | - get_theme函数中增加三个新的控制变量 58 | - 格式化markLine和markPoint的使用 59 | - 删去了帮助文档的中文字符 60 | - 修正Windows用户下geo-cahce的问题(更快地获取地理信息) 61 | 62 | #### V0.1 63 | 64 | - 基础函数: remap 65 | 66 | 67 | ---- 68 | ### Update Log 69 | #### V0.3.2 70 | - Add 11 new themes into remapB function 71 | - Fix bugs 72 | 73 | 74 | #### V0.3.1 75 | - New pictures will be saved in the R temporary file path 76 | - USe `options(remap.js.web = T)` to set options for saving pictures into working directory 77 | 78 | #### V0.3 79 | - fix warning bugs of remapC 80 | - add remapH heatmap function 81 | 82 | #### V0.2.2 83 | 84 | - Support demo for REmap 85 | - Change the airport cache data to city data in `get_geo_position` function 86 | - Fix bugs 87 | 88 | #### V0.2.1 89 | 90 | - Add tooltip to markpoint and markLine( set a vector called 'tooltip' to the data) 91 | - Add symbolSize to markpoint( set a vector called 'symbolsize' to the data) 92 | - Support REmap in knitr 93 | 94 | #### V0.2 95 | 96 | - Add Choropleth Map into REmap: remapC 97 | - Add BaiduMap into REmap: remapB 98 | - Add three new control into get_theme 99 | - Add markLine,markPoint control 100 | - Delete Chinese character in .Rd file 101 | - Fix geo-cache system in windows 102 | 103 | #### V0.1 104 | 105 | - Demo function: remap 106 | -------------------------------------------------------------------------------- /man/remapB.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/remapB.R 3 | \name{remapB} 4 | \alias{remapB} 5 | \title{Create a Bmap object} 6 | \usage{ 7 | remapB(center = c(104.114129,37.550339), 8 | zoom = 5, 9 | color = "Bright", 10 | title = "", 11 | subtitle = "", 12 | markLineData = NA, 13 | markPointData = NA, 14 | markLineTheme = markLineControl(), 15 | markPointTheme = markPointControl(), 16 | geoData = NA) 17 | } 18 | \arguments{ 19 | \item{center}{the center of the Bmap,a vector of (lon,lat), 20 | you can get from get_city_coord, e.g.get_city_coord("beijing")} 21 | 22 | \item{zoom}{the size of the Bmap, zoom:5 country data, 23 | zoom:15 city data} 24 | 25 | \item{color}{"Bright", "Blue", "light", "dark", "redalert", 26 | "googlelite", "grassgreen", "midnight", "pink", "darkgreen", 27 | "bluish", "grayscale", "hardedge"} 28 | 29 | \item{title}{a character string of the title} 30 | 31 | \item{subtitle}{a character string of the subtitle} 32 | 33 | \item{markLineData}{data for mark line} 34 | 35 | \item{markPointData}{data for mark point} 36 | 37 | \item{markLineTheme}{theme for mark line} 38 | 39 | \item{geoData}{geoData for markLine and markPoint format is 40 | similar as get_geo_position()} 41 | 42 | \item{markLineTheme}{theme for mark point} 43 | } 44 | \value{ 45 | An remap object 46 | } 47 | \description{ 48 | remapB uses BaiduAPI instead of SVG object as the map object. 49 | You can mark line or point on the remapB. 50 | } 51 | \examples{ 52 | geoData = get_geo_position(unique(demoC[demoC==demoC])) 53 | # this may take some time,be patient~ 54 | 55 | remapB(markLineData = demoC,geoData = geoData) 56 | 57 | # Different themes 58 | remapB(markLineData = demoC,color = "Blue",geoData = geoData) 59 | remapB(markLineData = demoC,color = "light",geoData = geoData) 60 | remapB(markLineData = demoC,color = "dark",geoData = geoData) 61 | remapB(markLineData = demoC,color = "redalert",geoData = geoData) 62 | remapB(markLineData = demoC,color = "googlelite",geoData = geoData) 63 | remapB(markLineData = demoC,color = "grassgreen",geoData = geoData) 64 | remapB(markLineData = demoC,color = "midnight",geoData = geoData) 65 | remapB(markLineData = demoC,color = "pink",geoData = geoData) 66 | remapB(markLineData = demoC,color = "darkgreen",geoData = geoData) 67 | remapB(markLineData = demoC,color = "bluish",geoData = geoData) 68 | remapB(markLineData = demoC,color = "grayscale",geoData = geoData) 69 | remapB(markLineData = demoC,color = "hardedge",geoData = geoData) 70 | 71 | remapB(markLineData = demoC,markPointData = demoC[,2], 72 | color = "Blue",geoData = geoData) 73 | } 74 | \author{ 75 | Chiffon <\url{http://lchiffon.github.io}> 76 | } 77 | 78 | -------------------------------------------------------------------------------- /R/plot.remap.R: -------------------------------------------------------------------------------- 1 | ##' plot the remap object 2 | ##' 3 | ##' plot.remap is a function to create the htmlfile 4 | ##' and open it by browser 5 | ##' 6 | ##' 7 | ##' @param object an remap object 8 | ##' @param path the path for saving REmap object 9 | ##' @return Create a html file according to the id of the object 10 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 11 | ##' @examples 12 | ##' set.seed(125) 13 | ##' out = remap(demoC,title = "REmap: Demo DATA", 14 | ##' subtitle = "theme:Dark") 15 | ##' plot(out) 16 | 17 | 18 | plot.remap = function(object,path = ""){ 19 | 20 | if(.Platform$OS.type == "windows"){ 21 | locate = Sys.getlocale("LC_CTYPE") 22 | Sys.setlocale("LC_CTYPE", 23 | "chs") 24 | } 25 | 26 | 27 | 28 | 29 | ## Web js, don't need to rewrite JS 30 | if( getOption('remap.js.web')){ 31 | file_name = paste0(object@id,".html") 32 | writeLines(object@content, 33 | paste0(path,file_name), 34 | useBytes = T) 35 | }else{ 36 | ## else, write file to local temp files 37 | path = tempdir() 38 | file_name = paste0(path,"/",object@id,".html") 39 | local.plot(object,file_name) 40 | } 41 | 42 | if(.Platform$OS.type == "windows"){ 43 | Sys.setlocale("LC_CTYPE",locate) 44 | } 45 | 46 | cat("Save img as:",file_name) 47 | browseURL(file_name) 48 | } 49 | 50 | 51 | 52 | local.plot = function(object,file_name){ 53 | 54 | 55 | 56 | ## SVG rewrite JS path 57 | if(object@maptype == 'SVG'){ 58 | content = sub("http://echarts.baidu.com/build/dist/echarts.js", 59 | "./js/echarts.js", 60 | object@content) 61 | content = sub("http://echarts.baidu.com/build/dist/echarts-all.js", 62 | "./js/echarts-all.js", 63 | content) 64 | } 65 | 66 | if(object@maptype == 'SVGH'){ 67 | content = sub("http://echarts.baidu.com/build/dist/echarts.js", 68 | "./js/echarts.js", 69 | object@content) 70 | content = sub("http://echarts.baidu.com/build/dist/echarts-all.js", 71 | "./js/echarts-all.js", 72 | content) 73 | } 74 | ## Bmap rewrite JS path 75 | if(object@maptype == "Bmap"){ 76 | content = sub("http://echarts.baidu.com/build/dist/echarts.js", 77 | "./js/echarts.js", 78 | object@content) 79 | content = sub("http://lchiffon.github.io/reveal_slidify/echarts/require/jquery.min.js", 80 | "./js/jquery.min.js", 81 | content) 82 | 83 | content = sub("http://lchiffon.github.io/reveal_slidify/echarts/require", 84 | "./js", 85 | content) 86 | 87 | content = sub("http://lchiffon.github.io/reveal_slidify/echarts/require", 88 | "./js", 89 | content) 90 | } 91 | writeLines(content, 92 | file_name, 93 | useBytes = T) 94 | 95 | } 96 | -------------------------------------------------------------------------------- /R/markLineControl.R: -------------------------------------------------------------------------------- 1 | ##' Control the theme of mark line 2 | ##' 3 | ##' markLineControl is a function for the themes of 4 | ##' mark line, which can be set as a element in remapC and 5 | ##' remapB 6 | ##' 7 | ##' @usage 8 | ##' markLineControl(symbol = c('none', 'arrow'), 9 | ##' symbolSize = c(2,4), 10 | ##' smooth = T, 11 | ##' smoothness = 0.2, 12 | ##' effect = T, 13 | ##' lineWidth = 1, 14 | ##' lineType = 'solid', 15 | ##' color = "Random") 16 | ##' 17 | ##' @param symbol the symbol of the point 18 | ##' default:'pin', can be one of the 'circle','rectangle', 19 | ##' 'triangle','diamond','emptyCircle','emptyRectangle', 20 | ##' 'emptyTriangle','emptyDiamond','heart','droplet','pin','arrow' 21 | ##' 'tar' or the filepath to a fingure file(e.g. 22 | ##' "'image://http://echarts.baidu.com/doc//asset/ico/favicon.png'") 23 | ##' @param symbolSize the size of the symbol, default is 10 24 | ##' @param smooth smoothed line, logical object, default is T, 25 | ##' while smooth is true, lineType can not be dashed. 26 | ##' @param smoothness Line smoothness. Only available when smooth is true 27 | ##' @param effect whether to show glow effect for markLine symbol 28 | ##' @param lineWidth width of the line 29 | ##' @param lineType type of the line can be 'solid', 'dotted' 30 | ##' or 'dashed'. 31 | ##' @param color Color of the line 32 | ##' @return A list of line control object, which can be used for 33 | ##' 34 | ##' @examples 35 | ##' mapdata = read.csv("demo/chinaIphone.csv") 36 | ##' out = remapC(data = mapdata, 37 | ##' color = c("white","white"), 38 | ##' theme=get_theme("none","white","white","white",'white'), 39 | ##' markPointData = demoC[,2], 40 | ##' markPointTheme = markPointControl( 41 | ##' symbol = "image://demo/1.png", 42 | ##' symbolSize = 50, 43 | ##' effectType = 'bounce' ), 44 | ##' geoData = geoData) 45 | 46 | 47 | 48 | markLineControl = function(symbol = c('none', 'arrow'), 49 | symbolSize = c(2,4), 50 | smooth = T, 51 | smoothness = 0.2, 52 | effect = T, 53 | lineWidth = 1, 54 | lineType = 'solid', 55 | color = "Random"){ 56 | markLineTheme = list() 57 | if(length(symbol) > 2){ 58 | warning("Only first two symbol will be used in the markLineTheme") 59 | }else if(length(symbol) == 1){ 60 | symbol = c(symbol,symbol) 61 | } 62 | markLineTheme$symbol = paste0("['",symbol[1],"', '",symbol[2],"']") 63 | 64 | 65 | if(length(symbolSize) > 2){ 66 | warning("Only first two symbol will be used in the markLineTheme") 67 | }else if(length(symbolSize) == 1){ 68 | symbolSize = c(symbolSize,symbolSize) 69 | } 70 | markLineTheme$symbolSize = paste0("['",symbolSize[1], 71 | "', '",symbolSize[2],"']") 72 | 73 | markLineTheme$smooth = smooth 74 | markLineTheme$smoothness = smoothness 75 | markLineTheme$effect = effect 76 | markLineTheme$lineWidth = lineWidth 77 | if(!lineType %in% c('solid','dotted','dashed')){ 78 | warning(paste("Line type of",lineType,"is not support!")) 79 | } 80 | markLineTheme$lineType = lineType 81 | markLineTheme$color = color 82 | 83 | 84 | return(markLineTheme) 85 | } -------------------------------------------------------------------------------- /man/get_theme.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2 (4.1.1): do not edit by hand 2 | % Please edit documentation in R/get_theme.R 3 | \name{get_theme} 4 | \alias{get_theme} 5 | \title{Create a theme object for remap} 6 | \usage{ 7 | get_theme(theme = "Dark", lineColor = "Random", 8 | backgroundColor = "#1b1b1b", titleColor = "#fff", 9 | borderColor = "rgba(100,149,237,1)", regionColor = "#1b1b1b", 10 | labelShow = T, pointShow = F, pointColor = "gold") 11 | } 12 | \arguments{ 13 | \item{theme}{a character object in ("Dark","Bright,"Sky","none)} 14 | 15 | \item{lineColor}{Control the color of the line, "Random" for 16 | random color} 17 | 18 | \item{backgroundColor}{Control the color of the background} 19 | 20 | \item{titleColor}{Control the color of the title} 21 | 22 | \item{borderColor}{Control the color of the border} 23 | 24 | \item{regionColor}{Control the color of the region} 25 | 26 | \item{labelShow}{whether show the label of each element, 27 | only support mapC.} 28 | 29 | \item{pointShow}{whether show the center point of each element, 30 | only support mapC.} 31 | 32 | \item{pointColor}{color of the center point of each element, 33 | only support mapC.} 34 | } 35 | \value{ 36 | A list of color control, which can be used by remap 37 | } 38 | \description{ 39 | get_theme create a theme list to control the color 40 | we see in the remap.including lineColor, backgroundColor, 41 | titleColor, borderColor and regionColor. 42 | } 43 | \details{ 44 | If you use the theme argument of the get_theme function, 45 | you will get the default theme in one of ("Dark","Bright,"Sky"). 46 | If you don't like the color, set theme = "none" and use other 47 | parameters control remap.\\ 48 | Can use "red","#1b1b1b" or rgba(100,100,100,1) to control the color 49 | } 50 | \examples{ 51 | ## default theme:"Dark" 52 | set.seed(125) 53 | out = remap(demoC,title = "REmap",subtitle = "theme:Bright", 54 | theme = get_theme("Bright")) 55 | plot(out) 56 | 57 | ## set Line color as 'orange' 58 | set.seed(125) 59 | out = remap(demoC,title = "REmap",subtitle = "theme:Bright", 60 | theme = get_theme("None", 61 | lineColor = "orange")) 62 | plot(out) 63 | 64 | ## Set backgroundColor as 'red'(#FF0000) 65 | 66 | out = remap(demoC,title = "REmap",subtitle = "theme:Bright", 67 | theme = get_theme("None", 68 | lineColor = "orange", 69 | backgroundColor = "#FF0000")) 70 | plot(out) 71 | 72 | ## Set TitleColor 73 | out = remap(demoC,title = "REmap",subtitle = "theme:Bright", 74 | theme = get_theme("None", 75 | lineColor = "orange", 76 | backgroundColor = "#FFC1C1", 77 | titleColor = "#1b1b1b")) 78 | plot(out) 79 | 80 | ## Set Region Color 81 | out = remap(demoC,title = "REmap",subtitle = "theme:Bright", 82 | theme = get_theme("None", 83 | lineColor = "orange", 84 | backgroundColor = "#FFC1C1", 85 | titleColor = "#1b1b1b", 86 | regionColor = '#ADD8E6')) 87 | plot(out) 88 | } 89 | \author{ 90 | Chiffon <\url{http://lchiffon.github.io}> 91 | } 92 | 93 | -------------------------------------------------------------------------------- /R/knitrREmap.R: -------------------------------------------------------------------------------- 1 | ##' Plot REmap in knitr 2 | ##' 3 | ##' @description 4 | ##' Function for plotting REmap in knitr 5 | ##' 6 | ##' 7 | ##' 8 | ##' @param objct an REmap object for plotting 9 | ##' @param height height for the DOM of REmap 10 | ##' @param width width for the DOM of REmap 11 | ##' 12 | ##' @details 13 | ##' After using the remap.init function, you can use this function 14 | ##' for plotting REmap in knitr in any chuck 15 | ##' 16 | ##' @examples 17 | ##' library(REmap) 18 | ##' out = remap(demoC) 19 | ##' knitrREmap(out) 20 | 21 | 22 | 23 | 24 | 25 | knitrREmap = function(object, 26 | height = "300px", 27 | width = "100%", 28 | local = F){ 29 | 30 | 31 | if(.Platform$OS.type == "windows"){ 32 | locate = Sys.getlocale("LC_CTYPE") 33 | Sys.setlocale("LC_CTYPE", 34 | "chs") 35 | # local = T 36 | } 37 | 38 | if(local){ 39 | # if(!dir.exists("js")){ 40 | dir.create("js") 41 | # } 42 | } 43 | 44 | if(object@maptype == "Bmap"){ 45 | 46 | foot = sub("optionNameData", 47 | paste0("option", object@id), html.knitr.list$Bmap.foot) 48 | ##write Bmap content 49 | content = paste0(html.knitr.list$Bmap.head, 50 | object@option, 51 | foot) 52 | 53 | 54 | content = sub("#main", 55 | paste0("#",object@id) 56 | ,content) 57 | 58 | 59 | }else if(object@maptype == "SVG"){ 60 | head = sub("optionNameData", 61 | paste0("option", object@id), html.knitr.list$SVG.head) 62 | 63 | foot = sub("optionNameData", 64 | paste0("option", object@id), html.knitr.list$SVG.foot) 65 | 66 | ## write SVG content 67 | content = paste0(head, 68 | object@option, 69 | foot) 70 | 71 | content = sub("main", 72 | object@id 73 | ,content) 74 | 75 | }else if(object@maptype == "SVGH"){ 76 | 77 | foot = sub("optionNameData", 78 | paste0("option", object@id), html.knitr.list$SVGH.foot) 79 | 80 | ## write SVG content 81 | content = paste0(html.knitr.list$SVGH.head, 82 | object@option, 83 | foot) 84 | 85 | content = sub("main", 86 | object@id 87 | ,content) 88 | 89 | } 90 | 91 | 92 | 93 | if(local){ 94 | file_name = paste0(object@id,".js") 95 | writeLines(content, 96 | paste0("js/",file_name), 97 | useBytes = T) 98 | } 99 | 100 | if(.Platform$OS.type == "windows"){ 101 | Sys.setlocale("LC_CTYPE",locate) 102 | } 103 | 104 | 105 | if(local){ 106 | 107 | htmltools::tagList( 108 | ### initial for echarts svg 109 | htmltools::tag("div",list( 110 | id = object@id, 111 | style = sprintf("height:%s; width:%s",height,width))), 112 | 113 | 114 | htmltools::tag("script",list( 115 | src = sprintf("js/%s.js",object@id)))) 116 | 117 | }else{ 118 | 119 | htmltools::tagList( 120 | ### initial for echarts svg 121 | htmltools::tag("div",list( 122 | id = object@id, 123 | style = sprintf("height:%s; width:%s",height,width))), 124 | 125 | 126 | htmltools::tag("script",list( 127 | content))) 128 | 129 | 130 | 131 | } 132 | 133 | } 134 | 135 | 136 | 137 | html.knitr.list = list(Bmap.head = "", 138 | Bmap.foot = " 139 | var myChart = BMapExt.initECharts(container); 140 | window.onresize = myChart.onresize; 141 | BMapExt.setOption(optionNameData); 142 | } 143 | ); 144 | })();", 145 | SVG.head = " var myChart = echarts.init(document.getElementById(\"main\")); 146 | 147 | var optionNameData = ", 148 | SVG.foot = "; 149 | myChart.setOption(optionNameData); ", 150 | SVGH.head = 151 | " var myChart = echarts.init(document.getElementById(\"main\"));", 152 | SVGH.foot = "; 153 | myChart.setOption(optionNameData); " 154 | ) 155 | -------------------------------------------------------------------------------- /R/renderREmap.R: -------------------------------------------------------------------------------- 1 | ##' Plot REmap in shiny 2 | ##' 3 | ##' @description 4 | ##' Function for plotting REmap in shiny 5 | ##' 6 | ##' @usage 7 | ##' REmapOutput(outputId, inline = FALSE, container,...) 8 | ##' renderREmap(expr, env = parent.frame(),height = "800px", 9 | ##' width = "100%", quoted = FALSE, func = NULL) 10 | ##' 11 | ##' @details 12 | ##' USe renderREmap render an REmap object and use REmapOutput 13 | ##' output an REmap object. See more details in shiny package. 14 | ##' 15 | ##' @examples 16 | ##' library(REmap) 17 | ##' library(shiny) 18 | ##' runApp(system.file("shiny","shinyBmap", package = "REmap")) 19 | REmapOutput =function (outputId, inline = FALSE, container = if (inline) span else div, 20 | ...) 21 | { 22 | div(includeHTML(remap.shiny.init()), 23 | container(id = outputId, class = "shiny-html-output", ...)) 24 | } 25 | 26 | renderREmap = function (expr, env = parent.frame(), quoted = FALSE, func = NULL, 27 | height = "800px", 28 | width = "100%") 29 | { 30 | if (!is.null(func)) { 31 | shinyDeprecated(msg = "renderUI: argument 'func' is deprecated. Please use 'expr' instead.") 32 | } 33 | else { 34 | installExprFunction(expr, "func", env, quoted) 35 | } 36 | markRenderFunction(uiOutput, function(shinysession, name, 37 | ...) { 38 | result <- func() 39 | if (is.null(result) || length(result) == 0) 40 | return(NULL) 41 | 42 | output = intoHtmlObject(result, height = height, width = width) 43 | output <- htmltools::takeSingletons(output, shinysession$singletons, 44 | desingleton = FALSE)$ui 45 | output <- htmltools::surroundSingletons(output) 46 | # dependencies <- lapply(resolveDependencies(findDependencies(output)), 47 | # createWebDependency) 48 | # names(dependencies) <- NULL 49 | output <- list(html = htmltools::doRenderTags(output), deps = NULL) 50 | return(output) 51 | 52 | }) 53 | } 54 | 55 | intoHtmlObject = function(object, 56 | height = "1200px", 57 | width = "100%"){ 58 | 59 | 60 | if(.Platform$OS.type == "windows"){ 61 | locate = Sys.getlocale("LC_CTYPE") 62 | Sys.setlocale("LC_CTYPE", 63 | "chs") 64 | 65 | } 66 | 67 | if(object@maptype == "Bmap"){ 68 | 69 | foot = sub("optionNameData", 70 | paste0("option", object@id), html.knitr.list$Bmap.foot) 71 | ##write Bmap content 72 | content = paste0(html.knitr.list$Bmap.head, 73 | object@option, 74 | foot) 75 | 76 | 77 | content = sub("#main", 78 | paste0("#",object@id) 79 | ,content) 80 | 81 | 82 | }else if(object@maptype == "SVG"){ 83 | head = sub("optionNameData", 84 | paste0("option", object@id), html.knitr.list$SVG.head) 85 | 86 | foot = sub("optionNameData", 87 | paste0("option", object@id), html.knitr.list$SVG.foot) 88 | 89 | ## write SVG content 90 | content = paste0(head, 91 | object@option, 92 | foot) 93 | 94 | content = sub("main", 95 | object@id 96 | ,content) 97 | 98 | }else if(object@maptype == "SVGH"){ 99 | 100 | foot = sub("optionNameData", 101 | paste0("option", object@id), html.knitr.list$SVGH.foot) 102 | 103 | ## write SVG content 104 | content = paste0(html.knitr.list$SVGH.head, 105 | object@option, 106 | foot) 107 | 108 | content = sub("main", 109 | object@id 110 | ,content) 111 | 112 | } 113 | 114 | 115 | 116 | 117 | if(.Platform$OS.type == "windows"){ 118 | Sys.setlocale("LC_CTYPE",locate) 119 | } 120 | 121 | 122 | 123 | 124 | htmltools::tagList( 125 | ### initial for echarts svg 126 | htmltools::tag("div",list( 127 | id = object@id, 128 | style = sprintf("height:%s; width:%s",height,width))), 129 | htmltools::tag("script",list( 130 | content))) 131 | 132 | } 133 | 134 | 135 | remap.shiny.init = function(){ 136 | return(file.path(system.file("shiny", package = "REmap"), "remapWidget.html" )) 137 | 138 | } 139 | -------------------------------------------------------------------------------- /ID_20191206165920_22851.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /ID_20191206170358_13612.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /R/get_theme.R: -------------------------------------------------------------------------------- 1 | ##' Create a theme object for remap 2 | ##' 3 | ##' get_theme create a theme list to control the color 4 | ##' we see in the remap.including lineColor, backgroundColor, 5 | ##' titleColor, borderColor and regionColor. 6 | ##' 7 | ##' If you use the theme argument of the get_theme function, 8 | ##' you will get the default theme in one of ("Dark","Bright,"Sky"). 9 | ##' If you don't like the color, set theme = "none" and use other 10 | ##' parameters control remap.\\ 11 | ##' Can use "red","#1b1b1b" or rgba(100,100,100,1) to control the color 12 | ##' 13 | ##' 14 | ##' @param theme a character object in ("Dark","Bright,"Sky","none) 15 | ##' @param lineColor Control the color of the line, "Random" for 16 | ##' random color 17 | ##' @param backgroundColor Control the color of the background 18 | ##' @param titleColor Control the color of the title 19 | ##' @param borderColor Control the color of the border 20 | ##' @param regionColor Control the color of the region 21 | ##' @param labelShow whether show the label of each element, 22 | ##' only support mapC. 23 | ##' @param pointShow whether show the center point of each element, 24 | ##' only support mapC. 25 | ##' @param pointColor color of the center point of each element, 26 | ##' only support mapC. 27 | ##' @return A list of color control, which can be used by remap 28 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 29 | ##' @examples 30 | ##' ## default theme:"Dark" 31 | ##' set.seed(125) 32 | ##' out = remap(demoC,title = "REmap示例数据",subtitle = "theme:Bright", 33 | ##' theme = get_theme("Bright")) 34 | ##' plot(out) 35 | ##' 36 | ##' ## set Line color as 'orange' 37 | ##' set.seed(125) 38 | ##' out = remap(demoC,title = "REmap示例数据",subtitle = "theme:Bright", 39 | ##' theme = get_theme("None", 40 | ##' lineColor = "orange")) 41 | ##' plot(out) 42 | ##' 43 | ##' ## Set backgroundColor as 'red'(#FF0000) 44 | ##' 45 | ##' out = remap(demoC,title = "REmap示例数据",subtitle = "theme:Bright", 46 | ##' theme = get_theme("None", 47 | ##' lineColor = "orange", 48 | ##' backgroundColor = "#FF0000")) 49 | ##' plot(out) 50 | ##' 51 | ##' ## Set TitleColor 52 | ##' out = remap(demoC,title = "REmap示例数据",subtitle = "theme:Bright", 53 | ##' theme = get_theme("None", 54 | ##' lineColor = "orange", 55 | ##' backgroundColor = "#FFC1C1", 56 | ##' titleColor = "#1b1b1b")) 57 | ##' plot(out) 58 | ##' 59 | ##' ## Set Region Color 60 | ##' out = remap(demoC,title = "REmap示例数据",subtitle = "theme:Bright", 61 | ##' theme = get_theme("None", 62 | ##' lineColor = "orange", 63 | ##' backgroundColor = "#FFC1C1", 64 | ##' titleColor = "#1b1b1b", 65 | ##' regionColor = '#ADD8E6')) 66 | ##' plot(out) 67 | 68 | 69 | 70 | get_theme = function(theme = "Dark", 71 | lineColor = "Random", 72 | backgroundColor = "#1b1b1b", 73 | titleColor = "#fff", 74 | borderColor = "rgba(100,149,237,1)", 75 | regionColor = "#1b1b1b", 76 | labelShow = T, 77 | pointShow = F, 78 | pointColor = 'gold'){ 79 | 80 | 81 | theme_data = list( 82 | Dark = list( 83 | lineColor = "Random", 84 | backgroundColor = "#1b1b1b", 85 | titleColor = "#fff", 86 | borderColor = "rgba(100,149,237,1)", 87 | regionColor = "#1b1b1b", 88 | labelShow = 'true', 89 | pointShow = 'false', 90 | pointColor = 'gold' 91 | ), 92 | Bright = list( 93 | lineColor = "Random", 94 | backgroundColor = "#D9D9D9", 95 | titleColor = "#1b1b1b", 96 | borderColor = "rgba(100,149,237,1)", 97 | regionColor = "#fff", 98 | labelShow = 'true', 99 | pointShow = 'false', 100 | pointColor = 'gold' 101 | ), 102 | Sky = list( 103 | lineColor = "Random", 104 | backgroundColor = "#fff", 105 | titleColor = "#1b1b1b", 106 | borderColor = "rgba(100,149,237,1)", 107 | regionColor = "#AEEEEE", 108 | labelShow = 'true', 109 | pointShow = 'false', 110 | pointColor = 'gold' 111 | ) 112 | ) 113 | 114 | 115 | if(labelShow){ 116 | labelShow = 'true' 117 | }else{ 118 | labelShow = 'false' 119 | } 120 | 121 | if(pointShow){ 122 | pointShow = 'true' 123 | }else{ 124 | pointShow = 'false' 125 | } 126 | 127 | 128 | 129 | if (theme %in% c("Dark","Bright","Sky")){ 130 | out_theme = theme_data[[theme]] 131 | }else{ 132 | out_theme = list( 133 | lineColor = lineColor, 134 | backgroundColor = backgroundColor, 135 | titleColor = titleColor, 136 | borderColor = borderColor, 137 | regionColor = regionColor, 138 | labelShow = labelShow, 139 | pointShow = pointShow, 140 | pointColor = pointColor 141 | ) 142 | } 143 | 144 | if(out_theme$lineColor == "Random"){ 145 | out_theme$lineColor2 = 146 | "['#ff3333', 'orange', 'yellow','lime','aqua']" 147 | }else{ 148 | out_theme$lineColor2 = 149 | paste0("['",out_theme$lineColor, 150 | "', '", 151 | out_theme$lineColor,"', '", 152 | out_theme$lineColor,"', '", 153 | out_theme$lineColor,"', '", 154 | out_theme$lineColor,"']") 155 | } 156 | out_theme 157 | } -------------------------------------------------------------------------------- /R/markPointStr.R: -------------------------------------------------------------------------------- 1 | markPointStr = function(markPointData, 2 | markPointTheme, 3 | geoData){ 4 | 5 | 6 | if(length(markPointData) == 0 ){ 7 | stop("Mark Point data should have at least 1 object") 8 | } 9 | 10 | if(is.null(dim(markPointData))){ 11 | markPointData = data.frame(markPointData) 12 | } 13 | 14 | if(!is.character(markPointData[1,1])){ 15 | markPointData[,1] = as.character(markPointData[,1]) 16 | } 17 | 18 | symbol = markPointTheme$symbol 19 | symbolSize = markPointTheme$symbolSize 20 | effect = markPointTheme$effect 21 | effectType = markPointTheme$effectType 22 | color = markPointTheme$color 23 | 24 | ## If geoData is not founded,search geoData from baiduAPI 25 | if(!is.data.frame(geoData)){ 26 | city_vec = unique(markPointData[,1]) 27 | 28 | geoData = get_geo_position(city_vec) 29 | 30 | } 31 | 32 | if(!is.numeric(geoData[1,1])){ 33 | geoData[,1] = as.numeric(as.character(geoData[,1])) 34 | geoData[,2] = as.numeric(as.character(geoData[,2])) 35 | } 36 | 37 | if(!is.character(geoData[1,3])){ 38 | geoData[,3] = as.character(geoData[,3]) 39 | } 40 | 41 | ## If geo Data is exists 42 | if(!all(sapply(geoData,class) == 43 | c("numeric","numeric","character"))){ 44 | stop("Format of geoData is similar as get_geo_position()!") 45 | } 46 | 47 | ## Geo str 48 | city_data_vec = apply(geoData,1,function(x) 49 | paste0("'", 50 | x[3], 51 | "'", 52 | ': [' 53 | ,x[1], 54 | ',', 55 | x[2], 56 | ']')) 57 | geoDataStr = paste(city_data_vec,collapse = ",\n") 58 | 59 | 60 | n = nrow(markPointData) 61 | dataName = tolower(names(markPointData)) 62 | symbolExist = 'symbol' %in% dataName 63 | 64 | if(symbolExist){ 65 | symboldata = markPointData[,which('symbol' == dataName)] 66 | }else{ 67 | symboldata = rep(symbol[1],n) 68 | } 69 | 70 | 71 | colorExist = 'color' %in% dataName 72 | symbolsizeExist = 'symbolsize' %in% dataName 73 | tooltipExist = 'tooltip' %in% dataName 74 | 75 | 76 | if(colorExist){ 77 | colorData = "function(param){ 78 | return(param.data.value.colorValue); 79 | }" 80 | colorValue = sprintf("'%s'", 81 | markPointData[,which('color' == dataName)] 82 | ) 83 | }else if(color == "Random"){ 84 | colorData = "function(param){ 85 | return(param.data.value.colorValue); 86 | }" 87 | randomColor = c('#ff3333', 'orange', 'yellow','lime','aqua') 88 | colorValue = sprintf("'%s'", 89 | sample(randomColor,n,replace = T) 90 | ) 91 | }else{ 92 | colorData = sprintf("'%s'",color) 93 | colorValue = NULL 94 | } 95 | 96 | if(symbolsizeExist){ 97 | symbolsizeData = "function(param){ 98 | return(param.symbolsizeValue); 99 | }" 100 | symbolsizeValue = markPointData[,which('symbolsize' == dataName)] 101 | 102 | symbolsizeValue = as.numeric(symbolsizeValue) 103 | symbolsizeValue = round( 104 | (symbolsizeValue-min(symbolsizeValue))/ 105 | (max(symbolsizeValue)-min(symbolsizeValue))*13 + 7 106 | ) 107 | 108 | }else if(symbolSize == "Random"){ 109 | symbolsizeData = "function (v){ 110 | return(10+Math.round(Math.random()*10)); 111 | }" 112 | symbolsizeValue = NULL 113 | }else{ 114 | symbolsizeData = symbolSize 115 | symbolsizeValue = NULL 116 | } 117 | 118 | if(tooltipExist){ 119 | tooltipValue = sprintf("'%s'",as.character( 120 | markPointData[,which('tooltip' == dataName)])) 121 | }else{ 122 | tooltipValue = NULL 123 | } 124 | 125 | 126 | valueDF = as.data.frame(cbind(colorValue, 127 | symbolsizeValue, 128 | tooltipValue), 129 | stringsAsFactors = F) 130 | 131 | if(symbolsizeExist){ 132 | valueDF$symbolsizeValue = as.numeric(valueDF$symbolsizeValue) 133 | } 134 | 135 | if(any(symbolsizeExist, 136 | colorExist, 137 | color=="Random", 138 | tooltipExist)){ 139 | valuedata = getValue(valueDF) 140 | }else{ 141 | valuedata = sample(100,nrow(markPointData),replace = T) 142 | } 143 | 144 | mapdata = data.frame(markPointData[,1], 145 | symboldata, 146 | valuedata) 147 | 148 | # if(colorExist){ 149 | # colordata = markPointData[,which('color' == dataName)] 150 | # }else if(color == "Random"){ 151 | # randomColor = c('#ff3333', 'orange', 'yellow','lime','aqua') 152 | # colordata = sample(randomColor,n,replace = T) 153 | # }else if(length(color) > 1){ 154 | # colordata = sample(color,n,replace = T) 155 | # }else{ 156 | # colordata = rep(color,n) 157 | # } 158 | # 159 | # 160 | # 161 | # mapdata = data.frame(markPointData[,1], 162 | # symboldata, 163 | # colordata) 164 | 165 | ###markPointData 166 | 167 | markpoint = apply(mapdata,1,function(x) 168 | paste0("{name:'",x[1],"',value:",x[3],",symbol:'",x[2],"'}")) 169 | markPointStr= paste(markpoint,collapse = ",\n") 170 | 171 | 172 | if(effect){ 173 | effect = 'true' 174 | }else{ 175 | effect = 'false' 176 | } 177 | 178 | 179 | 180 | Output = paste0(",markPoint : { 181 | symbol:'emptyCircle', 182 | symbolSize :",symbolsizeData,", 183 | effect : { 184 | show: ",effect,", 185 | type: '",effectType,"', 186 | shadowBlur : 0 187 | }, 188 | itemStyle:{ 189 | normal:{ 190 | label:{show:false}, 191 | color:",colorData," 192 | }, 193 | emphasis: { 194 | label:{show:false} 195 | } 196 | }, 197 | data : [",markPointStr," 198 | ]}, 199 | geoCoord:{", 200 | geoDataStr," 201 | } 202 | ") 203 | 204 | 205 | Output 206 | 207 | } 208 | -------------------------------------------------------------------------------- /R/markLineStr.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | markLineStr = function(markLineData, 4 | markLineTheme, 5 | geoData){ 6 | 7 | if(!is.data.frame(markLineData)){ 8 | stop("Mark Line data should be a data frame.") 9 | } 10 | 11 | markLineData = na.omit(markLineData) 12 | 13 | if(ncol(markLineData)<2 | nrow(markLineData) == 0 ){ 14 | stop("Mark Line data should have at least 2 columns and 1 row") 15 | } 16 | 17 | if(!is.character(markLineData[1,1])){ 18 | markLineData[,1] = as.character(markLineData[,1]) 19 | markLineData[,2] = as.character(markLineData[,2]) 20 | } 21 | 22 | 23 | symbol = markLineTheme$symbol 24 | symbolSize = markLineTheme$symbolSize 25 | smooth = markLineTheme$smooth 26 | smoothness = markLineTheme$smoothness 27 | effect = markLineTheme$effect 28 | lineWidth = markLineTheme$lineWidth 29 | lineType = markLineTheme$lineType 30 | 31 | color = markLineTheme$color 32 | 33 | ## If geoData is not founded,search geoData from baiduAPI 34 | if(length(dim(geoData))!=2){ 35 | city_vec = unique(c(markLineData[,1],markLineData[,2])) 36 | 37 | geoData = get_geo_position(city_vec) 38 | 39 | } 40 | 41 | if(!is.numeric(geoData[1,1])){ 42 | geoData[,1] = as.numeric(as.character(geoData[,1])) 43 | geoData[,2] = as.numeric(as.character(geoData[,2])) 44 | } 45 | 46 | if(!is.character(geoData[1,3])){ 47 | geoData[,3] = as.character(geoData[,3]) 48 | } 49 | 50 | ## If geo Data is exists 51 | if(!all(sapply(geoData,class) == 52 | c("numeric","numeric","character"))){ 53 | stop("Format of geoData is similar as get_geo_position()!") 54 | } 55 | 56 | ## Geo str 57 | city_data_vec = apply(geoData,1,function(x) 58 | paste0("'", 59 | x[3], 60 | "'", 61 | ': [' 62 | ,x[1], 63 | ',', 64 | x[2], 65 | ']')) 66 | geoDataStr = paste(city_data_vec,collapse = ",\n") 67 | 68 | 69 | n = nrow(markLineData) 70 | dataName = tolower(names(markLineData)) 71 | colorExist = 'color' %in% dataName 72 | linewidthExist = 'linewidth' %in% dataName 73 | tooltipExist = 'tooltip' %in% dataName 74 | 75 | 76 | if(colorExist){ 77 | colorData = "function(param){ 78 | return(param.data[0].value.colorValue); 79 | }" 80 | colorValue = sprintf("'%s'", 81 | markLineData[,which('color' == dataName)] 82 | ) 83 | }else if(color == "Random"){ 84 | colorData = "function(param){ 85 | return(param.data[0].value.colorValue); 86 | }" 87 | randomColor = c('#ff3333', 'orange', 'yellow','lime','aqua') 88 | colorValue = sprintf("'%s'", 89 | sample(randomColor,n,replace = T) 90 | ) 91 | }else{ 92 | colorData = sprintf("'%s'",color) 93 | colorValue = NULL 94 | } 95 | 96 | if(linewidthExist){ 97 | linewidthData = "function(param){ 98 | return(param.data[0].value.linewidthValue); 99 | }" 100 | linewidthValue = markLineData[,which('linewidth' == dataName)] 101 | }else{ 102 | linewidthData = lineWidth 103 | linewidthValue = NULL 104 | } 105 | 106 | if(tooltipExist){ 107 | tooltipValue = sprintf("'%s'", 108 | as.character( 109 | markLineData[,which('tooltip' == dataName)]) 110 | ) 111 | }else{ 112 | tooltipValue = NULL 113 | } 114 | 115 | 116 | valueDF = as.data.frame(cbind(colorValue, 117 | linewidthValue, 118 | tooltipValue), 119 | stringsAsFactors = F) 120 | 121 | if(linewidthExist){ 122 | valueDF$linewidthValue = as.numeric(valueDF$linewidthValue) 123 | } 124 | 125 | if(any(linewidthExist, 126 | colorExist, 127 | color=="Random", 128 | tooltipExist)){ 129 | valuedata = getValue(valueDF) 130 | }else{ 131 | #valuedata = sample(100,nrow(markLineData)) 132 | valuedata = sample(100,nrow(markLineData),replace=T) 133 | } 134 | # if(colorExist){ 135 | # colordata = markLineData[,which('color' == dataName)] 136 | # }else if(color == "Random"){ 137 | # randomColor = c('#ff3333', 'orange', 'yellow','lime','aqua') 138 | # colordata = sample(randomColor,n,replace = T) 139 | # }else if(length(color) > 1){ 140 | # colordata = sample(color,n,replace = T) 141 | # }else{ 142 | # colordata = rep(color,n) 143 | # } 144 | # 145 | # 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | mapdata = data.frame(markLineData[,1], 154 | markLineData[,2], 155 | valuedata) 156 | 157 | ###markLineData 158 | markLine = apply(mapdata,1,function(x) 159 | paste0("[{name:'",x[1],"'}, {name:'",x[2], 160 | "',value:",x[3],"}]" )) 161 | markLineStr = paste(markLine,collapse = ",\n") 162 | 163 | if(smooth){ 164 | smooth = 'true' 165 | }else{ 166 | smooth = 'false' 167 | } 168 | 169 | if(effect){ 170 | effect = 'true' 171 | }else{ 172 | effect = 'false' 173 | } 174 | 175 | 176 | Output = paste0(" 177 | ,markLine : { 178 | Symbol:",symbol,", 179 | symbolSize:",symbolSize,", 180 | smooth:",smooth,", 181 | smooth:",smoothness,", 182 | effect : { 183 | show: ",effect,", 184 | scaleSize: 1, 185 | period: 30, 186 | color: '#fff', 187 | shadowBlur: 10 188 | }, 189 | itemStyle : { 190 | color: 'red', 191 | normal: { 192 | color:",colorData,", 193 | borderWidth:1, 194 | lineStyle: { 195 | type: '",lineType,"', 196 | width: ",lineWidth,", 197 | shadowBlur: 10 198 | }, 199 | label:{show:false} 200 | } 201 | }, 202 | 203 | data : [", 204 | markLineStr, 205 | "]}, 206 | geoCoord:{", 207 | geoDataStr," 208 | } 209 | ") 210 | 211 | Output 212 | } 213 | 214 | # 215 | # a = 1:26 216 | # b = letters 217 | # c = NULL 218 | # 219 | # b = sapply(b,function(x) sprintf("'%s'",x)) 220 | # c = sapply(c,function(x) sprintf("'%s'",x)) 221 | # valueDF = as.data.frame(cbind(a,b,c),stringsAsFactors = F) 222 | # valueDF$a = as.numeric(valueDF$a) 223 | 224 | 225 | getValue = function(valueDF){ 226 | col = ncol(valueDF) 227 | for ( i in 1: col){ 228 | valueDF[,i] = paste0(names(valueDF)[i],":",valueDF[,i]) 229 | } 230 | 231 | as = apply(valueDF,1,function(x) { 232 | sprintf("{%s}",paste(x,collapse = ",")) 233 | }) 234 | #as = gsub("\"","",as) 235 | # as = gsub("\n","",as) 236 | 237 | as 238 | } 239 | -------------------------------------------------------------------------------- /R/remap.r: -------------------------------------------------------------------------------- 1 | ##' Create an remap object 2 | ##' 3 | ##' remap use a data frame create a remap object 4 | ##' which can be used by plot to see the map by browser 5 | ##' 6 | ##' mapdata should be a dataframe which including two columns, 7 | ##' the first column is depart, second column is destination. 8 | ##' 9 | ##' @param mapdata a data frame including depart and destination 10 | ##' in each column 11 | ##' @param title a character string of the title 12 | ##' @param subtitle a character string of the subtitle 13 | ##' @param theme a list object created by get_theme,control 14 | ##' the color of the map. 15 | ##' @return An remap object 16 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 17 | ##' @examples 18 | ##' set.seed(125) 19 | ##' out = remap(demoC,title = "REmap",subtitle = "theme:Dark") 20 | ##' plot(out) 21 | ##' summary(out) 22 | 23 | 24 | remap = function(mapdata, 25 | title = "", 26 | subtitle = "", 27 | theme = get_theme("Dark")){ 28 | if(.Platform$OS.type == "windows"){ 29 | locate = Sys.getlocale("LC_CTYPE") 30 | Sys.setlocale("LC_CTYPE", 31 | "English_United Kingdom.1252") 32 | } 33 | 34 | ### Test and create label: 35 | if(!is.data.frame(mapdata)){ 36 | stop("Map data should be a data frame.") 37 | } 38 | 39 | mapdata = na.omit(mapdata) 40 | 41 | if(ncol(mapdata)<2 | nrow(mapdata) == 0 ){ 42 | stop("Mapdata should have at least 2 columns and 1 row") 43 | } 44 | 45 | if(ncol(mapdata) == 2){ 46 | label = apply(mapdata,1,function(x) paste(x[1],x[2],sep = " -- ")) 47 | }else{ 48 | label = mapdata[,3] 49 | } 50 | 51 | ### Get geo position 52 | if(!is.character(mapdata[1,1])){ 53 | mapdata[,1] = as.character(mapdata[,1]) 54 | mapdata[,2] = as.character(mapdata[,2]) 55 | } 56 | city_vec = unique(c(mapdata[,1],mapdata[,2])) 57 | 58 | Geo_data = get_geo_position(city_vec) 59 | 60 | 61 | 62 | ###geoCoord_data 63 | mapdata$value = sample(seq(0,100,10),nrow(mapdata),replace = T) 64 | 65 | city_data_vec = apply(Geo_data,1,function(x) 66 | paste0("'", 67 | x[3], 68 | "'", 69 | ': [' 70 | ,x[1], 71 | ',', 72 | x[2], 73 | ']')) 74 | geoCoord_data = paste(city_data_vec,collapse = ",\n") 75 | 76 | ###markLineData 77 | markLine = apply(mapdata,1,function(x) 78 | paste0("[{name:'",x[1],"'}, {name:'",x[2], 79 | "',value:",x[3],"}]" )) 80 | markLineData = paste(markLine,collapse = ",\n") 81 | 82 | ### markPointData 83 | 84 | markpoint = apply(mapdata,1,function(x) 85 | paste0("{name:'",x[2],"',value:",x[3],"}")) 86 | markPointData= paste(markpoint,collapse = ",\n") 87 | 88 | 89 | 90 | 91 | ### write remap object 92 | output = new("remap") 93 | output@id = paste('ID', format(Sys.time(), "%Y%m%d%H%M%S"), round(proc.time()[3]*100), sep="_") 94 | output@theme = theme 95 | output@maptype = "SVG" 96 | 97 | output@option = html.data$option 98 | head = html.data$head 99 | foot = html.data$foot 100 | 101 | if(.Platform$OS.type == "windows"){ 102 | Sys.setlocale("LC_CTYPE", 103 | "chs") 104 | } 105 | 106 | output@option = sub("forChange", 107 | "一",output@option) 108 | 109 | output@option = sub("backgroundColorData", 110 | theme$backgroundColor,output@option) 111 | output@option = sub("titleData",title,output@option) 112 | output@option = sub("subtitleData",subtitle,output@option) 113 | output@option = sub("titleColorData",theme$titleColor,output@option) 114 | output@option = sub("lineColorData",theme$lineColor2,output@option) 115 | output@option = sub("borderColorData",theme$borderColor,output@option) 116 | output@option = sub("regionColorData",theme$regionColor,output@option) 117 | output@option = sub("geoCoord_data",geoCoord_data,output@option) 118 | output@option = sub("markLineData",markLineData,output@option) 119 | output@option = sub("markPointData",markPointData,output@option) 120 | 121 | ## optionNameData 122 | outputHead= sub("optionNameData", 123 | paste0("option", output@id),head) 124 | outputFoot = sub("optionNameData", 125 | paste0("option", output@id),foot) 126 | 127 | 128 | output@option = strsplit(output@option,"kkkmmm")[[1]][2] 129 | output@content = paste(outputHead,output@option,outputFoot,sep = "\n") 130 | 131 | if(.Platform$OS.type == "windows"){ 132 | Sys.setlocale("LC_CTYPE",locate) 133 | } 134 | return(output) 135 | } 136 | 137 | 138 | 139 | html.data = list( 140 | head = " 141 | 142 | 143 | 151 | 152 | 153 |
154 | 155 | 156 | 260 | 261 | " 262 | ) 263 | -------------------------------------------------------------------------------- /R/remapC.R: -------------------------------------------------------------------------------- 1 | ##' Create a choropleth map object 2 | ##' 3 | ##' remapC uses a data frame create a remap object 4 | ##' which can be used by plot to see the map by browser 5 | ##' 6 | ##' mapdata should be a dataframe which including two columns, 7 | ##' the first column is the names of places, 8 | ##' second column is value. 9 | ##' 10 | ##' @usage 11 | ##' remapC(data, 12 | ##' maptype = 'china', 13 | ##' markLineData = NULL, 14 | ##' markPointData = NULL, 15 | ##' color = c('#1e90ff','#f0ffff'), 16 | ##' theme = get_theme("Bright"), 17 | ##' title = "", 18 | ##' subtitle = "", 19 | ##' markLineTheme = markLineControl(), 20 | ##' markPointTheme = markPointControl(), 21 | ##' geoData = NA, 22 | ##' mindata = NA, 23 | ##' maxdata = NA) 24 | ##' 25 | ##' 26 | ##' @param data a data frame including place names and values 27 | ##' @param maptype the type of the map. For example,'china', 28 | ##' 'world' or other names of province in China. 29 | ##' @param title a character string of the title 30 | ##' @param subtitle a character string of the subtitle 31 | ##' @param theme a list object created by get_theme,control 32 | ##' the color of the map. 33 | ##' @param color vector of the color, if the length of color is 34 | ##' 1, white will be added to the color. 35 | ##' @param markLineData data for mark line 36 | ##' @param markPointData data for mark point 37 | ##' @param markLineTheme theme for mark line 38 | ##' @param markLineTheme theme for mark point 39 | ##' @param geoData geoData for markLine and markPoint format is 40 | ##' similar as get_geo_position() 41 | ##' @param mindata mindata for legend 42 | ##' @param maxdata maxdata for legend 43 | ##' @return An remap object 44 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 45 | ##' @examples 46 | ##' data = data.frame(country = mapNames("world"), 47 | ##' value = 5*sample(178)+200) 48 | ##' head(data) 49 | ##' out = remapC(data,maptype = "world",color = 'skyblue') 50 | ##' plot(out) 51 | ##' 52 | ##' remapC(chinaIphone, 53 | ##' markLineData = demoC, 54 | ##' markPointData = demoC[,2]) 55 | 56 | remapC = function(data, 57 | maptype = 'china', 58 | markLineData = NULL, 59 | markPointData = NULL, 60 | color = c('#1e90ff','#f0ffff'), 61 | theme = get_theme("Bright"), 62 | title = "", 63 | subtitle = "", 64 | markLineTheme = markLineControl(), 65 | markPointTheme = markPointControl(), 66 | geoData = NA, 67 | mindata = NA, 68 | maxdata = NA){ 69 | 70 | if(.Platform$OS.type == "windows"){ 71 | locate = Sys.getlocale("LC_CTYPE") 72 | Sys.setlocale("LC_CTYPE","eng") 73 | } 74 | 75 | if(!is.data.frame(data)){ 76 | stop("Map data should be a data frame.") 77 | } 78 | 79 | data = na.omit(data) 80 | 81 | if(ncol(data)<2 | nrow(data) == 0 ){ 82 | stop("Data should have at least 2 columns and 1 row") 83 | } 84 | 85 | if(!is.character(data[1,1])){ 86 | data[,1] = as.character(data[,1]) 87 | } 88 | 89 | if(!is.numeric(data[1,2])){ 90 | stop("Column 2 should be numeric!") 91 | } 92 | 93 | maptype = checkMapName(maptype) 94 | mapnames = mapNames(mapType = maptype) 95 | # hit = sum(sapply(data[,1],function(x) 96 | # sum(x %in% mapnames)))/length(mapnames) 97 | # 98 | # if(hit<0.5){ 99 | # warning(paste0("Over 50% places(column 1) are not found in ",maptype)) 100 | # } 101 | 102 | if(is.null(data$tooltip)){ 103 | mapCVec = apply(data,1,function(x) 104 | paste0("{name:'",x[1], 105 | "',value:",x[2],"}" )) 106 | }else{ 107 | mapCVec = apply(data,1,function(x) 108 | paste0("{name:'",x[1], 109 | "',value:",x[2],",tooltipValue:",x[3],"}" )) 110 | } 111 | 112 | 113 | mapCData = paste(mapCVec,collapse = ',\n\t\t') 114 | 115 | if(class(color) != 'character'){ 116 | stop("Color should be a character object!") 117 | } 118 | 119 | if(length(color) == 1){ 120 | color = c(color,'white') 121 | } 122 | 123 | ColorData = paste0("['",paste(color,collapse = "', '"),"']") 124 | 125 | 126 | if(is.na(maxdata)){ 127 | maxData = round(max(data[,2]) + 128 | (max(data[,2])- min(data[,2]))/15) 129 | }else{ 130 | maxData = maxdata 131 | } 132 | 133 | if(is.na(mindata)){ 134 | minData = round(min(data[,2]) - 135 | (max(data[,2])- min(data[,2]))/15) 136 | }else{ 137 | minData = mindata 138 | } 139 | 140 | markLineLogi = (length(dim(markLineData)) ==2) 141 | markPointLogi = class(markPointData)!='logical' 142 | geoDataLogi = class(geoData)!='logical' 143 | 144 | 145 | if(markLineLogi & markPointLogi & !geoDataLogi){ 146 | cityNames = c(as.character(markLineData[,1]), 147 | as.character(markLineData[,2])) 148 | if(is.data.frame(markPointData)){ 149 | cityNames = c(cityNames, 150 | as.character(markPointData[,1])) 151 | }else{ 152 | # it's a vector 153 | cityNames = c(cityNames, 154 | as.character(markPointData)) 155 | } 156 | 157 | geoData = get_geo_position(unique(cityNames)) 158 | } 159 | 160 | 161 | 162 | ## Prepare for mark Line data 163 | if(is.null(markLineData)){ 164 | markLineData = "" 165 | }else{ 166 | markLineData = markLineStr(markLineData, 167 | markLineTheme, 168 | geoData) 169 | } 170 | 171 | ## Prepare for mark point data 172 | if(is.null(markPointData)){ 173 | markPointData = "" 174 | }else{ 175 | markPointData = markPointStr(markPointData, 176 | markPointTheme, 177 | geoData) 178 | } 179 | 180 | 181 | if(maptype == 'world'){ 182 | theme$labelShow = 'false' 183 | } 184 | ### write remap object 185 | output = new("remap") 186 | output@id = paste('ID', format(Sys.time(), "%Y%m%d%H%M%S"), 187 | round(proc.time()[3]*100), sep="_") 188 | output@theme = theme 189 | output@maptype = "SVG" 190 | 191 | output@option = html.data.C$option 192 | head = html.data.C$head 193 | foot = html.data.C$foot 194 | 195 | if(.Platform$OS.type == "windows"){ 196 | Sys.setlocale("LC_CTYPE", 197 | "chs") 198 | } 199 | 200 | output@option = sub("forChange", 201 | "一",output@option) 202 | 203 | ##V0.2: label&point 204 | output@option = sub("labelShowData", 205 | theme$labelShow,output@option) 206 | output@option = sub("pointShowData", 207 | theme$pointShow,output@option) 208 | output@option = sub("pointColorData", 209 | theme$pointColor,output@option) 210 | 211 | ## end V0.2 212 | output@option = gsub("backgroundColorData", 213 | theme$backgroundColor,output@option) 214 | output@option = sub("titleData",title,output@option) 215 | output@option = sub("subtitleData",subtitle,output@option) 216 | output@option = gsub("titleColorData", 217 | theme$titleColor,output@option) 218 | 219 | output@option = sub("minData",minData,output@option) 220 | output@option = sub("maxData",maxData,output@option) 221 | output@option = sub("colorData",ColorData,output@option) 222 | output@option = sub("mapTypeData",maptype,output@option) 223 | output@option = sub("borderColorData", 224 | theme$borderColor,output@option) 225 | 226 | output@option = sub("mapCData",mapCData,output@option) 227 | 228 | 229 | output@option = sub("//markLineData", 230 | markLineData,output@option) 231 | output@option = sub("//markPointData", 232 | markPointData,output@option) 233 | ## optionNameData 234 | outputHead= sub("optionNameData", 235 | paste0("option", output@id),head) 236 | outputFoot = sub("optionNameData", 237 | paste0("option", output@id),foot) 238 | 239 | output@option = strsplit(output@option,"kkkmmm")[[1]][2] 240 | output@content = paste(outputHead,output@option,outputFoot,sep = "\n") 241 | 242 | if(.Platform$OS.type == "windows"){ 243 | Sys.setlocale("LC_CTYPE",locate) 244 | } 245 | return(output) 246 | 247 | 248 | 249 | } 250 | 251 | 252 | 253 | 254 | html.data.C = list( 255 | head = " 256 | 257 | 258 | 266 | 267 | 268 |
269 | 270 | 271 | 347 | 348 | " 349 | ) 350 | 351 | checkMapName = function(maptype){ 352 | maptype = tolower(maptype) 353 | logi = maptype == mapCList[[37]] 354 | return(names(mapCList)[which(logi)[1]%%37]) 355 | } 356 | -------------------------------------------------------------------------------- /inst/JS/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * echarts 百度地图扩展,必须在echarts初始化前使用 3 | * 4 | * @desc echarts基于Canvas,纯Javascript图表库,提供直观,生动,可交互,可个性化定制的数据统计图表。 5 | * @author Neil (杨骥, 511415343@qq.com) 6 | */ 7 | define(function (require) { 8 | 9 | /** 10 | * 构造函数 11 | * 12 | * @param {String|HTMLElement|BMap.Map} obj 13 | * @param {BMap} BMap 14 | * @param {echarts} ec 15 | * @parma {Object=} mapOption 百度地图初始化选项 16 | * @constructor 17 | */ 18 | function BMapExt(obj, BMap, ec, mapOption) { 19 | this._init(obj, BMap, ec, mapOption); 20 | }; 21 | 22 | /** 23 | * echarts 容器元素 24 | * 25 | * @type {HTMLElement} 26 | * @private 27 | */ 28 | BMapExt.prototype._echartsContainer = null; 29 | 30 | /** 31 | * 百度地图实例 32 | * 33 | * @type {BMap.Map} 34 | * @private 35 | */ 36 | BMapExt.prototype._map = null; 37 | 38 | /** 39 | * 使用的echarts实例 40 | * 41 | * @type {ECharts} 42 | * @private 43 | */ 44 | BMapExt.prototype._ec = null; 45 | 46 | /** 47 | * geoCoord 48 | * 49 | * @type {Object} 50 | * @private 51 | */ 52 | BMapExt.prototype._geoCoord = []; 53 | 54 | /** 55 | * 记录地图的便宜量 56 | * 57 | * @type {Array.} 58 | * @private 59 | */ 60 | BMapExt.prototype._mapOffset = [0, 0]; 61 | 62 | 63 | /** 64 | * 初始化方法 65 | * 66 | * @param {String|HTMLElement|BMap.Map} obj 67 | * @param {BMap} BMap 68 | * @param {echarts} ec 69 | * @private 70 | */ 71 | BMapExt.prototype._init = function (obj, BMap, ec, mapOption) { 72 | var self = this; 73 | self._map = obj.constructor == BMap.Map ? obj : new BMap.Map(obj, mapOption); 74 | 75 | /** 76 | * Overlay类,用来生成覆盖物 77 | * 78 | * @constructor 79 | * @extends BMap.Overlay 80 | */ 81 | function Overlay() {} 82 | 83 | Overlay.prototype = new BMap.Overlay(); 84 | 85 | /** 86 | * 初始化 87 | * 88 | * @param {BMap.Map} map 89 | * @override 90 | */ 91 | Overlay.prototype.initialize = function (map) { 92 | var size = map.getSize(); 93 | var div = self._echartsContainer = document.createElement('div'); 94 | div.style.position = 'absolute'; 95 | div.style.height = size.height + 'px'; 96 | div.style.width = size.width + 'px'; 97 | div.style.top = 0; 98 | div.style.left = 0; 99 | map.getPanes().labelPane.appendChild(div); 100 | return div; 101 | }; 102 | 103 | /** 104 | * @override 105 | */ 106 | Overlay.prototype.draw = function () {}; 107 | 108 | var myOverlay = new Overlay(); 109 | 110 | /** 111 | * 获取echarts容器 112 | * 113 | * @return {HTMLElement} 114 | * @public 115 | */ 116 | self.getEchartsContainer = function () { 117 | return self._echartsContainer; 118 | }; 119 | 120 | /** 121 | * 获取map实例 122 | * 123 | * @return {BMap.Map} 124 | * @public 125 | */ 126 | self.getMap = function () { 127 | return self._map; 128 | } 129 | 130 | /** 131 | * 自定义拖拽事件 132 | */ 133 | self.onmoving = null; 134 | self.onmoveend = null; 135 | 136 | /** 137 | * 自定义缩放事件 138 | */ 139 | self.onzoom = null; 140 | 141 | /** 142 | * 经纬度转换为屏幕像素 143 | * 144 | * @param {Array.} geoCoord 经纬度 145 | * @return {Array.} 146 | * @public 147 | */ 148 | self.geoCoord2Pixel = function (geoCoord) { 149 | var point = new BMap.Point(geoCoord[0], geoCoord[1]); 150 | var pos = self._map.pointToOverlayPixel(point); 151 | return [pos.x, pos.y]; 152 | }; 153 | 154 | /** 155 | * 屏幕像素转换为经纬度 156 | * 157 | * @param {Array.} pixel 像素坐标 158 | * @return {Array.} 159 | * @public 160 | */ 161 | self.pixel2GeoCoord = function (pixel) { 162 | var point = self._map.overlayPixelToPoint({ 163 | x: pixel[0], 164 | y: pixel[1] 165 | }); 166 | return [point.lng, point.lat]; 167 | }; 168 | 169 | /** 170 | * 初始化echarts实例 171 | * 172 | * @return {ECharts} 173 | * @public 174 | */ 175 | self.initECharts = function () { 176 | self._ec = ec.init.apply(self, arguments); 177 | self._bindEvent(); 178 | self._addMarkWrap(); 179 | return self._ec; 180 | }; 181 | 182 | // addMark wrap for get position from baidu map by geo location 183 | // by kener at 2015.01.08 184 | self._addMarkWrap = function () { 185 | function _addMark (seriesIdx, markData, markType) { 186 | var data; 187 | if (markType == 'markPoint') { 188 | var data = markData.data; 189 | if (data && data.length) { 190 | for (var k = 0, len = data.length; k < len; k++) { 191 | self._AddPos(data[k]); 192 | } 193 | } 194 | } 195 | else { 196 | data = markData.data; 197 | if (data && data.length) { 198 | for (var k = 0, len = data.length; k < len; k++) { 199 | self._AddPos(data[k][0]); 200 | self._AddPos(data[k][1]); 201 | } 202 | } 203 | } 204 | self._ec._addMarkOri(seriesIdx, markData, markType); 205 | } 206 | self._ec._addMarkOri = self._ec._addMark; 207 | self._ec._addMark = _addMark; 208 | }; 209 | 210 | /** 211 | * 获取ECharts实例 212 | * 213 | * @return {ECharts} 214 | * @public 215 | */ 216 | self.getECharts = function () { 217 | return self._ec; 218 | }; 219 | 220 | /** 221 | * 获取地图的偏移量 222 | * 223 | * @return {Array.} 224 | * @public 225 | */ 226 | self.getMapOffset = function () { 227 | return self._mapOffset; 228 | }; 229 | 230 | /** 231 | * 对echarts的setOption加一次处理 232 | * 用来为markPoint、markLine中添加x、y坐标,需要name与geoCoord对应 233 | * 234 | * @param {Object} 235 | * @public 236 | */ 237 | self.setOption = function (option, notMerge) { 238 | var series = option.series || {}; 239 | 240 | // 记录所有的geoCoord 241 | for (var i = 0, item; item = series[i++];) { 242 | var geoCoord = item.geoCoord; 243 | if (geoCoord) { 244 | for (var k in geoCoord) { 245 | self._geoCoord[k] = geoCoord[k]; 246 | } 247 | } 248 | } 249 | 250 | // 添加x、y 251 | for (var i = 0, item; item = series[i++];) { 252 | var markPoint = item.markPoint || {}; 253 | var markLine = item.markLine || {}; 254 | 255 | var data = markPoint.data; 256 | if (data && data.length) { 257 | for (var k = 0, len = data.length; k < len; k++) { 258 | self._AddPos(data[k]); 259 | } 260 | } 261 | 262 | data = markLine.data; 263 | if (data && data.length) { 264 | for (var k = 0, len = data.length; k < len; k++) { 265 | self._AddPos(data[k][0]); 266 | self._AddPos(data[k][1]); 267 | } 268 | } 269 | } 270 | 271 | self._ec.setOption(option, notMerge); 272 | } 273 | 274 | /** 275 | * 增加x、y坐标 276 | * 277 | * @param {Object} obj markPoint、markLine data中的项,必须有name 278 | * @param {Object} geoCoord 279 | */ 280 | self._AddPos = function (obj) { 281 | var coord = this._geoCoord[obj.name] 282 | var pos = this.geoCoord2Pixel(coord); 283 | obj.x = pos[0] - self._mapOffset[0]; 284 | obj.y = pos[1] - self._mapOffset[1]; 285 | }; 286 | 287 | /** 288 | * 绑定地图事件的处理方法 289 | * 290 | * @private 291 | */ 292 | self._bindEvent = function () { 293 | self._map.addEventListener('zoomend', _zoomChangeHandler); 294 | 295 | self._map.addEventListener('moving', _moveHandler('moving')); 296 | self._map.addEventListener('moveend', _moveHandler('moveend')); 297 | 298 | self._ec.getZrender().on('dragstart', _dragZrenderHandler(true)); 299 | self._ec.getZrender().on('dragend', _dragZrenderHandler(false)); 300 | } 301 | 302 | /** 303 | * 地图缩放触发事件 304 | * 305 | * @private 306 | */ 307 | function _zoomChangeHandler() { 308 | _fireEvent('zoom'); 309 | } 310 | 311 | /** 312 | * 地图移动、如拖拽触发事件 313 | * 314 | * @param {string} type moving | moveend 移动中|移动结束 315 | * @return {Function} 316 | * @private 317 | */ 318 | function _moveHandler(type) { 319 | return function () { 320 | // 记录便宜量 321 | var offsetEle = 322 | self._echartsContainer.parentNode.parentNode.parentNode; 323 | self._mapOffset = [ 324 | - parseInt(offsetEle.style.left) || 0, 325 | - parseInt(offsetEle.style.top) || 0 326 | ]; 327 | self._echartsContainer.style.left = self._mapOffset[0] + 'px'; 328 | self._echartsContainer.style.top = self._mapOffset[1] + 'px'; 329 | 330 | _fireEvent(type); 331 | } 332 | } 333 | 334 | /** 335 | * Zrender拖拽触发事件 336 | * 337 | * @param {boolean} isStart 338 | * @return {Function} 339 | * @private 340 | */ 341 | function _dragZrenderHandler(isStart) { 342 | return function () { 343 | var func = isStart ? 'disableDragging' : 'enableDragging'; 344 | self._map[func](); 345 | } 346 | } 347 | 348 | /** 349 | * 触发事件 350 | * 351 | * @param {stirng} type 事件类型 352 | * @private 353 | */ 354 | function _fireEvent(type) { 355 | var func = self['on' + type]; 356 | if (func) { 357 | func(); 358 | } else { 359 | self.refresh(); 360 | } 361 | } 362 | 363 | /** 364 | * 刷新页面 365 | * 366 | * @public 367 | */ 368 | self.refresh = function () { 369 | if (self._ec) { 370 | var option = self._ec.getOption(); 371 | var component = self._ec.component || {}; 372 | var legend = component.legend; 373 | var dataRange = component.dataRange; 374 | 375 | if (legend) { 376 | option.legend.selected = legend.getSelectedMap(); 377 | } 378 | 379 | if (dataRange) { 380 | option.dataRange.range = dataRange._range; 381 | } 382 | self._ec.clear(); 383 | self.setOption(option); 384 | } 385 | }; 386 | 387 | self._map.addOverlay(myOverlay); 388 | }; 389 | 390 | return BMapExt; 391 | }); -------------------------------------------------------------------------------- /inst/JS/chart/heatmap.js: -------------------------------------------------------------------------------- 1 | define('echarts/chart/heatmap', [ 2 | 'require', 3 | './base', 4 | '../layer/heatmap', 5 | '../config', 6 | '../util/ecData', 7 | 'zrender/tool/util', 8 | 'zrender/tool/color', 9 | 'zrender/shape/Image', 10 | '../chart' 11 | ], function (require) { 12 | var ChartBase = require('./base'); 13 | var HeatmapLayer = require('../layer/heatmap'); 14 | var ecConfig = require('../config'); 15 | var ecData = require('../util/ecData'); 16 | var zrUtil = require('zrender/tool/util'); 17 | var zrColor = require('zrender/tool/color'); 18 | var zrImage = require('zrender/shape/Image'); 19 | ecConfig.heatmap = { 20 | zlevel: 0, 21 | z: 2, 22 | clickable: true 23 | }; 24 | function Heatmap(ecTheme, messageCenter, zr, option, myChart) { 25 | ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart); 26 | this.refresh(option); 27 | } 28 | Heatmap.prototype = { 29 | type: ecConfig.CHART_TYPE_HEATMAP, 30 | refresh: function (newOption) { 31 | this.clear(); 32 | if (newOption) { 33 | this.option = newOption; 34 | this.series = newOption.series; 35 | } 36 | this._init(); 37 | }, 38 | _init: function () { 39 | var series = this.series; 40 | this.backupShapeList(); 41 | var len = series.length; 42 | for (var i = 0; i < len; ++i) { 43 | if (series[i].type === ecConfig.CHART_TYPE_HEATMAP) { 44 | series[i] = this.reformOption(series[i]); 45 | var layer = new HeatmapLayer(series[i]); 46 | var canvas = layer.getCanvas(series[i].data, this.zr.getWidth(), this.zr.getHeight()); 47 | var image = new zrImage({ 48 | position: [ 49 | 0, 50 | 0 51 | ], 52 | scale: [ 53 | 1, 54 | 1 55 | ], 56 | hoverable: this.option.hoverable, 57 | style: { 58 | x: 0, 59 | y: 0, 60 | image: canvas, 61 | width: canvas.width, 62 | height: canvas.height 63 | } 64 | }); 65 | this.shapeList.push(image); 66 | } 67 | } 68 | this.addShapeList(); 69 | } 70 | }; 71 | zrUtil.inherits(Heatmap, ChartBase); 72 | require('../chart').define('heatmap', Heatmap); 73 | return Heatmap; 74 | });define('echarts/layer/heatmap', ['require'], function (require) { 75 | var defaultOptions = { 76 | blurSize: 30, 77 | gradientColors: [ 78 | 'blue', 79 | 'cyan', 80 | 'lime', 81 | 'yellow', 82 | 'red' 83 | ], 84 | minAlpha: 0.05, 85 | valueScale: 1, 86 | opacity: 1 87 | }; 88 | var BRUSH_SIZE = 20; 89 | var GRADIENT_LEVELS = 256; 90 | function Heatmap(opt) { 91 | this.option = opt; 92 | if (opt) { 93 | for (var i in defaultOptions) { 94 | if (opt[i] !== undefined) { 95 | this.option[i] = opt[i]; 96 | } else { 97 | this.option[i] = defaultOptions[i]; 98 | } 99 | } 100 | } else { 101 | this.option = defaultOptions; 102 | } 103 | } 104 | Heatmap.prototype = { 105 | getCanvas: function (data, width, height) { 106 | var brush = this._getBrush(); 107 | var gradient = this._getGradient(); 108 | var r = BRUSH_SIZE + this.option.blurSize; 109 | var canvas = document.createElement('canvas'); 110 | canvas.width = width; 111 | canvas.height = height; 112 | var ctx = canvas.getContext('2d'); 113 | var len = data.length; 114 | for (var i = 0; i < len; ++i) { 115 | var p = data[i]; 116 | var x = p[0]; 117 | var y = p[1]; 118 | var value = p[2]; 119 | var alpha = Math.min(1, Math.max(value * this.option.valueScale || this.option.minAlpha, this.option.minAlpha)); 120 | ctx.globalAlpha = alpha; 121 | ctx.drawImage(brush, x - r, y - r); 122 | } 123 | var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); 124 | var pixels = imageData.data; 125 | var len = pixels.length / 4; 126 | while (len--) { 127 | var id = len * 4 + 3; 128 | var alpha = pixels[id] / 256; 129 | var colorOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)); 130 | pixels[id - 3] = gradient[colorOffset * 4]; 131 | pixels[id - 2] = gradient[colorOffset * 4 + 1]; 132 | pixels[id - 1] = gradient[colorOffset * 4 + 2]; 133 | pixels[id] *= this.option.opacity; 134 | } 135 | ctx.putImageData(imageData, 0, 0); 136 | return canvas; 137 | }, 138 | _getBrush: function () { 139 | if (!this._brushCanvas) { 140 | this._brushCanvas = document.createElement('canvas'); 141 | var r = BRUSH_SIZE + this.option.blurSize; 142 | var d = r * 2; 143 | this._brushCanvas.width = d; 144 | this._brushCanvas.height = d; 145 | var ctx = this._brushCanvas.getContext('2d'); 146 | ctx.shadowOffsetX = d; 147 | ctx.shadowBlur = this.option.blurSize; 148 | ctx.shadowColor = 'black'; 149 | ctx.beginPath(); 150 | ctx.arc(-r, r, BRUSH_SIZE, 0, Math.PI * 2, true); 151 | ctx.closePath(); 152 | ctx.fill(); 153 | } 154 | return this._brushCanvas; 155 | }, 156 | _getGradient: function () { 157 | if (!this._gradientPixels) { 158 | var levels = GRADIENT_LEVELS; 159 | var canvas = document.createElement('canvas'); 160 | canvas.width = 1; 161 | canvas.height = levels; 162 | var ctx = canvas.getContext('2d'); 163 | var gradient = ctx.createLinearGradient(0, 0, 0, levels); 164 | var len = this.option.gradientColors.length; 165 | for (var i = 0; i < len; ++i) { 166 | if (typeof this.option.gradientColors[i] === 'string') { 167 | gradient.addColorStop((i + 1) / len, this.option.gradientColors[i]); 168 | } else { 169 | gradient.addColorStop(this.option.gradientColors[i].offset, this.option.gradientColors[i].color); 170 | } 171 | } 172 | ctx.fillStyle = gradient; 173 | ctx.fillRect(0, 0, 1, levels); 174 | this._gradientPixels = ctx.getImageData(0, 0, 1, levels).data; 175 | } 176 | return this._gradientPixels; 177 | } 178 | }; 179 | return Heatmap; 180 | });define('echarts/layer/heatmap', ['require'], function (require) { 181 | var defaultOptions = { 182 | blurSize: 30, 183 | gradientColors: [ 184 | 'blue', 185 | 'cyan', 186 | 'lime', 187 | 'yellow', 188 | 'red' 189 | ], 190 | minAlpha: 0.05, 191 | valueScale: 1, 192 | opacity: 1 193 | }; 194 | var BRUSH_SIZE = 20; 195 | var GRADIENT_LEVELS = 256; 196 | function Heatmap(opt) { 197 | this.option = opt; 198 | if (opt) { 199 | for (var i in defaultOptions) { 200 | if (opt[i] !== undefined) { 201 | this.option[i] = opt[i]; 202 | } else { 203 | this.option[i] = defaultOptions[i]; 204 | } 205 | } 206 | } else { 207 | this.option = defaultOptions; 208 | } 209 | } 210 | Heatmap.prototype = { 211 | getCanvas: function (data, width, height) { 212 | var brush = this._getBrush(); 213 | var gradient = this._getGradient(); 214 | var r = BRUSH_SIZE + this.option.blurSize; 215 | var canvas = document.createElement('canvas'); 216 | canvas.width = width; 217 | canvas.height = height; 218 | var ctx = canvas.getContext('2d'); 219 | var len = data.length; 220 | for (var i = 0; i < len; ++i) { 221 | var p = data[i]; 222 | var x = p[0]; 223 | var y = p[1]; 224 | var value = p[2]; 225 | var alpha = Math.min(1, Math.max(value * this.option.valueScale || this.option.minAlpha, this.option.minAlpha)); 226 | ctx.globalAlpha = alpha; 227 | ctx.drawImage(brush, x - r, y - r); 228 | } 229 | var imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); 230 | var pixels = imageData.data; 231 | var len = pixels.length / 4; 232 | while (len--) { 233 | var id = len * 4 + 3; 234 | var alpha = pixels[id] / 256; 235 | var colorOffset = Math.floor(alpha * (GRADIENT_LEVELS - 1)); 236 | pixels[id - 3] = gradient[colorOffset * 4]; 237 | pixels[id - 2] = gradient[colorOffset * 4 + 1]; 238 | pixels[id - 1] = gradient[colorOffset * 4 + 2]; 239 | pixels[id] *= this.option.opacity; 240 | } 241 | ctx.putImageData(imageData, 0, 0); 242 | return canvas; 243 | }, 244 | _getBrush: function () { 245 | if (!this._brushCanvas) { 246 | this._brushCanvas = document.createElement('canvas'); 247 | var r = BRUSH_SIZE + this.option.blurSize; 248 | var d = r * 2; 249 | this._brushCanvas.width = d; 250 | this._brushCanvas.height = d; 251 | var ctx = this._brushCanvas.getContext('2d'); 252 | ctx.shadowOffsetX = d; 253 | ctx.shadowBlur = this.option.blurSize; 254 | ctx.shadowColor = 'black'; 255 | ctx.beginPath(); 256 | ctx.arc(-r, r, BRUSH_SIZE, 0, Math.PI * 2, true); 257 | ctx.closePath(); 258 | ctx.fill(); 259 | } 260 | return this._brushCanvas; 261 | }, 262 | _getGradient: function () { 263 | if (!this._gradientPixels) { 264 | var levels = GRADIENT_LEVELS; 265 | var canvas = document.createElement('canvas'); 266 | canvas.width = 1; 267 | canvas.height = levels; 268 | var ctx = canvas.getContext('2d'); 269 | var gradient = ctx.createLinearGradient(0, 0, 0, levels); 270 | var len = this.option.gradientColors.length; 271 | for (var i = 0; i < len; ++i) { 272 | if (typeof this.option.gradientColors[i] === 'string') { 273 | gradient.addColorStop((i + 1) / len, this.option.gradientColors[i]); 274 | } else { 275 | gradient.addColorStop(this.option.gradientColors[i].offset, this.option.gradientColors[i].color); 276 | } 277 | } 278 | ctx.fillStyle = gradient; 279 | ctx.fillRect(0, 0, 1, levels); 280 | this._gradientPixels = ctx.getImageData(0, 0, 1, levels).data; 281 | } 282 | return this._gradientPixels; 283 | } 284 | }; 285 | return Heatmap; 286 | }); -------------------------------------------------------------------------------- /R/remapH.R: -------------------------------------------------------------------------------- 1 | ##' Create a heat map 2 | ##' 3 | ##' remapH uses a data frame create a heat remap object 4 | ##' which can be used by plot to see the map by browser 5 | ##' 6 | ##' data should be a dataframe which including three columns, 7 | ##' the first column is lontitude, second column is latitude, 8 | ##' third column is the density. 9 | ##' 10 | ##' @usage 11 | ##' remapH(data, 12 | ##' maptype = 'china', 13 | ##' theme = get_theme("Dark"), 14 | ##' blurSize = 30, 15 | ##' color = c('blue', 'cyan', 'lime', 'yellow', 'red'), 16 | ##' minAlpha = 0.05, 17 | ##' opacity = 1, 18 | ##' ...) 19 | ##' 20 | ##' 21 | ##' 22 | ##' @param data a data frame including lontitude, latitude and density 23 | ##' @param maptype the type of the map. For exameple,'china', 24 | ##' 'world' or other names of province in China. 25 | ##' @param theme a list object created by get_theme,control 26 | ##' the color of the map. 27 | ##' @param blurSize blur size of the data point, default is 30. 28 | ##' @param color a vector of strings like 29 | ##' ['blue', 'cyan', 'lime', 'yellow', 'red'], 30 | ##' with which the color will transform evenly. 31 | ##' @param minAlpha If the unified value is less than minAlpha, 32 | ##' remapH will be set to minAlpha to ensure 33 | ##' small data value can also be visible on the chart. 34 | ##' @param opacity Opacity of the heatmap. Default is 1 35 | ##' @param ... other paramters like title, subtitle,data for mark line 36 | ##' @return An remap object of heat map 37 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 38 | ##' @examples 39 | ##' heatmap = sampleData() 40 | ##' ## This is a function to create sample data as 41 | ##' ## http://echarts.baidu.com/doc/example/heatmap_map.html 42 | ##' 43 | ##' remapH(heatmap,minAlpha = 0.1,title = "Heat Map from REmap") 44 | 45 | 46 | remapH = function(data, 47 | maptype = 'china', 48 | # color = c('#1e90ff','#f0ffff'), 49 | theme = get_theme("Dark"), 50 | blurSize = 30, 51 | color = c('blue', 'cyan', 'lime', 'yellow', 'red'), 52 | minAlpha = 0.05, 53 | opacity = 1, 54 | title = "", 55 | subtitle = "", 56 | markLineData = NULL, 57 | markPointData = NULL, 58 | markLineTheme = markLineControl(), 59 | markPointTheme = markPointControl(), 60 | geoData = NA 61 | # mindata = NA, 62 | # maxdata = NA 63 | ){ 64 | 65 | if(.Platform$OS.type == "windows"){ 66 | locate = Sys.getlocale("LC_CTYPE") 67 | Sys.setlocale("LC_CTYPE","eng") 68 | } 69 | 70 | if(!is.data.frame(data)){ 71 | stop("Map data should be a data frame.") 72 | } 73 | 74 | data = na.omit(data) 75 | 76 | if(ncol(data)<3 | nrow(data) == 0 ){ 77 | stop("Data should have at least 3 columns and 1 row") 78 | } 79 | 80 | 81 | if(!is.numeric(data[1,1]) | 82 | !is.numeric(data[1,2]) | 83 | !is.numeric(data[1,3])){ 84 | data[,1] = as.numeric(data[,1]) 85 | data[,2] = as.numeric(data[,2]) 86 | data[,3] = as.numeric(data[,3]) 87 | } 88 | 89 | 90 | heatdata = apply(data,1,function(x){ 91 | out = sprintf('[%s,%s,%s]',x[1],x[2],x[3]) 92 | return(out) 93 | }) 94 | 95 | heatdata = paste(heatdata,collapse = ",\n") 96 | 97 | # mapnames = mapNames(mapType = maptype) 98 | # hit = sum(sapply(data[,1],function(x) 99 | # sum(x %in% mapnames)))/length(mapnames) 100 | # 101 | # if(hit<0.5){ 102 | # warning(paste0("Over 50% places(column 1) are not found in ",maptype)) 103 | # } 104 | 105 | 106 | # mapCVec = apply(data,1,function(x) 107 | # paste0("{name:'",x[1], 108 | # "',value:",x[2],"}" )) 109 | # mapCData = paste(mapCVec,collapse = ',\n\t\t') 110 | 111 | if(class(color) != 'character'){ 112 | stop("Color should be a character object!") 113 | } 114 | 115 | if(length(color) == 1){ 116 | color = c(color,'white') 117 | } 118 | 119 | ColorData = paste0("['",paste(color,collapse = "', '"),"']") 120 | 121 | 122 | # if(is.na(maxdata)){ 123 | # maxData = round(max(data[,2]) + 124 | # (max(data[,2])- min(data[,2]))/15) 125 | # }else{ 126 | # maxData = maxdata 127 | # } 128 | # 129 | # if(is.na(mindata)){ 130 | # minData = round(min(data[,2]) - 131 | # (max(data[,2])- min(data[,2]))/15) 132 | # }else{ 133 | # minData = mindata 134 | # } 135 | heatMapStrData = heatMapStr(blurSize = blurSize, 136 | colors = ColorData, 137 | minAlpha = minAlpha, 138 | opacity = opacity) 139 | 140 | markLineLogi = (length(dim(markLineData)) ==2) 141 | markPointLogi = class(markPointData)!='logical' 142 | geoDataLogi = class(geoData)!='logical' 143 | 144 | 145 | if(markLineLogi & markPointLogi & !geoDataLogi){ 146 | cityNames = c(as.character(markLineData[,1]), 147 | as.character(markLineData[,1])) 148 | if(is.data.frame(markPointData)){ 149 | cityNames = c(cityNames, 150 | as.character(markPointData[,1])) 151 | }else{ 152 | # it's a vector 153 | cityNames = c(cityNames,markPointData) 154 | } 155 | 156 | geoData = get_geo_position(unique(cityNames)) 157 | } 158 | 159 | 160 | 161 | ## Prepare for mark Line data 162 | if(is.null(markLineData)){ 163 | markLineData = "" 164 | }else{ 165 | markLineData = markLineStr(markLineData, 166 | markLineTheme, 167 | geoData) 168 | } 169 | 170 | ## Prepare for mark point data 171 | if(is.null(markPointData)){ 172 | markPointData = "" 173 | }else{ 174 | markPointData = markPointStr(markPointData, 175 | markPointTheme, 176 | geoData) 177 | } 178 | 179 | 180 | if(maptype == 'world'){ 181 | theme$labelShow = 'false' 182 | } 183 | ### write remap object 184 | output = new("remap") 185 | output@id = paste('ID', format(Sys.time(), "%Y%m%d%H%M%S"), 186 | round(proc.time()[3]*100), sep="_") 187 | output@theme = theme 188 | output@maptype = "SVGH" 189 | 190 | output@option = html.data.H$option 191 | head = html.data.H$head 192 | foot = html.data.H$foot 193 | 194 | if(.Platform$OS.type == "windows"){ 195 | Sys.setlocale("LC_CTYPE", 196 | "chs") 197 | } 198 | 199 | output@option = sub("forChange", 200 | "一",output@option) 201 | 202 | 203 | 204 | output@option = sub("heatMapData", 205 | heatdata,output@option) 206 | 207 | ##V0.2: label&point 208 | output@option = sub("labelShowData", 209 | theme$labelShow,output@option) 210 | output@option = sub("pointShowData", 211 | theme$pointShow,output@option) 212 | output@option = sub("pointColorData", 213 | theme$pointColor,output@option) 214 | 215 | ## end V0.2 216 | output@option = sub("backgroundColorData", 217 | theme$backgroundColor,output@option) 218 | output@option = sub("titleData",title,output@option) 219 | output@option = sub("subtitleData",subtitle,output@option) 220 | output@option = gsub("titleColorData", 221 | theme$titleColor,output@option) 222 | 223 | # output@option = sub("minData",minData,output@option) 224 | # output@option = sub("maxData",maxData,output@option) 225 | # output@option = sub("colorData",ColorData,output@option) 226 | output@option = sub("mapTypeData",maptype,output@option) 227 | output@option = sub("borderColorData", 228 | theme$borderColor,output@option) 229 | 230 | # output@option = sub("mapCData",mapCData,output@option) 231 | 232 | 233 | output@option = sub("//markLineData", 234 | markLineData,output@option) 235 | output@option = sub("//markPointData", 236 | markPointData,output@option) 237 | output@option = sub("//heatMapStrData", 238 | heatMapStrData,output@option) 239 | 240 | ## optionNameData 241 | output@option= sub("optionNameData", 242 | paste0("option", output@id),output@option) 243 | outputFoot = sub("optionNameData", 244 | paste0("option", output@id),foot) 245 | 246 | output@option = strsplit(output@option,"kkkmmm")[[1]][2] 247 | output@content = paste(head,output@option,outputFoot,sep = "\n") 248 | 249 | if(.Platform$OS.type == "windows"){ 250 | Sys.setlocale("LC_CTYPE",locate) 251 | } 252 | return(output) 253 | 254 | 255 | 256 | } 257 | 258 | 259 | 260 | 261 | html.data.H = list( 262 | head = " 263 | 264 | 265 | 273 | 274 | 275 |
276 | 277 | 278 | 360 | 361 | " 362 | ) 363 | 364 | 365 | 366 | 367 | 368 | heatMapStr = function(blurSize , 369 | colors , 370 | minAlpha , 371 | opacity 372 | ){ 373 | 374 | out = sprintf(",heatmap: { 375 | blurSize:%s , 376 | colors:%s , 377 | minAlpha:%s , 378 | opacity:%s , 379 | data: heatData}", 380 | blurSize, 381 | colors, 382 | minAlpha, 383 | opacity) 384 | 385 | return(out) 386 | } 387 | 388 | 389 | 390 | 391 | sampleData = function(){ 392 | heatData = data.frame( 393 | lon = 100 + runif(200,max = 20), 394 | lat = 24 + runif(200,max = 16), 395 | prob = runif(200) 396 | ) 397 | 398 | 399 | 400 | 401 | for (j in 1:10) { 402 | x = 100 + runif(1) * 16 403 | y = 24 + runif(1) * 12 404 | cnt = 30 * runif(1) 405 | for (i in 1:cnt) { 406 | n = nrow(heatData) 407 | heatData[(n+1),] = c( 408 | x + runif(1) * 2, 409 | y + runif(1) * 2, 410 | runif(1) 411 | ) 412 | } 413 | } 414 | 415 | return(heatData) 416 | } 417 | -------------------------------------------------------------------------------- /R/remapB.R: -------------------------------------------------------------------------------- 1 | ##' Create a Bmap object 2 | ##' 3 | ##' remapB uses BaiduAPI instead of SVG object as the map object. 4 | ##' You can mark line or point on the remapB. 5 | ##' 6 | ##' 7 | ##' @usage 8 | ##' remapB(center = c(104.114129,37.550339), 9 | ##' zoom = 5, 10 | ##' color = "Bright", 11 | ##' title = "", 12 | ##' subtitle = "", 13 | ##' markLineData = NA, 14 | ##' markPointData = NA, 15 | ##' markLineTheme = markLineControl(), 16 | ##' markPointTheme = markPointControl(), 17 | ##' geoData = NA) 18 | ##' 19 | ##' @param center the center of the Bmap,a vector of (lon,lat), 20 | ##' you can get from get_city_coord, e.g.get_city_coord("beijing") 21 | ##' @param zoom the size of the Bmap, zoom:5 country data, 22 | ##' zoom:15 city data 23 | ##' @param color "Bright", "Blue", "light", "dark", "redalert", 24 | ##' "googlelite", "grassgreen", "midnight", "pink", "darkgreen", 25 | ##' "bluish", "grayscale", "hardedge" 26 | ##' @param title a character string of the title 27 | ##' @param subtitle a character string of the subtitle 28 | ##' @param markLineData data for mark line 29 | ##' @param markPointData data for mark point 30 | ##' @param markLineTheme theme for mark line 31 | ##' @param markLineTheme theme for mark point 32 | ##' @param geoData geoData for markLine and markPoint format is 33 | ##' similar as get_geo_position() 34 | ##' @return An remap object 35 | ##' @author Chiffon <\url{http://lchiffon.github.io}> 36 | ##' @examples 37 | ##' 38 | ##' geoData = get_geo_position(unique(demoC[demoC==demoC])) 39 | ##' # this may take some time,be patient~ 40 | ##' 41 | ##' remapB(markLineData = demoC,geoData = geoData) 42 | ##' 43 | ##' # Different themes 44 | ##' remapB(markLineData = demoC,color = "Blue",geoData = geoData) 45 | ##' remapB(markLineData = demoC,color = "light",geoData = geoData) 46 | ##' remapB(markLineData = demoC,color = "dark",geoData = geoData) 47 | ##' remapB(markLineData = demoC,color = "redalert",geoData = geoData) 48 | ##' remapB(markLineData = demoC,color = "googlelite",geoData = geoData) 49 | ##' remapB(markLineData = demoC,color = "grassgreen",geoData = geoData) 50 | ##' remapB(markLineData = demoC,color = "midnight",geoData = geoData) 51 | ##' remapB(markLineData = demoC,color = "pink",geoData = geoData) 52 | ##' remapB(markLineData = demoC,color = "darkgreen",geoData = geoData) 53 | ##' remapB(markLineData = demoC,color = "bluish",geoData = geoData) 54 | ##' remapB(markLineData = demoC,color = "grayscale",geoData = geoData) 55 | ##' remapB(markLineData = demoC,color = "hardedge",geoData = geoData) 56 | ##' 57 | ##' remapB(markLineData = demoC,markPointData = demoC[,2], 58 | ##' color = "Blue",geoData = geoData) 59 | 60 | 61 | 62 | 63 | remapB = function(center = c(104.114129,37.550339), 64 | zoom = 5, 65 | color = "Bright", 66 | title = "", 67 | subtitle = "", 68 | markLineData = NA, 69 | markPointData = NA, 70 | markLineTheme = markLineControl(), 71 | markPointTheme = markPointControl(), 72 | geoData = NA){ 73 | 74 | 75 | if(.Platform$OS.type == "windows"){ 76 | locate = Sys.getlocale("LC_CTYPE") 77 | Sys.setlocale("LC_CTYPE","eng") 78 | } 79 | 80 | 81 | markLineLogi = (length(dim(markLineData)) ==2) 82 | markPointLogi = class(markPointData)!='logical' 83 | geoDataLogi = class(geoData)!='logical' 84 | 85 | 86 | 87 | # if(!(markLineLogi | markPointLogi)){ 88 | # stop("You should have at least a dataframe, markLineData or markPointData ") 89 | # } 90 | # 91 | 92 | if(markLineLogi & markPointLogi & !geoDataLogi){ 93 | cityNames = c(as.character(markLineData[,1]), 94 | as.character(markLineData[,2])) 95 | if(is.data.frame(markPointData)){ 96 | cityNames = c(cityNames, 97 | as.character(markPointData[,1])) 98 | }else{ 99 | # it's a vector 100 | cityNames = c(cityNames, 101 | as.character(markPointData)) 102 | } 103 | 104 | geoData = get_geo_position(unique(cityNames)) 105 | } 106 | 107 | if(markLineLogi ==F){ 108 | markLineData = "" 109 | }else{ 110 | markLineData = markLineStr(markLineData, 111 | markLineTheme, 112 | geoData) 113 | } 114 | 115 | if(markPointLogi ==F){ 116 | markPointData = "" 117 | }else{ 118 | markPointData = markPointStr(markPointData, 119 | markPointTheme, 120 | geoData) 121 | } 122 | 123 | 124 | if(color == "Blue"){ 125 | mapStyleData = "map.setMapStyle({ 126 | styleJson: [ 127 | { 128 | 'featureType': 'water', 129 | 'elementType': 'all', 130 | 'stylers': { 131 | 'color': '#044161' 132 | } 133 | }, 134 | { 135 | 'featureType': 'land', 136 | 'elementType': 'all', 137 | 'stylers': { 138 | 'color': '#004981' 139 | } 140 | }, 141 | { 142 | 'featureType': 'boundary', 143 | 'elementType': 'geometry', 144 | 'stylers': { 145 | 'color': '#064f85' 146 | } 147 | }, 148 | { 149 | 'featureType': 'railway', 150 | 'elementType': 'all', 151 | 'stylers': { 152 | 'visibility': 'off' 153 | } 154 | }, 155 | { 156 | 'featureType': 'highway', 157 | 'elementType': 'geometry', 158 | 'stylers': { 159 | 'color': '#004981' 160 | } 161 | }, 162 | { 163 | 'featureType': 'highway', 164 | 'elementType': 'geometry.fill', 165 | 'stylers': { 166 | 'color': '#005b96', 167 | 'lightness': 1 168 | } 169 | }, 170 | { 171 | 'featureType': 'highway', 172 | 'elementType': 'labels', 173 | 'stylers': { 174 | 'visibility': 'off' 175 | } 176 | }, 177 | { 178 | 'featureType': 'arterial', 179 | 'elementType': 'geometry', 180 | 'stylers': { 181 | 'color': '#004981' 182 | } 183 | }, 184 | { 185 | 'featureType': 'arterial', 186 | 'elementType': 'geometry.fill', 187 | 'stylers': { 188 | 'color': '#00508b' 189 | } 190 | }, 191 | { 192 | 'featureType': 'poi', 193 | 'elementType': 'all', 194 | 'stylers': { 195 | 'visibility': 'off' 196 | } 197 | }, 198 | { 199 | 'featureType': 'green', 200 | 'elementType': 'all', 201 | 'stylers': { 202 | 'color': '#056197', 203 | 'visibility': 'off' 204 | } 205 | }, 206 | { 207 | 'featureType': 'subway', 208 | 'elementType': 'all', 209 | 'stylers': { 210 | 'visibility': 'off' 211 | } 212 | }, 213 | { 214 | 'featureType': 'manmade', 215 | 'elementType': 'all', 216 | 'stylers': { 217 | 'visibility': 'off' 218 | } 219 | }, 220 | { 221 | 'featureType': 'local', 222 | 'elementType': 'all', 223 | 'stylers': { 224 | 'visibility': 'off' 225 | } 226 | }, 227 | { 228 | 'featureType': 'arterial', 229 | 'elementType': 'labels', 230 | 'stylers': { 231 | 'visibility': 'off' 232 | } 233 | }, 234 | { 235 | 'featureType': 'boundary', 236 | 'elementType': 'geometry.fill', 237 | 'stylers': { 238 | 'color': '#029fd4' 239 | } 240 | }, 241 | { 242 | 'featureType': 'building', 243 | 'elementType': 'all', 244 | 'stylers': { 245 | 'color': '#1a5787' 246 | } 247 | }, 248 | { 249 | 'featureType': 'label', 250 | 'elementType': 'all', 251 | 'stylers': { 252 | 'visibility': 'off' 253 | } 254 | } 255 | ] 256 | });" 257 | titleColor = "#fff" 258 | }else{ 259 | mapStyleData = sprintf("map.setMapStyle({style:'%s'});",color) 260 | titleColor = "black" 261 | } 262 | 263 | output = new("remap") 264 | output@id = paste('ID', format(Sys.time(), "%Y%m%d%H%M%S"), 265 | round(proc.time()[3]*100), sep="_") 266 | output@theme = get_theme() 267 | output@maptype = "Bmap" 268 | 269 | 270 | 271 | output@option = html.data.B$option 272 | head = html.data.B$head 273 | foot = html.data.B$foot 274 | 275 | if(.Platform$OS.type == "windows"){ 276 | Sys.setlocale("LC_CTYPE", 277 | "chs") 278 | } 279 | 280 | 281 | output@option = sub("forChange", 282 | "一",output@option) 283 | 284 | ##longtitude and latitude 285 | output@option = sub("lonData", 286 | center[1],output@option) 287 | output@option = sub("latData", 288 | center[2],output@option) 289 | 290 | ## zoom 291 | output@option = gsub("zoomData", 292 | zoom,output@option) 293 | 294 | ## theme 295 | 296 | output@option = sub("//mapStyleData", 297 | mapStyleData,output@option) 298 | 299 | ## Title subtitle and color 300 | output@option = sub("titleData",title,output@option) 301 | output@option = sub("subtitleData",subtitle,output@option) 302 | output@option = gsub("titleColorData", 303 | titleColor,output@option) 304 | 305 | 306 | ## markline and mark point 307 | output@option = sub("//markLineData", 308 | markLineData,output@option) 309 | output@option = sub("//markPointData", 310 | markPointData,output@option) 311 | 312 | ## optionNameData 313 | output@option = sub("optionNameData", 314 | paste0("option", output@id),output@option) 315 | outputFoot = sub("optionNameData", 316 | paste0("option", output@id),foot) 317 | 318 | output@option = strsplit(output@option,"kkkmmm")[[1]][2] 319 | output@content = paste(head,output@option,outputFoot,sep = "\n") 320 | 321 | if(.Platform$OS.type == "windows"){ 322 | Sys.setlocale("LC_CTYPE",locate) 323 | } 324 | return(output) 325 | 326 | 327 | 328 | 329 | 330 | 331 | } 332 | 333 | 334 | 335 | 336 | html.data.B = list(head = " 337 | 338 | 339 | 347 | 348 | 349 |
350 | 351 | 352 | 353 | 445 | 446 | 447 | 448 | ") 449 | -------------------------------------------------------------------------------- /inst/JS/chart/k.js: -------------------------------------------------------------------------------- 1 | define('echarts/chart/k', [ 2 | 'require', 3 | './base', 4 | '../util/shape/Candle', 5 | '../component/axis', 6 | '../component/grid', 7 | '../component/dataZoom', 8 | '../config', 9 | '../util/ecData', 10 | 'zrender/tool/util', 11 | '../chart' 12 | ], function (require) { 13 | var ChartBase = require('./base'); 14 | var CandleShape = require('../util/shape/Candle'); 15 | require('../component/axis'); 16 | require('../component/grid'); 17 | require('../component/dataZoom'); 18 | var ecConfig = require('../config'); 19 | ecConfig.k = { 20 | zlevel: 0, 21 | z: 2, 22 | clickable: true, 23 | hoverable: true, 24 | legendHoverLink: false, 25 | xAxisIndex: 0, 26 | yAxisIndex: 0, 27 | itemStyle: { 28 | normal: { 29 | color: '#fff', 30 | color0: '#00aa11', 31 | lineStyle: { 32 | width: 1, 33 | color: '#ff3200', 34 | color0: '#00aa11' 35 | }, 36 | label: { show: false } 37 | }, 38 | emphasis: { label: { show: false } } 39 | } 40 | }; 41 | var ecData = require('../util/ecData'); 42 | var zrUtil = require('zrender/tool/util'); 43 | function K(ecTheme, messageCenter, zr, option, myChart) { 44 | ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart); 45 | this.refresh(option); 46 | } 47 | K.prototype = { 48 | type: ecConfig.CHART_TYPE_K, 49 | _buildShape: function () { 50 | var series = this.series; 51 | this.selectedMap = {}; 52 | var _position2sIndexMap = { 53 | top: [], 54 | bottom: [] 55 | }; 56 | var xAxis; 57 | for (var i = 0, l = series.length; i < l; i++) { 58 | if (series[i].type === ecConfig.CHART_TYPE_K) { 59 | series[i] = this.reformOption(series[i]); 60 | this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink; 61 | xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex); 62 | if (xAxis.type === ecConfig.COMPONENT_TYPE_AXIS_CATEGORY) { 63 | _position2sIndexMap[xAxis.getPosition()].push(i); 64 | } 65 | } 66 | } 67 | for (var position in _position2sIndexMap) { 68 | if (_position2sIndexMap[position].length > 0) { 69 | this._buildSinglePosition(position, _position2sIndexMap[position]); 70 | } 71 | } 72 | this.addShapeList(); 73 | }, 74 | _buildSinglePosition: function (position, seriesArray) { 75 | var mapData = this._mapData(seriesArray); 76 | var locationMap = mapData.locationMap; 77 | var maxDataLength = mapData.maxDataLength; 78 | if (maxDataLength === 0 || locationMap.length === 0) { 79 | return; 80 | } 81 | this._buildHorizontal(seriesArray, maxDataLength, locationMap); 82 | for (var i = 0, l = seriesArray.length; i < l; i++) { 83 | this.buildMark(seriesArray[i]); 84 | } 85 | }, 86 | _mapData: function (seriesArray) { 87 | var series = this.series; 88 | var serie; 89 | var serieName; 90 | var legend = this.component.legend; 91 | var locationMap = []; 92 | var maxDataLength = 0; 93 | for (var i = 0, l = seriesArray.length; i < l; i++) { 94 | serie = series[seriesArray[i]]; 95 | serieName = serie.name; 96 | this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true; 97 | if (this.selectedMap[serieName]) { 98 | locationMap.push(seriesArray[i]); 99 | } 100 | maxDataLength = Math.max(maxDataLength, serie.data.length); 101 | } 102 | return { 103 | locationMap: locationMap, 104 | maxDataLength: maxDataLength 105 | }; 106 | }, 107 | _buildHorizontal: function (seriesArray, maxDataLength, locationMap) { 108 | var series = this.series; 109 | var seriesIndex; 110 | var serie; 111 | var xAxisIndex; 112 | var categoryAxis; 113 | var yAxisIndex; 114 | var valueAxis; 115 | var pointList = {}; 116 | var candleWidth; 117 | var data; 118 | var value; 119 | var barMaxWidth; 120 | for (var j = 0, k = locationMap.length; j < k; j++) { 121 | seriesIndex = locationMap[j]; 122 | serie = series[seriesIndex]; 123 | xAxisIndex = serie.xAxisIndex || 0; 124 | categoryAxis = this.component.xAxis.getAxis(xAxisIndex); 125 | candleWidth = serie.barWidth || Math.floor(categoryAxis.getGap() / 2); 126 | barMaxWidth = serie.barMaxWidth; 127 | if (barMaxWidth && barMaxWidth < candleWidth) { 128 | candleWidth = barMaxWidth; 129 | } 130 | yAxisIndex = serie.yAxisIndex || 0; 131 | valueAxis = this.component.yAxis.getAxis(yAxisIndex); 132 | pointList[seriesIndex] = []; 133 | for (var i = 0, l = maxDataLength; i < l; i++) { 134 | if (categoryAxis.getNameByIndex(i) == null) { 135 | break; 136 | } 137 | data = serie.data[i]; 138 | value = this.getDataFromOption(data, '-'); 139 | if (value === '-' || value.length != 4) { 140 | continue; 141 | } 142 | pointList[seriesIndex].push([ 143 | categoryAxis.getCoordByIndex(i), 144 | candleWidth, 145 | valueAxis.getCoord(value[0]), 146 | valueAxis.getCoord(value[1]), 147 | valueAxis.getCoord(value[2]), 148 | valueAxis.getCoord(value[3]), 149 | i, 150 | categoryAxis.getNameByIndex(i) 151 | ]); 152 | } 153 | } 154 | this._buildKLine(seriesArray, pointList); 155 | }, 156 | _buildKLine: function (seriesArray, pointList) { 157 | var series = this.series; 158 | var nLineWidth; 159 | var nLineColor; 160 | var nLineColor0; 161 | var nColor; 162 | var nColor0; 163 | var eLineWidth; 164 | var eLineColor; 165 | var eLineColor0; 166 | var eColor; 167 | var eColor0; 168 | var serie; 169 | var queryTarget; 170 | var data; 171 | var seriesPL; 172 | var singlePoint; 173 | var candleType; 174 | var seriesIndex; 175 | for (var sIdx = 0, len = seriesArray.length; sIdx < len; sIdx++) { 176 | seriesIndex = seriesArray[sIdx]; 177 | serie = series[seriesIndex]; 178 | seriesPL = pointList[seriesIndex]; 179 | if (this._isLarge(seriesPL)) { 180 | seriesPL = this._getLargePointList(seriesPL); 181 | } 182 | if (serie.type === ecConfig.CHART_TYPE_K && seriesPL != null) { 183 | queryTarget = serie; 184 | nLineWidth = this.query(queryTarget, 'itemStyle.normal.lineStyle.width'); 185 | nLineColor = this.query(queryTarget, 'itemStyle.normal.lineStyle.color'); 186 | nLineColor0 = this.query(queryTarget, 'itemStyle.normal.lineStyle.color0'); 187 | nColor = this.query(queryTarget, 'itemStyle.normal.color'); 188 | nColor0 = this.query(queryTarget, 'itemStyle.normal.color0'); 189 | eLineWidth = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.width'); 190 | eLineColor = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color'); 191 | eLineColor0 = this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color0'); 192 | eColor = this.query(queryTarget, 'itemStyle.emphasis.color'); 193 | eColor0 = this.query(queryTarget, 'itemStyle.emphasis.color0'); 194 | for (var i = 0, l = seriesPL.length; i < l; i++) { 195 | singlePoint = seriesPL[i]; 196 | data = serie.data[singlePoint[6]]; 197 | queryTarget = data; 198 | candleType = singlePoint[3] < singlePoint[2]; 199 | this.shapeList.push(this._getCandle(seriesIndex, singlePoint[6], singlePoint[7], singlePoint[0], singlePoint[1], singlePoint[2], singlePoint[3], singlePoint[4], singlePoint[5], candleType ? this.query(queryTarget, 'itemStyle.normal.color') || nColor : this.query(queryTarget, 'itemStyle.normal.color0') || nColor0, this.query(queryTarget, 'itemStyle.normal.lineStyle.width') || nLineWidth, candleType ? this.query(queryTarget, 'itemStyle.normal.lineStyle.color') || nLineColor : this.query(queryTarget, 'itemStyle.normal.lineStyle.color0') || nLineColor0, candleType ? this.query(queryTarget, 'itemStyle.emphasis.color') || eColor || nColor : this.query(queryTarget, 'itemStyle.emphasis.color0') || eColor0 || nColor0, this.query(queryTarget, 'itemStyle.emphasis.lineStyle.width') || eLineWidth || nLineWidth, candleType ? this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color') || eLineColor || nLineColor : this.query(queryTarget, 'itemStyle.emphasis.lineStyle.color0') || eLineColor0 || nLineColor0)); 200 | } 201 | } 202 | } 203 | }, 204 | _isLarge: function (singlePL) { 205 | return singlePL[0][1] < 0.5; 206 | }, 207 | _getLargePointList: function (singlePL) { 208 | var total = this.component.grid.getWidth(); 209 | var len = singlePL.length; 210 | var newList = []; 211 | for (var i = 0; i < total; i++) { 212 | newList[i] = singlePL[Math.floor(len / total * i)]; 213 | } 214 | return newList; 215 | }, 216 | _getCandle: function (seriesIndex, dataIndex, name, x, width, y0, y1, y2, y3, nColor, nLinewidth, nLineColor, eColor, eLinewidth, eLineColor) { 217 | var series = this.series; 218 | var serie = series[seriesIndex]; 219 | var data = serie.data[dataIndex]; 220 | var queryTarget = [ 221 | data, 222 | serie 223 | ]; 224 | var itemShape = { 225 | zlevel: serie.zlevel, 226 | z: serie.z, 227 | clickable: this.deepQuery(queryTarget, 'clickable'), 228 | hoverable: this.deepQuery(queryTarget, 'hoverable'), 229 | style: { 230 | x: x, 231 | y: [ 232 | y0, 233 | y1, 234 | y2, 235 | y3 236 | ], 237 | width: width, 238 | color: nColor, 239 | strokeColor: nLineColor, 240 | lineWidth: nLinewidth, 241 | brushType: 'both' 242 | }, 243 | highlightStyle: { 244 | color: eColor, 245 | strokeColor: eLineColor, 246 | lineWidth: eLinewidth 247 | }, 248 | _seriesIndex: seriesIndex 249 | }; 250 | itemShape = this.addLabel(itemShape, serie, data, name); 251 | ecData.pack(itemShape, serie, seriesIndex, data, dataIndex, name); 252 | itemShape = new CandleShape(itemShape); 253 | return itemShape; 254 | }, 255 | getMarkCoord: function (seriesIndex, mpData) { 256 | var serie = this.series[seriesIndex]; 257 | var xAxis = this.component.xAxis.getAxis(serie.xAxisIndex); 258 | var yAxis = this.component.yAxis.getAxis(serie.yAxisIndex); 259 | return [ 260 | typeof mpData.xAxis != 'string' && xAxis.getCoordByIndex ? xAxis.getCoordByIndex(mpData.xAxis || 0) : xAxis.getCoord(mpData.xAxis || 0), 261 | typeof mpData.yAxis != 'string' && yAxis.getCoordByIndex ? yAxis.getCoordByIndex(mpData.yAxis || 0) : yAxis.getCoord(mpData.yAxis || 0) 262 | ]; 263 | }, 264 | refresh: function (newOption) { 265 | if (newOption) { 266 | this.option = newOption; 267 | this.series = newOption.series; 268 | } 269 | this.backupShapeList(); 270 | this._buildShape(); 271 | }, 272 | addDataAnimation: function (params, done) { 273 | var series = this.series; 274 | var aniMap = {}; 275 | for (var i = 0, l = params.length; i < l; i++) { 276 | aniMap[params[i][0]] = params[i]; 277 | } 278 | var x; 279 | var dx; 280 | var y; 281 | var serie; 282 | var seriesIndex; 283 | var dataIndex; 284 | var aniCount = 0; 285 | function animationDone() { 286 | aniCount--; 287 | if (aniCount === 0) { 288 | done && done(); 289 | } 290 | } 291 | for (var i = 0, l = this.shapeList.length; i < l; i++) { 292 | seriesIndex = this.shapeList[i]._seriesIndex; 293 | if (aniMap[seriesIndex] && !aniMap[seriesIndex][3]) { 294 | if (this.shapeList[i].type === 'candle') { 295 | dataIndex = ecData.get(this.shapeList[i], 'dataIndex'); 296 | serie = series[seriesIndex]; 297 | if (aniMap[seriesIndex][2] && dataIndex === serie.data.length - 1) { 298 | this.zr.delShape(this.shapeList[i].id); 299 | continue; 300 | } else if (!aniMap[seriesIndex][2] && dataIndex === 0) { 301 | this.zr.delShape(this.shapeList[i].id); 302 | continue; 303 | } 304 | dx = this.component.xAxis.getAxis(serie.xAxisIndex || 0).getGap(); 305 | x = aniMap[seriesIndex][2] ? dx : -dx; 306 | y = 0; 307 | aniCount++; 308 | this.zr.animate(this.shapeList[i].id, '').when(this.query(this.option, 'animationDurationUpdate'), { 309 | position: [ 310 | x, 311 | y 312 | ] 313 | }).done(animationDone).start(); 314 | } 315 | } 316 | } 317 | if (!aniCount) { 318 | done && done(); 319 | } 320 | } 321 | }; 322 | zrUtil.inherits(K, ChartBase); 323 | require('../chart').define('k', K); 324 | return K; 325 | }); -------------------------------------------------------------------------------- /inst/JS/chart/eventRiver.js: -------------------------------------------------------------------------------- 1 | define('echarts/chart/eventRiver', [ 2 | 'require', 3 | './base', 4 | '../layout/eventRiver', 5 | 'zrender/shape/Polygon', 6 | '../component/axis', 7 | '../component/grid', 8 | '../component/dataZoom', 9 | '../config', 10 | '../util/ecData', 11 | '../util/date', 12 | 'zrender/tool/util', 13 | 'zrender/tool/color', 14 | '../chart' 15 | ], function (require) { 16 | var ChartBase = require('./base'); 17 | var eventRiverLayout = require('../layout/eventRiver'); 18 | var PolygonShape = require('zrender/shape/Polygon'); 19 | require('../component/axis'); 20 | require('../component/grid'); 21 | require('../component/dataZoom'); 22 | var ecConfig = require('../config'); 23 | ecConfig.eventRiver = { 24 | zlevel: 0, 25 | z: 2, 26 | clickable: true, 27 | legendHoverLink: true, 28 | itemStyle: { 29 | normal: { 30 | borderColor: 'rgba(0,0,0,0)', 31 | borderWidth: 1, 32 | label: { 33 | show: true, 34 | position: 'inside', 35 | formatter: '{b}' 36 | } 37 | }, 38 | emphasis: { 39 | borderColor: 'rgba(0,0,0,0)', 40 | borderWidth: 1, 41 | label: { show: true } 42 | } 43 | } 44 | }; 45 | var ecData = require('../util/ecData'); 46 | var ecDate = require('../util/date'); 47 | var zrUtil = require('zrender/tool/util'); 48 | var zrColor = require('zrender/tool/color'); 49 | function EventRiver(ecTheme, messageCenter, zr, option, myChart) { 50 | ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart); 51 | var self = this; 52 | self._ondragend = function () { 53 | self.isDragend = true; 54 | }; 55 | this.refresh(option); 56 | } 57 | EventRiver.prototype = { 58 | type: ecConfig.CHART_TYPE_EVENTRIVER, 59 | _buildShape: function () { 60 | var series = this.series; 61 | this.selectedMap = {}; 62 | this._dataPreprocessing(); 63 | var legend = this.component.legend; 64 | var eventRiverSeries = []; 65 | for (var i = 0; i < series.length; i++) { 66 | if (series[i].type === this.type) { 67 | series[i] = this.reformOption(series[i]); 68 | this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink; 69 | var serieName = series[i].name || ''; 70 | this.selectedMap[serieName] = legend ? legend.isSelected(serieName) : true; 71 | if (!this.selectedMap[serieName]) { 72 | continue; 73 | } 74 | this.buildMark(i); 75 | eventRiverSeries.push(this.series[i]); 76 | } 77 | } 78 | eventRiverLayout(eventRiverSeries, this._intervalX, this.component.grid.getArea()); 79 | this._drawEventRiver(); 80 | this.addShapeList(); 81 | }, 82 | _dataPreprocessing: function () { 83 | var series = this.series; 84 | var xAxis; 85 | var evolutionList; 86 | for (var i = 0, iLen = series.length; i < iLen; i++) { 87 | if (series[i].type === this.type) { 88 | xAxis = this.component.xAxis.getAxis(series[i].xAxisIndex || 0); 89 | for (var j = 0, jLen = series[i].data.length; j < jLen; j++) { 90 | evolutionList = series[i].data[j].evolution; 91 | for (var k = 0, kLen = evolutionList.length; k < kLen; k++) { 92 | evolutionList[k].timeScale = xAxis.getCoord(ecDate.getNewDate(evolutionList[k].time) - 0); 93 | evolutionList[k].valueScale = Math.pow(evolutionList[k].value, 0.8); 94 | } 95 | } 96 | } 97 | } 98 | this._intervalX = Math.round(this.component.grid.getWidth() / 40); 99 | }, 100 | _drawEventRiver: function () { 101 | var series = this.series; 102 | for (var i = 0; i < series.length; i++) { 103 | var serieName = series[i].name || ''; 104 | if (series[i].type === this.type && this.selectedMap[serieName]) { 105 | for (var j = 0; j < series[i].data.length; j++) { 106 | this._drawEventBubble(series[i].data[j], i, j); 107 | } 108 | } 109 | } 110 | }, 111 | _drawEventBubble: function (oneEvent, seriesIndex, dataIndex) { 112 | var series = this.series; 113 | var serie = series[seriesIndex]; 114 | var serieName = serie.name || ''; 115 | var data = serie.data[dataIndex]; 116 | var queryTarget = [ 117 | data, 118 | serie 119 | ]; 120 | var legend = this.component.legend; 121 | var defaultColor = legend ? legend.getColor(serieName) : this.zr.getColor(seriesIndex); 122 | var normal = this.deepMerge(queryTarget, 'itemStyle.normal') || {}; 123 | var emphasis = this.deepMerge(queryTarget, 'itemStyle.emphasis') || {}; 124 | var normalColor = this.getItemStyleColor(normal.color, seriesIndex, dataIndex, data) || defaultColor; 125 | var emphasisColor = this.getItemStyleColor(emphasis.color, seriesIndex, dataIndex, data) || (typeof normalColor === 'string' ? zrColor.lift(normalColor, -0.2) : normalColor); 126 | var pts = this._calculateControlPoints(oneEvent); 127 | var eventBubbleShape = { 128 | zlevel: serie.zlevel, 129 | z: serie.z, 130 | clickable: this.deepQuery(queryTarget, 'clickable'), 131 | style: { 132 | pointList: pts, 133 | smooth: 'spline', 134 | brushType: 'both', 135 | lineJoin: 'round', 136 | color: normalColor, 137 | lineWidth: normal.borderWidth, 138 | strokeColor: normal.borderColor 139 | }, 140 | highlightStyle: { 141 | color: emphasisColor, 142 | lineWidth: emphasis.borderWidth, 143 | strokeColor: emphasis.borderColor 144 | }, 145 | draggable: 'vertical', 146 | ondragend: this._ondragend 147 | }; 148 | eventBubbleShape = new PolygonShape(eventBubbleShape); 149 | this.addLabel(eventBubbleShape, serie, data, oneEvent.name); 150 | ecData.pack(eventBubbleShape, series[seriesIndex], seriesIndex, series[seriesIndex].data[dataIndex], dataIndex, series[seriesIndex].data[dataIndex].name); 151 | this.shapeList.push(eventBubbleShape); 152 | }, 153 | _calculateControlPoints: function (oneEvent) { 154 | var intervalX = this._intervalX; 155 | var posY = oneEvent.y; 156 | var evolution = oneEvent.evolution; 157 | var n = evolution.length; 158 | if (n < 1) { 159 | return; 160 | } 161 | var time = []; 162 | var value = []; 163 | for (var i = 0; i < n; i++) { 164 | time.push(evolution[i].timeScale); 165 | value.push(evolution[i].valueScale); 166 | } 167 | var pts = []; 168 | pts.push([ 169 | time[0], 170 | posY 171 | ]); 172 | var i = 0; 173 | for (i = 0; i < n - 1; i++) { 174 | pts.push([ 175 | (time[i] + time[i + 1]) / 2, 176 | value[i] / -2 + posY 177 | ]); 178 | } 179 | pts.push([ 180 | (time[i] + (time[i] + intervalX)) / 2, 181 | value[i] / -2 + posY 182 | ]); 183 | pts.push([ 184 | time[i] + intervalX, 185 | posY 186 | ]); 187 | pts.push([ 188 | (time[i] + (time[i] + intervalX)) / 2, 189 | value[i] / 2 + posY 190 | ]); 191 | for (i = n - 1; i > 0; i--) { 192 | pts.push([ 193 | (time[i] + time[i - 1]) / 2, 194 | value[i - 1] / 2 + posY 195 | ]); 196 | } 197 | return pts; 198 | }, 199 | ondragend: function (param, status) { 200 | if (!this.isDragend || !param.target) { 201 | return; 202 | } 203 | status.dragOut = true; 204 | status.dragIn = true; 205 | status.needRefresh = false; 206 | this.isDragend = false; 207 | }, 208 | refresh: function (newOption) { 209 | if (newOption) { 210 | this.option = newOption; 211 | this.series = newOption.series; 212 | } 213 | this.backupShapeList(); 214 | this._buildShape(); 215 | } 216 | }; 217 | zrUtil.inherits(EventRiver, ChartBase); 218 | require('../chart').define('eventRiver', EventRiver); 219 | return EventRiver; 220 | });define('echarts/layout/eventRiver', ['require'], function (require) { 221 | function eventRiverLayout(series, intervalX, area) { 222 | var space = 4; 223 | var scale = intervalX; 224 | function importanceSort(a, b) { 225 | var x = a.importance; 226 | var y = b.importance; 227 | return x > y ? -1 : x < y ? 1 : 0; 228 | } 229 | function indexOf(array, value) { 230 | if (array.indexOf) { 231 | return array.indexOf(value); 232 | } 233 | for (var i = 0, len = array.length; i < len; i++) { 234 | if (array[i] === value) { 235 | return i; 236 | } 237 | } 238 | return -1; 239 | } 240 | for (var i = 0; i < series.length; i++) { 241 | for (var j = 0; j < series[i].data.length; j++) { 242 | if (series[i].data[j].weight == null) { 243 | series[i].data[j].weight = 1; 244 | } 245 | var importance = 0; 246 | for (var k = 0; k < series[i].data[j].evolution.length; k++) { 247 | importance += series[i].data[j].evolution[k].valueScale; 248 | } 249 | series[i].data[j].importance = importance * series[i].data[j].weight; 250 | } 251 | series[i].data.sort(importanceSort); 252 | } 253 | for (var i = 0; i < series.length; i++) { 254 | if (series[i].weight == null) { 255 | series[i].weight = 1; 256 | } 257 | var importance = 0; 258 | for (var j = 0; j < series[i].data.length; j++) { 259 | importance += series[i].data[j].weight; 260 | } 261 | series[i].importance = importance * series[i].weight; 262 | } 263 | series.sort(importanceSort); 264 | var minTime = Number.MAX_VALUE; 265 | var maxTime = 0; 266 | for (var i = 0; i < series.length; i++) { 267 | for (var j = 0; j < series[i].data.length; j++) { 268 | for (var k = 0; k < series[i].data[j].evolution.length; k++) { 269 | var time = series[i].data[j].evolution[k].timeScale; 270 | minTime = Math.min(minTime, time); 271 | maxTime = Math.max(maxTime, time); 272 | } 273 | } 274 | } 275 | minTime = ~~minTime; 276 | maxTime = ~~maxTime; 277 | var flagForOffset = function () { 278 | var length = maxTime - minTime + 1 + ~~intervalX; 279 | if (length <= 0) { 280 | return [0]; 281 | } 282 | var result = []; 283 | while (length--) { 284 | result.push(0); 285 | } 286 | return result; 287 | }(); 288 | var flagForPos = flagForOffset.slice(0); 289 | var bubbleData = []; 290 | var totalMaxy = 0; 291 | var totalOffset = 0; 292 | for (var i = 0; i < series.length; i++) { 293 | for (var j = 0; j < series[i].data.length; j++) { 294 | var e = series[i].data[j]; 295 | e.time = []; 296 | e.value = []; 297 | var tmp; 298 | var maxy = 0; 299 | for (var k = 0; k < series[i].data[j].evolution.length; k++) { 300 | tmp = series[i].data[j].evolution[k]; 301 | e.time.push(tmp.timeScale); 302 | e.value.push(tmp.valueScale); 303 | maxy = Math.max(maxy, tmp.valueScale); 304 | } 305 | bubbleBound(e, intervalX, minTime); 306 | e.y = findLocation(flagForPos, e, function (e, index) { 307 | return e.ypx[index]; 308 | }); 309 | e._offset = findLocation(flagForOffset, e, function () { 310 | return space; 311 | }); 312 | totalMaxy = Math.max(totalMaxy, e.y + maxy); 313 | totalOffset = Math.max(totalOffset, e._offset); 314 | bubbleData.push(e); 315 | } 316 | } 317 | scaleY(bubbleData, area, totalMaxy, totalOffset); 318 | } 319 | function scaleY(bubbleData, area, maxY, offset) { 320 | var height = area.height; 321 | var offsetScale = offset / height > 0.5 ? 0.5 : 1; 322 | var yBase = area.y; 323 | var yScale = (area.height - offset) / maxY; 324 | for (var i = 0, length = bubbleData.length; i < length; i++) { 325 | var e = bubbleData[i]; 326 | e.y = yBase + yScale * e.y + e._offset * offsetScale; 327 | delete e.time; 328 | delete e.value; 329 | delete e.xpx; 330 | delete e.ypx; 331 | delete e._offset; 332 | var evolutionList = e.evolution; 333 | for (var k = 0, klen = evolutionList.length; k < klen; k++) { 334 | evolutionList[k].valueScale *= yScale; 335 | } 336 | } 337 | } 338 | function line(x0, y0, x1, y1) { 339 | if (x0 === x1) { 340 | throw new Error('x0 is equal with x1!!!'); 341 | } 342 | if (y0 === y1) { 343 | return function () { 344 | return y0; 345 | }; 346 | } 347 | var k = (y0 - y1) / (x0 - x1); 348 | var b = (y1 * x0 - y0 * x1) / (x0 - x1); 349 | return function (x) { 350 | return k * x + b; 351 | }; 352 | } 353 | function bubbleBound(e, intervalX, minX) { 354 | var space = ~~intervalX; 355 | var length = e.time.length; 356 | e.xpx = []; 357 | e.ypx = []; 358 | var i = 0; 359 | var x0 = 0; 360 | var x1 = 0; 361 | var y0 = 0; 362 | var y1 = 0; 363 | var newline; 364 | for (; i < length; i++) { 365 | x0 = ~~e.time[i]; 366 | y0 = e.value[i] / 2; 367 | if (i === length - 1) { 368 | x1 = x0 + space; 369 | y1 = 0; 370 | } else { 371 | x1 = ~~e.time[i + 1]; 372 | y1 = e.value[i + 1] / 2; 373 | } 374 | newline = line(x0, y0, x1, y1); 375 | for (var x = x0; x < x1; x++) { 376 | e.xpx.push(x - minX); 377 | e.ypx.push(newline(x)); 378 | } 379 | } 380 | e.xpx.push(x1 - minX); 381 | e.ypx.push(y1); 382 | } 383 | function findLocation(flags, e, yvalue) { 384 | var pos = 0; 385 | var length = e.xpx.length; 386 | var i = 0; 387 | var y; 388 | for (; i < length; i++) { 389 | y = yvalue(e, i); 390 | pos = Math.max(pos, y + flags[e.xpx[i]]); 391 | } 392 | for (i = 0; i < length; i++) { 393 | y = yvalue(e, i); 394 | flags[e.xpx[i]] = pos + y; 395 | } 396 | return pos; 397 | } 398 | return eventRiverLayout; 399 | }); -------------------------------------------------------------------------------- /inst/JS/chart/gauge.js: -------------------------------------------------------------------------------- 1 | define('echarts/chart/gauge', [ 2 | 'require', 3 | './base', 4 | '../util/shape/GaugePointer', 5 | 'zrender/shape/Text', 6 | 'zrender/shape/Line', 7 | 'zrender/shape/Rectangle', 8 | 'zrender/shape/Circle', 9 | 'zrender/shape/Sector', 10 | '../config', 11 | '../util/ecData', 12 | '../util/accMath', 13 | 'zrender/tool/util', 14 | '../chart' 15 | ], function (require) { 16 | var ChartBase = require('./base'); 17 | var GaugePointerShape = require('../util/shape/GaugePointer'); 18 | var TextShape = require('zrender/shape/Text'); 19 | var LineShape = require('zrender/shape/Line'); 20 | var RectangleShape = require('zrender/shape/Rectangle'); 21 | var CircleShape = require('zrender/shape/Circle'); 22 | var SectorShape = require('zrender/shape/Sector'); 23 | var ecConfig = require('../config'); 24 | ecConfig.gauge = { 25 | zlevel: 0, 26 | z: 2, 27 | center: [ 28 | '50%', 29 | '50%' 30 | ], 31 | clickable: true, 32 | legendHoverLink: true, 33 | radius: '75%', 34 | startAngle: 225, 35 | endAngle: -45, 36 | min: 0, 37 | max: 100, 38 | splitNumber: 10, 39 | axisLine: { 40 | show: true, 41 | lineStyle: { 42 | color: [ 43 | [ 44 | 0.2, 45 | '#228b22' 46 | ], 47 | [ 48 | 0.8, 49 | '#48b' 50 | ], 51 | [ 52 | 1, 53 | '#ff4500' 54 | ] 55 | ], 56 | width: 30 57 | } 58 | }, 59 | axisTick: { 60 | show: true, 61 | splitNumber: 5, 62 | length: 8, 63 | lineStyle: { 64 | color: '#eee', 65 | width: 1, 66 | type: 'solid' 67 | } 68 | }, 69 | axisLabel: { 70 | show: true, 71 | textStyle: { color: 'auto' } 72 | }, 73 | splitLine: { 74 | show: true, 75 | length: 30, 76 | lineStyle: { 77 | color: '#eee', 78 | width: 2, 79 | type: 'solid' 80 | } 81 | }, 82 | pointer: { 83 | show: true, 84 | length: '80%', 85 | width: 8, 86 | color: 'auto' 87 | }, 88 | title: { 89 | show: true, 90 | offsetCenter: [ 91 | 0, 92 | '-40%' 93 | ], 94 | textStyle: { 95 | color: '#333', 96 | fontSize: 15 97 | } 98 | }, 99 | detail: { 100 | show: true, 101 | backgroundColor: 'rgba(0,0,0,0)', 102 | borderWidth: 0, 103 | borderColor: '#ccc', 104 | width: 100, 105 | height: 40, 106 | offsetCenter: [ 107 | 0, 108 | '40%' 109 | ], 110 | textStyle: { 111 | color: 'auto', 112 | fontSize: 30 113 | } 114 | } 115 | }; 116 | var ecData = require('../util/ecData'); 117 | var accMath = require('../util/accMath'); 118 | var zrUtil = require('zrender/tool/util'); 119 | function Gauge(ecTheme, messageCenter, zr, option, myChart) { 120 | ChartBase.call(this, ecTheme, messageCenter, zr, option, myChart); 121 | this.refresh(option); 122 | } 123 | Gauge.prototype = { 124 | type: ecConfig.CHART_TYPE_GAUGE, 125 | _buildShape: function () { 126 | var series = this.series; 127 | this._paramsMap = {}; 128 | this.selectedMap = {}; 129 | for (var i = 0, l = series.length; i < l; i++) { 130 | if (series[i].type === ecConfig.CHART_TYPE_GAUGE) { 131 | this.selectedMap[series[i].name] = true; 132 | series[i] = this.reformOption(series[i]); 133 | this.legendHoverLink = series[i].legendHoverLink || this.legendHoverLink; 134 | this._buildSingleGauge(i); 135 | this.buildMark(i); 136 | } 137 | } 138 | this.addShapeList(); 139 | }, 140 | _buildSingleGauge: function (seriesIndex) { 141 | var serie = this.series[seriesIndex]; 142 | this._paramsMap[seriesIndex] = { 143 | center: this.parseCenter(this.zr, serie.center), 144 | radius: this.parseRadius(this.zr, serie.radius), 145 | startAngle: serie.startAngle.toFixed(2) - 0, 146 | endAngle: serie.endAngle.toFixed(2) - 0 147 | }; 148 | this._paramsMap[seriesIndex].totalAngle = this._paramsMap[seriesIndex].startAngle - this._paramsMap[seriesIndex].endAngle; 149 | this._colorMap(seriesIndex); 150 | this._buildAxisLine(seriesIndex); 151 | this._buildSplitLine(seriesIndex); 152 | this._buildAxisTick(seriesIndex); 153 | this._buildAxisLabel(seriesIndex); 154 | this._buildPointer(seriesIndex); 155 | this._buildTitle(seriesIndex); 156 | this._buildDetail(seriesIndex); 157 | }, 158 | _buildAxisLine: function (seriesIndex) { 159 | var serie = this.series[seriesIndex]; 160 | if (!serie.axisLine.show) { 161 | return; 162 | } 163 | var min = serie.min; 164 | var total = serie.max - min; 165 | var params = this._paramsMap[seriesIndex]; 166 | var center = params.center; 167 | var startAngle = params.startAngle; 168 | var totalAngle = params.totalAngle; 169 | var colorArray = params.colorArray; 170 | var lineStyle = serie.axisLine.lineStyle; 171 | var lineWidth = this.parsePercent(lineStyle.width, params.radius[1]); 172 | var r = params.radius[1]; 173 | var r0 = r - lineWidth; 174 | var sectorShape; 175 | var lastAngle = startAngle; 176 | var newAngle; 177 | for (var i = 0, l = colorArray.length; i < l; i++) { 178 | newAngle = startAngle - totalAngle * (colorArray[i][0] - min) / total; 179 | sectorShape = this._getSector(center, r0, r, newAngle, lastAngle, colorArray[i][1], lineStyle, serie.zlevel, serie.z); 180 | lastAngle = newAngle; 181 | sectorShape._animationAdd = 'r'; 182 | ecData.set(sectorShape, 'seriesIndex', seriesIndex); 183 | ecData.set(sectorShape, 'dataIndex', i); 184 | this.shapeList.push(sectorShape); 185 | } 186 | }, 187 | _buildSplitLine: function (seriesIndex) { 188 | var serie = this.series[seriesIndex]; 189 | if (!serie.splitLine.show) { 190 | return; 191 | } 192 | var params = this._paramsMap[seriesIndex]; 193 | var splitNumber = serie.splitNumber; 194 | var min = serie.min; 195 | var total = serie.max - min; 196 | var splitLine = serie.splitLine; 197 | var length = this.parsePercent(splitLine.length, params.radius[1]); 198 | var lineStyle = splitLine.lineStyle; 199 | var color = lineStyle.color; 200 | var center = params.center; 201 | var startAngle = params.startAngle * Math.PI / 180; 202 | var totalAngle = params.totalAngle * Math.PI / 180; 203 | var r = params.radius[1]; 204 | var r0 = r - length; 205 | var angle; 206 | var sinAngle; 207 | var cosAngle; 208 | for (var i = 0; i <= splitNumber; i++) { 209 | angle = startAngle - totalAngle / splitNumber * i; 210 | sinAngle = Math.sin(angle); 211 | cosAngle = Math.cos(angle); 212 | this.shapeList.push(new LineShape({ 213 | zlevel: serie.zlevel, 214 | z: serie.z + 1, 215 | hoverable: false, 216 | style: { 217 | xStart: center[0] + cosAngle * r, 218 | yStart: center[1] - sinAngle * r, 219 | xEnd: center[0] + cosAngle * r0, 220 | yEnd: center[1] - sinAngle * r0, 221 | strokeColor: color === 'auto' ? this._getColor(seriesIndex, min + total / splitNumber * i) : color, 222 | lineType: lineStyle.type, 223 | lineWidth: lineStyle.width, 224 | shadowColor: lineStyle.shadowColor, 225 | shadowBlur: lineStyle.shadowBlur, 226 | shadowOffsetX: lineStyle.shadowOffsetX, 227 | shadowOffsetY: lineStyle.shadowOffsetY 228 | } 229 | })); 230 | } 231 | }, 232 | _buildAxisTick: function (seriesIndex) { 233 | var serie = this.series[seriesIndex]; 234 | if (!serie.axisTick.show) { 235 | return; 236 | } 237 | var params = this._paramsMap[seriesIndex]; 238 | var splitNumber = serie.splitNumber; 239 | var min = serie.min; 240 | var total = serie.max - min; 241 | var axisTick = serie.axisTick; 242 | var tickSplit = axisTick.splitNumber; 243 | var length = this.parsePercent(axisTick.length, params.radius[1]); 244 | var lineStyle = axisTick.lineStyle; 245 | var color = lineStyle.color; 246 | var center = params.center; 247 | var startAngle = params.startAngle * Math.PI / 180; 248 | var totalAngle = params.totalAngle * Math.PI / 180; 249 | var r = params.radius[1]; 250 | var r0 = r - length; 251 | var angle; 252 | var sinAngle; 253 | var cosAngle; 254 | for (var i = 0, l = splitNumber * tickSplit; i <= l; i++) { 255 | if (i % tickSplit === 0) { 256 | continue; 257 | } 258 | angle = startAngle - totalAngle / l * i; 259 | sinAngle = Math.sin(angle); 260 | cosAngle = Math.cos(angle); 261 | this.shapeList.push(new LineShape({ 262 | zlevel: serie.zlevel, 263 | z: serie.z + 1, 264 | hoverable: false, 265 | style: { 266 | xStart: center[0] + cosAngle * r, 267 | yStart: center[1] - sinAngle * r, 268 | xEnd: center[0] + cosAngle * r0, 269 | yEnd: center[1] - sinAngle * r0, 270 | strokeColor: color === 'auto' ? this._getColor(seriesIndex, min + total / l * i) : color, 271 | lineType: lineStyle.type, 272 | lineWidth: lineStyle.width, 273 | shadowColor: lineStyle.shadowColor, 274 | shadowBlur: lineStyle.shadowBlur, 275 | shadowOffsetX: lineStyle.shadowOffsetX, 276 | shadowOffsetY: lineStyle.shadowOffsetY 277 | } 278 | })); 279 | } 280 | }, 281 | _buildAxisLabel: function (seriesIndex) { 282 | var serie = this.series[seriesIndex]; 283 | if (!serie.axisLabel.show) { 284 | return; 285 | } 286 | var splitNumber = serie.splitNumber; 287 | var min = serie.min; 288 | var total = serie.max - min; 289 | var textStyle = serie.axisLabel.textStyle; 290 | var textFont = this.getFont(textStyle); 291 | var color = textStyle.color; 292 | var params = this._paramsMap[seriesIndex]; 293 | var center = params.center; 294 | var startAngle = params.startAngle; 295 | var totalAngle = params.totalAngle; 296 | var r0 = params.radius[1] - this.parsePercent(serie.splitLine.length, params.radius[1]) - 5; 297 | var angle; 298 | var sinAngle; 299 | var cosAngle; 300 | var value; 301 | for (var i = 0; i <= splitNumber; i++) { 302 | value = accMath.accAdd(min, accMath.accMul(accMath.accDiv(total, splitNumber), i)); 303 | angle = startAngle - totalAngle / splitNumber * i; 304 | sinAngle = Math.sin(angle * Math.PI / 180); 305 | cosAngle = Math.cos(angle * Math.PI / 180); 306 | angle = (angle + 360) % 360; 307 | this.shapeList.push(new TextShape({ 308 | zlevel: serie.zlevel, 309 | z: serie.z + 1, 310 | hoverable: false, 311 | style: { 312 | x: center[0] + cosAngle * r0, 313 | y: center[1] - sinAngle * r0, 314 | color: color === 'auto' ? this._getColor(seriesIndex, value) : color, 315 | text: this._getLabelText(serie.axisLabel.formatter, value), 316 | textAlign: angle >= 110 && angle <= 250 ? 'left' : angle <= 70 || angle >= 290 ? 'right' : 'center', 317 | textBaseline: angle >= 10 && angle <= 170 ? 'top' : angle >= 190 && angle <= 350 ? 'bottom' : 'middle', 318 | textFont: textFont, 319 | shadowColor: textStyle.shadowColor, 320 | shadowBlur: textStyle.shadowBlur, 321 | shadowOffsetX: textStyle.shadowOffsetX, 322 | shadowOffsetY: textStyle.shadowOffsetY 323 | } 324 | })); 325 | } 326 | }, 327 | _buildPointer: function (seriesIndex) { 328 | var serie = this.series[seriesIndex]; 329 | if (!serie.pointer.show) { 330 | return; 331 | } 332 | var total = serie.max - serie.min; 333 | var pointer = serie.pointer; 334 | var params = this._paramsMap[seriesIndex]; 335 | var length = this.parsePercent(pointer.length, params.radius[1]); 336 | var width = this.parsePercent(pointer.width, params.radius[1]); 337 | var center = params.center; 338 | var value = this._getValue(seriesIndex); 339 | value = value < serie.max ? value : serie.max; 340 | var angle = (params.startAngle - params.totalAngle / total * (value - serie.min)) * Math.PI / 180; 341 | var color = pointer.color === 'auto' ? this._getColor(seriesIndex, value) : pointer.color; 342 | var pointShape = new GaugePointerShape({ 343 | zlevel: serie.zlevel, 344 | z: serie.z + 1, 345 | clickable: this.query(serie, 'clickable'), 346 | style: { 347 | x: center[0], 348 | y: center[1], 349 | r: length, 350 | startAngle: params.startAngle * Math.PI / 180, 351 | angle: angle, 352 | color: color, 353 | width: width, 354 | shadowColor: pointer.shadowColor, 355 | shadowBlur: pointer.shadowBlur, 356 | shadowOffsetX: pointer.shadowOffsetX, 357 | shadowOffsetY: pointer.shadowOffsetY 358 | }, 359 | highlightStyle: { 360 | brushType: 'fill', 361 | width: width > 2 ? 2 : width / 2, 362 | color: '#fff' 363 | } 364 | }); 365 | ecData.pack(pointShape, this.series[seriesIndex], seriesIndex, this.series[seriesIndex].data[0], 0, this.series[seriesIndex].data[0].name, value); 366 | this.shapeList.push(pointShape); 367 | this.shapeList.push(new CircleShape({ 368 | zlevel: serie.zlevel, 369 | z: serie.z + 2, 370 | hoverable: false, 371 | style: { 372 | x: center[0], 373 | y: center[1], 374 | r: pointer.width / 2.5, 375 | color: '#fff' 376 | } 377 | })); 378 | }, 379 | _buildTitle: function (seriesIndex) { 380 | var serie = this.series[seriesIndex]; 381 | if (!serie.title.show) { 382 | return; 383 | } 384 | var data = serie.data[0]; 385 | var name = data.name != null ? data.name : ''; 386 | if (name !== '') { 387 | var title = serie.title; 388 | var offsetCenter = title.offsetCenter; 389 | var textStyle = title.textStyle; 390 | var textColor = textStyle.color; 391 | var params = this._paramsMap[seriesIndex]; 392 | var x = params.center[0] + this.parsePercent(offsetCenter[0], params.radius[1]); 393 | var y = params.center[1] + this.parsePercent(offsetCenter[1], params.radius[1]); 394 | this.shapeList.push(new TextShape({ 395 | zlevel: serie.zlevel, 396 | z: serie.z + (Math.abs(x - params.center[0]) + Math.abs(y - params.center[1]) < textStyle.fontSize * 2 ? 2 : 1), 397 | hoverable: false, 398 | style: { 399 | x: x, 400 | y: y, 401 | color: textColor === 'auto' ? this._getColor(seriesIndex) : textColor, 402 | text: name, 403 | textAlign: 'center', 404 | textFont: this.getFont(textStyle), 405 | shadowColor: textStyle.shadowColor, 406 | shadowBlur: textStyle.shadowBlur, 407 | shadowOffsetX: textStyle.shadowOffsetX, 408 | shadowOffsetY: textStyle.shadowOffsetY 409 | } 410 | })); 411 | } 412 | }, 413 | _buildDetail: function (seriesIndex) { 414 | var serie = this.series[seriesIndex]; 415 | if (!serie.detail.show) { 416 | return; 417 | } 418 | var detail = serie.detail; 419 | var offsetCenter = detail.offsetCenter; 420 | var color = detail.backgroundColor; 421 | var textStyle = detail.textStyle; 422 | var textColor = textStyle.color; 423 | var params = this._paramsMap[seriesIndex]; 424 | var value = this._getValue(seriesIndex); 425 | var x = params.center[0] - detail.width / 2 + this.parsePercent(offsetCenter[0], params.radius[1]); 426 | var y = params.center[1] + this.parsePercent(offsetCenter[1], params.radius[1]); 427 | this.shapeList.push(new RectangleShape({ 428 | zlevel: serie.zlevel, 429 | z: serie.z + (Math.abs(x + detail.width / 2 - params.center[0]) + Math.abs(y + detail.height / 2 - params.center[1]) < textStyle.fontSize ? 2 : 1), 430 | hoverable: false, 431 | style: { 432 | x: x, 433 | y: y, 434 | width: detail.width, 435 | height: detail.height, 436 | brushType: 'both', 437 | color: color === 'auto' ? this._getColor(seriesIndex, value) : color, 438 | lineWidth: detail.borderWidth, 439 | strokeColor: detail.borderColor, 440 | shadowColor: detail.shadowColor, 441 | shadowBlur: detail.shadowBlur, 442 | shadowOffsetX: detail.shadowOffsetX, 443 | shadowOffsetY: detail.shadowOffsetY, 444 | text: this._getLabelText(detail.formatter, value), 445 | textFont: this.getFont(textStyle), 446 | textPosition: 'inside', 447 | textColor: textColor === 'auto' ? this._getColor(seriesIndex, value) : textColor 448 | } 449 | })); 450 | }, 451 | _getValue: function (seriesIndex) { 452 | return this.getDataFromOption(this.series[seriesIndex].data[0]); 453 | }, 454 | _colorMap: function (seriesIndex) { 455 | var serie = this.series[seriesIndex]; 456 | var min = serie.min; 457 | var total = serie.max - min; 458 | var color = serie.axisLine.lineStyle.color; 459 | if (!(color instanceof Array)) { 460 | color = [[ 461 | 1, 462 | color 463 | ]]; 464 | } 465 | var colorArray = []; 466 | for (var i = 0, l = color.length; i < l; i++) { 467 | colorArray.push([ 468 | color[i][0] * total + min, 469 | color[i][1] 470 | ]); 471 | } 472 | this._paramsMap[seriesIndex].colorArray = colorArray; 473 | }, 474 | _getColor: function (seriesIndex, value) { 475 | if (value == null) { 476 | value = this._getValue(seriesIndex); 477 | } 478 | var colorArray = this._paramsMap[seriesIndex].colorArray; 479 | for (var i = 0, l = colorArray.length; i < l; i++) { 480 | if (colorArray[i][0] >= value) { 481 | return colorArray[i][1]; 482 | } 483 | } 484 | return colorArray[colorArray.length - 1][1]; 485 | }, 486 | _getSector: function (center, r0, r, startAngle, endAngle, color, lineStyle, zlevel, z) { 487 | return new SectorShape({ 488 | zlevel: zlevel, 489 | z: z, 490 | hoverable: false, 491 | style: { 492 | x: center[0], 493 | y: center[1], 494 | r0: r0, 495 | r: r, 496 | startAngle: startAngle, 497 | endAngle: endAngle, 498 | brushType: 'fill', 499 | color: color, 500 | shadowColor: lineStyle.shadowColor, 501 | shadowBlur: lineStyle.shadowBlur, 502 | shadowOffsetX: lineStyle.shadowOffsetX, 503 | shadowOffsetY: lineStyle.shadowOffsetY 504 | } 505 | }); 506 | }, 507 | _getLabelText: function (formatter, value) { 508 | if (formatter) { 509 | if (typeof formatter === 'function') { 510 | return formatter.call(this.myChart, value); 511 | } else if (typeof formatter === 'string') { 512 | return formatter.replace('{value}', value); 513 | } 514 | } 515 | return value; 516 | }, 517 | refresh: function (newOption) { 518 | if (newOption) { 519 | this.option = newOption; 520 | this.series = newOption.series; 521 | } 522 | this.backupShapeList(); 523 | this._buildShape(); 524 | } 525 | }; 526 | zrUtil.inherits(Gauge, ChartBase); 527 | require('../chart').define('gauge', Gauge); 528 | return Gauge; 529 | });define('echarts/util/shape/GaugePointer', [ 530 | 'require', 531 | 'zrender/shape/Base', 532 | 'zrender/tool/util', 533 | './normalIsCover' 534 | ], function (require) { 535 | var Base = require('zrender/shape/Base'); 536 | var zrUtil = require('zrender/tool/util'); 537 | function GaugePointer(options) { 538 | Base.call(this, options); 539 | } 540 | GaugePointer.prototype = { 541 | type: 'gauge-pointer', 542 | buildPath: function (ctx, style) { 543 | var r = style.r; 544 | var width = style.width; 545 | var angle = style.angle; 546 | var x = style.x - Math.cos(angle) * width * (width >= r / 3 ? 1 : 2); 547 | var y = style.y + Math.sin(angle) * width * (width >= r / 3 ? 1 : 2); 548 | angle = style.angle - Math.PI / 2; 549 | ctx.moveTo(x, y); 550 | ctx.lineTo(style.x + Math.cos(angle) * width, style.y - Math.sin(angle) * width); 551 | ctx.lineTo(style.x + Math.cos(style.angle) * r, style.y - Math.sin(style.angle) * r); 552 | ctx.lineTo(style.x - Math.cos(angle) * width, style.y + Math.sin(angle) * width); 553 | ctx.lineTo(x, y); 554 | return; 555 | }, 556 | getRect: function (style) { 557 | if (style.__rect) { 558 | return style.__rect; 559 | } 560 | var width = style.width * 2; 561 | var xStart = style.x; 562 | var yStart = style.y; 563 | var xEnd = xStart + Math.cos(style.angle) * style.r; 564 | var yEnd = yStart - Math.sin(style.angle) * style.r; 565 | style.__rect = { 566 | x: Math.min(xStart, xEnd) - width, 567 | y: Math.min(yStart, yEnd) - width, 568 | width: Math.abs(xStart - xEnd) + width, 569 | height: Math.abs(yStart - yEnd) + width 570 | }; 571 | return style.__rect; 572 | }, 573 | isCover: require('./normalIsCover') 574 | }; 575 | zrUtil.inherits(GaugePointer, Base); 576 | return GaugePointer; 577 | }); --------------------------------------------------------------------------------