第五次作业

维基百科可视化山寨

输入数据:

a <- read.table(file("graph_1.dat"), header = TRUE, sep=":"); a
##   no.    name wc                                                     cont
## 1   1    mary 10                                                mary;10;1
## 2   2 suzanne 15                                    mary,suzanne;10,5;2,1
## 3   3  martin 11                    mary,martin,-,suzanne;4,2,6,5;3,1,0,2
## 4   4 suzanne 13 mary,suzanne,mary,martin,suzanne;1.5,2,2.5,2,5;4,1,4,2,3
men <- levels(a$name); # 版本发布人
total <- max(a$wc);    # 最大版本内容

绘图

# 画布要素全局设置
par(lwd = 5, bg = "#3D3D3DFF", mai = c(0, 0, 0, 0), omi = c(0, 0, 0, 0))
color <- c("#5FD213FF", "#FD5800FF", "#129DF0FF")
color_step <- 20  # 设定版本颜色渐变的步长
palette(color)

paint_area <- T  # 控制是否输出关联区域绘图

# 根据版本内容设定坐标系的大小
height <- max(total + 1)
width <- max(a$no.)

plot(0, 0, type = "n", col = 1, xlim = c(-0.5, width + 0.3), ylim = c(0, height + 
    1))

# 对第一次版本处理
ac <- strsplit(as.character(a$cont[1]), ";")
x <- c(1, 1)
y <- c(height, height - as.numeric(ac[[1]][2]))
lines(x, y, col = which(men == ac[[1]][1]))
text(1, height + 1, paste("version", 1), col = "white")

# 开始绘图
for (i in 2:width) {
    #
    # 分解数据:其中ac_men表示版本人,ac_word表示版本内容长度,ac_sc表示版本的历史修改步长
    # 技巧:ac_sc中(0,1)2个数字在程序中做了特殊处理 0 表示删除,1 表示新增

    ac <- strsplit(as.character(a$cont[i]), ";")
    ac_men <- strsplit(ac[[1]][1], ",")[[1]]
    ac_word <- as.numeric(strsplit(ac[[1]][2], ",")[[1]])
    ac_sc <- as.integer(strsplit(ac[[1]][3], ",")[[1]])

    hy1 <- 0
    hy2 <- height
    py1 <- 0
    py2 <- height
    text(i, height + 1, paste("version", i), col = "white")
    j <- 1
    while (j <= length(ac_men)) {
        if (ac_sc[j] == 0) {
            # 当版本中存在删除的内容时,不绘制这部分内容的背景图,即不绘制多边形
            # ,通过移动Y坐标的值来达到。
            py2 <- py2 - ac_word[j]
        } else {
            x <- c(i, i)
            hy1 <- hy2 - ac_word[j]
            y <- c(hy2, hy1)
            # 对于新增的和旧版本,绘制线段图
            lines(x, y, col = which(men == ac_men[j]))
            py1 <- py2 - ac_word[j]

            # 只有版本是历史版本的时候,执行这一步,也就是版本的历史修改>1的情况
            if (ac_sc[j] > 1 && paint_area) {
                xx <- c(i, i, i - 1, i - 1, i)
                yy <- c(hy2, hy1, py1, py2, hy2)
                col2 <- color[which(men == ac_men[j])]
                col3 <- as.integer(paste("0x", substr(col2, 8, 9), sep = "")) - 
                  color_step * i
                col2 <- paste(substr(col2, 1, 7), toupper(as.hexmode(col3)), 
                  sep = "")

                polygon(xx, yy, col = col2, border = NA)
                py2 <- py1
            }
            hy2 <- hy1
        }
        j <- j + 1
    }
}

# 输出版本发布人姓名
x <- -0.5
y <- 2
h <- 0.9
for (m in c("mary", "suzanne", "martin")) {
    text(x, y, m, col = grep(m, men), adj = c(0, NA))
    y <- y - h
}

plot of chunk unnamed-chunk-2

Referenced many idea dataguru