Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code gists to the rescue #3

Open
helgasoft opened this issue Nov 22, 2021 · 14 comments
Open

Code gists to the rescue #3

helgasoft opened this issue Nov 22, 2021 · 14 comments

Comments

@helgasoft
Copy link
Owner

helgasoft commented Nov 22, 2021

Several programming questions have been addressed already in our Code Gists.
Gists are searchable by keyword. Example: to search for scatter in all gists - do this.

Since search is easier in Issues however, newer code snippets will mostly show up in this thread as comments.

@helgasoft helgasoft pinned this issue Nov 22, 2021
@helgasoft
Copy link
Owner Author

endLabel formatting, inquiry by @Tom-Jenkins

tmp <- read.csv('https://github.com/JohnCoene/echarts4r/files/9375371/life_continent.txt', sep='\t')
tmp |> mutate(life_expectancy= round(life_expectancy,2), year= as.factor(year)) |>
	select(year, life_expectancy, country) |>   # order x,y,grp - will be redundant in echarty 1.4.7
	group_by(country) |> 
ec.init(
	ctype='line', 
	yAxis= list(scale= TRUE), 
	grid= list(right= '28%'),
	animation= list(duration= 5000)) |> 
ec.upd({
	series <- lapply(series, function(ss) {
		ss$showSymbol <- FALSE
		ss$emphasis <- list(disable=FALSE, lineStyle= list(width= 3), focus= "self")
		ss$endLabel <- list(show= TRUE, valueAnimation= TRUE, color= 'inherit',
				offset= c(-50,11), 
				formatter= ec.clmn('%@ %L@',3,2))
	ss })
})

image
if you like this solution, please consider granting a Github star ⭐ to echarty.

@helgasoft
Copy link
Owner Author

Layout with two pie charts, inquiry by @DavZim.

library(dplyr)
df <- tibble(
	name = rep(c("v1", "v2", "v3"), 2), # pie native 'axes' are name/value
	value = c(20, 40, 40, 50, 30, 20),
	group = rep(c("A", "B"), each = 3)  # echarty currently requires group column to be last
)

library(echarty)   # v.1.4.7.01+
p <- lapply(df |> group_by(group) |> group_split(), function(x) { 
	ec.init(preset= FALSE, height= 250,
			  title= list(text= unique(x$group)), 
			  series= list(list(type= 'pie', data= ec.data(x, 'names'))),
			  legend= list(show=TRUE))
})
ec.util(p, cmd='layout', cols=2)

# try also new tabset command
htmltools::browsable(
	ec.util(cmd='tabset', tab1= p[[1]], tab2= p[[2]])
)

image

df2 <- tibble(
	group = rep(c("A", "B"), each = 100),
	time = rep(1:100, 2)
) %>% mutate(value = time + rnorm(100) + ifelse(group == "A", 10, 0)) %>% 
	select(time,value,group)

library(echarty)
lapply(df2 |> group_by(group) |> group_split(), function(gd) { 
	tmp <- lm(value ~ time, gd)
	ec.init( 
		height= 300, title= list(text= unique(gd$group)), 
		xAxis= list(show=TRUE), yAxis=list(show=TRUE),
		series= list(
			list(type= 'scatter', data= ec.data(gd[,1:2]), symbolSize=3, name='data'),
			list(type='line', data= ec.data(data.frame(gd$time, tmp$fitted.values)),
				  showSymbol= FALSE, lineStyle= list(width=1, color='red'), name='lm')
		),
		legend= list(show=TRUE))
}) |>
ec.util(cmd='layout', cols= 2)

image

if you like this solution, please consider granting a Github star ⭐ to echarty.

@helgasoft
Copy link
Owner Author

helgasoft commented Sep 14, 2022

Answer question by @kesselhwvan about duplicating a ggplot chart

#  set.seed(?)
data = tibble(time = factor(sort(rep(c(4,8,24), 30)), levels = c(4,8,24)),
	dose = factor(rep(c(1,2,3), 30), levels = c(1,2,3)),
	id = rep(sort(rep(LETTERS[1:10], 3)),3),
	y = rnorm(n = 90, mean = 5, sd = 3))

# This is the plot i am aiming to recreate:
# ggplot(data = data, mapping = aes(x = time, y = y, group = id)) + geom_point() +
#      geom_line() + facet_wrap(~dose)

