Open helgasoft opened 2 years ago
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 })
})
if you like this solution, please consider granting a Github star ⭐ to echarty.
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]])
)
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)
if you like this solution, please consider granting a Github star ⭐ to echarty.
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)
if you like this solution, please consider granting a Github star ⭐ to echarty.
@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')
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'))
))
)
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")
)
if you like this solution, please consider granting a Github star ⭐ to echarty.
That worked perfectly, thank you so much!
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')
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)
)
if you like this solution, please consider granting a Github star ⭐ to echarty.
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)
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')
@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
})
})
some less used chart types, translated to echarty from official source, for @msgoussi
# 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 )
)
# 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"
)
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 https://github.com/apache/echarts/issues/18923.
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.