remotes::install_github('helgasoft/echarty')      # get latest 1.4.7.02
library(echarty)

df <- data |> select(time,y,id,dose)	# default order for X,Y,group,etc 
lapply(unique(df$dose), function(i) 
	df |> filter(dose==i) |> group_by(id) |> 
	ec.init(ctype='line', title= list(text= i), legend= list(show=FALSE)
               ,yAxis= list(min= floor(min(df$y)), max= ceiling(max(df$y)))
               ,grid= list(containLabel= TRUE)) 
) |>
ec.util(cmd='layout', cols=3)

image
if you like this solution, please consider granting a Github star ⭐ to echarty.

@helgasoft
Copy link
Owner Author

helgasoft commented Oct 10, 2022

@XiangyunHuang, hope that's what you are looking for.
Parameter visualMap.dimension works with ECharts dataset, which is set by default in echarty.

library(echarty)
# enhance symbol size related to magnitude
quakes |> mutate(mage= ifelse(mag<5, 4, ifelse(mag<6, 10, 15))) |> 
ec.init(load='3D',
  xAxis3D= list(name= "Lat", scale=TRUE),
  yAxis3D= list(name = "Long", scale=TRUE),
  zAxis3D= list(name = "Depth"),
  series= list(list(type= 'scatter3D',
    encode= list(x= 'lat', y= 'long', z= 'depth'),
    symbolSize = ec.clmn(6),  # = mage
    name = "Fiji"
  )),
  visualMap= list(
    type = "continuous",
    # inRange = list(color = c('#4B0055', '#009B95', '#FDE333')),
    inRange = list(color = c('green', 'yellow', 'red')),
    dimension = 3, # third dimension x = 0, y = 1, z = 2, mag = 3, station = 4
    max= max(quakes$mag), min= min(quakes$mag), 
    text= c(paste('mag\n',max(quakes$mag)), min(quakes$mag)),
    top = 20, calculable= TRUE, precision= 1,
    textStyle= list(color= '#bbb')
  )
) |> ec.theme('dark-mushroom')

image

@helgasoft
Copy link
Owner Author

Numbers locale-based formatting, asked by @oobd
Done with ec.clmn() in echarty. Format %L@ stands for 'localized'.

library(dplyr); library(echarty)
iris %>%
  mutate(Petal.Length = Petal.Length * 1000) %>% 
  group_by(Species) %>% 
  summarise(Petal.Length = sum(Petal.Length)) %>% 
  ec.init(
    grid= list(containLabel= TRUE),
    series= list(list( 
      type= 'bar',
      encode= list(x= 'Petal.Length', y= 'Species'),
      label= list(show= TRUE, position= 'inside', fontSize= 10, offset= c(0, 0.5),
                  formatter= ec.clmn('%L@', 'Petal.Length'))
    ))
  )

image

@helgasoft
Copy link
Owner Author

helgasoft commented Nov 22, 2022

Simple heatmap of weekly hours, inquiry by @avenn98

set.seed(2022)
df <- data.frame(day_of_week= sample(c('Mon','Tue','Wed','Thu','Fri','Sat','Sun'),100, replace=TRUE), 
		hour_of_day= sample(5:23, 100, replace=TRUE), 
		jobs= sample(1:100, 100)) |> 
	dplyr::distinct(hour_of_day, day_of_week, .keep_all= TRUE)
df |> echarty::ec.init(
	title= list(text= "Heatmap of Successful API Requests by Day and Hour"),
	series= list(list(type= 'heatmap')),
	xAxis= list(type= 'category', data= c('Mon','Tue','Wed','Thu','Fri','Sat','Sun')),
	yAxis= list(min= min(df$hour_of_day)-1, name= 'hours', interval= 1),
	visualMap= list(calculable= TRUE, max= 100, 
		orient= 'horizontal', bottom= 'bottom', left='middle', align= 'right', 
		inRange= list(color= c('yellow','red'))),
	tooltip= list(trigger= "item")
)

image
if you like this solution, please consider granting a Github star ⭐ to echarty.

@avenn98
Copy link

avenn98 commented Nov 23, 2022

That worked perfectly, thank you so much!

@helgasoft
Copy link
Owner Author

Stacked bar chart with factor categories + colors, sample by @mmfc

library(dplyr)
ccv <- "project_id	sum	count	status
100	35	20	Accepted
100	35	14	Proposal
100	35	1	QA
107	33	8	Accepted
107	33	9	In Progress
107	33	12	Proposal
107	33	4	QA
83	20	10	Accepted
83	20	3	In Progress
83	20	7	Proposal
11	18	6	Accepted
11	18	3	In Progress
11	18	5	Proposal
11	18	4	QA
91	17	11	Accepted
91	17	4	In Progress
91	17	2	Proposal
8	15	7	Accepted
8	15	3	Аbandoned
8	15	1	Blocked"
df <- read.csv(text=ccv, sep='\t', header=T) 
df$status <- factor(df$status, levels= c('Accepted','Proposal','QA','In Progress','Blocked','Аbandoned','Reference'))

library(echarty)
df |> mutate(project_id= as.character(project_id)) |> arrange(desc(sum)) |> 
  relocate(sum, .after=last_col()) |> group_by(status) |> 
ec.init(ctype= 'bar', 
  series.param= list(stack= "stak"), tooltip= list(show=T),
  xAxis= list(type= 'category', 
              data= unique(unname(unlist(df$project_id)))),
  # 'status' colors in same (factor) order
  color= c("#FEF2C0","#BFE5BF","#D4C5F9","#a10b0b","#000000","#7F8C8D","green")
) |> ec.theme('dark-mushroom')

image

@helgasoft
Copy link
Owner Author

A solution for boxplot + data chart using helper function echarty::ec.data(format='boxplot',...)
for @lhabegger and @varunrd

library(echarty)      # use v.1.5.1+
# prepare data
ds <- iris |> dplyr::relocate(Species) |>
	ec.data(format= 'boxplot', jitter= 0.1, layout= 'v', 
	        symbolSize= 6, tooltip= list(formatter= ec.clmn('%@',2)))
# display
ec.init(
  dataset= ds$dataset, series= ds$series,xAxis= ds$xAxis, yAxis= ds$yAxis,
  legend= list(show= T), tooltip= list(show= T)
)

image
if you like this solution, please consider granting a Github star ⭐ to echarty.

@helgasoft
Copy link
Owner Author

Make data.tree acme dataset show as sunburst chart, for @GillesSanMartin.
See also various hierarchical structures for echarty explained.

library(data.tree)
tmp <- acme
tmp$Do(function(x) x$value <- x$cost)  # add 'value' for sunburst
lst <- tmp |> ToListExplicit(unname = TRUE)

library(echarty)
p1 <- ec.init(
	series= list(list(
           # data=list(lst) is ok too, but children are not colored
           #type= 'treemap', data= lst$children) 
            type= 'sunburst', data= lst$children, 
               radius= list(0, '90%'), label= list(rotate='radial')))
)
p2 <- ec.init(width=300, series= list(list(type= 'tree', data= list(lst))))
ec.util(list(p1,p2), cmd='layout', cols=2)

image

@helgasoft
Copy link
Owner Author

New in version 1.6.0 - save complete chart to file, show local or remote charts.
@rdatasculptor will like it

remotes::install_github('helgasoft/echarty')    # get latest v.1.6.0
library(echarty)

# build a chart with custom Javascript handlers
js = "chart.getZr().on('contextmenu', x => {chart.setOption({title:{text:'right-clicked'}}) })"
p <- cars |> ec.init(js= js, dataZoom= list(type='inside'))
p$x$on = list(
    list(event= 'datazoom', 
         handler= ec.clmn("function() {this.setOption({title:{text:'zoomed'}});}") )
)

# save chart to local file
p |> ec.inspect(target='full', file='c:/temp/tcar.txt')
# file could now be uploaded to net

# read local file and show chart
con <- file('c:/temp/tcar.txt','rb')
ec.fromJson(con); close(con)

# show a remote chart
echarty::ec.fromJson('https://helgasoft.github.io/echarty/test/pfull.json')

@helgasoft
Copy link
Owner Author

@pizifan, an complex example indeed from ECharts.
But echarty can handle it. Currently tl.series supports a single serie, but more can be added thru ec.upd().
Notice that list attributes are straight from ECharts API.

remotes::install_github('helgasoft/echarty')  # get latest!
library(echarty)

tmp <- as.data.frame(jsonlite::fromJSON('https://echarts.apache.org/examples/data/asset/data/life-expectancy-table.json'))
colnames(tmp) <- tmp[1,]
df <- tmp[-1,]
df <- df |> mutate(across(.cols= -c(Country), as.numeric)) |> 
  filter(Year %in% c(1985,2000,2015), Country %in% c('Canada','France','Turkey'))
clr <- ec.clmn("(p) => { return p.dataIndex==0 ? 'violet' : p.dataIndex==1 ? 'orange' : 'brown' }")

df |> group_by(Year) |> 
ec.init(
  yAxis= list(list(name='income', max=45000), 
              list(name='life', max=85)),
  tl.series= list(type='bar', name='income',
                  encode= list(x='Country', y='Income')),
  tooltip= list(show=T), 
  legend= list(data= c('income','life','pop.'))
) |> 
ec.upd({
  options <- lapply(options, \(oo) {
    dix <- oo$series[[1]]$datasetIndex  # from tl.series (bar)
    oo$series <- append(oo$series, 
      list(
        list(type='bar', name='life', yAxisIndex=1, 
             datasetIndex= dix,
             encode= list(x='Country', y='Life Expectancy')),
        list(type='pie', name='pop.', itemStyle= list(color=clr),
             datasetIndex= dix,
             encode= list(value='Population', itemName='Country'), 
             center= c('75%', '25%'), radius= '20%', 
             label= list(show=T), labelLine= list(length=5, length2=0))
    ))
    oo
  })
})

image

@helgasoft
Copy link
Owner Author

some less used chart types, translated to echarty from official source, for @msgoussi

waterfall

# original https://echarts.apache.org/examples/en/editor.html?c=bar-waterfall2
xdat <- paste('Nov',1:11)
jscode <- htmlwidgets::JS("function(params) {
  let tar;
  if (params[1] && params[1].value !== '-') {
    tar = params[1];
  } else {
    tar = params[2];
  }
  return tar && tar.name + '<br/>' + tar.seriesName + ' : ' + tar.value;
}")

ec.init(
  title=list(text='Accumulated Waterfall Chart'),
  legend= list(show=T),
  grid= list(left='3%',right='4%',bottom='3%',containLabel=TRUE),
  xAxis=list(type='category', data=xdat),
  yAxis=list(type='value'),
  series=list(
    list(type='bar',stack='Total',silent=TRUE,  #Placeholder
         itemStyle=list(borderColor='transparent',color='transparent'),
         emphasis=list(itemStyle=list(borderColor='transparent',color='transparent')),
         data=list(0, 900, 1245, 1530, 1376, 1376, 1511, 1689, 1856, 1495, 1292)),
    list(name='Income',type='bar',stack='Total',label=list(show=TRUE,position='top'),
         data=list(900, 345, 393, '-', '-', 135, 178, 286, '-', '-', '-')),
    list(name='Expenses',type='bar',stack='Total',label=list(show=TRUE,position='bottom'),
         data=list('-', '-', '-', 108, 154, '-', '-', '-', 119, 361, 203))),
  tooltip=list(trigger='axis', axisPointer=list(type='shadow'), 
               formatter= jscode )
)

image

bar race

# original https://echarts.apache.org/examples/en/editor.html?c=bar-race
data <- round(runif(5,1, 200))
js <- paste0("
const data=[",paste(data,collapse=","),"];
function run() {
  for (var i = 0; i < data.length; ++i) {
    if (Math.random() > 0.9) {
      data[i] += Math.round(Math.random() * 2000);
    } else {
      data[i] += Math.round(Math.random() * 200);
    }
  }
  chart.setOption({ series: [{type: 'bar', data}] });
}
setTimeout(function () { run(); }, 0);
setInterval(function () { run();}, 3000);"
)

ec.init( js= js,
  xAxis = list(max = "dataMax"), 
  yAxis = list(type = "category", data = list("A","B","C","D","E"), inverse = TRUE, 
               animationDuration = 300, animationDurationUpdate = 300), 
  series = list(
    list(realtimeSort= TRUE, type= "bar", 
         data= data, colorBy= 'data',
         label= list(show= TRUE, position= "right", valueAnimation= TRUE))), 
  animationDuration= 0, animationDurationUpdate= 2000, 
  animationEasing= "linear", animationEasingUpdate= "linear"
) 

image

@helgasoft
Copy link
Owner Author

New extras function 💲 to build a two-level axis, with responsive auto-resize.
Currently coded in Javascript, but usable with ec.init. R-code version planned also.
Often used to present category groups, see apache/echarts#18923.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants