mirror of
https://shylinux.com/x/icebergs
synced 2025-04-25 17:18:05 +08:00
opt some
This commit is contained in:
parent
87b675d294
commit
1ef53c5610
92
core/wiki/chart/block.go
Normal file
92
core/wiki/chart/block.go
Normal file
@ -0,0 +1,92 @@
|
||||
package chart
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/core/wiki"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Block struct {
|
||||
Text string
|
||||
FontSize int
|
||||
FontColor string
|
||||
BackGround string
|
||||
|
||||
TextData string
|
||||
RectData string
|
||||
|
||||
Padding int
|
||||
MarginX int
|
||||
MarginY int
|
||||
|
||||
Height int
|
||||
Width int
|
||||
x, y int
|
||||
}
|
||||
|
||||
func (b *Block) Init(m *ice.Message, arg ...string) wiki.Chart {
|
||||
b.FontSize = kit.Int(kit.Select("24", m.Option(wiki.FONT_SIZE)))
|
||||
b.Padding = kit.Int(kit.Select("10", m.Option(wiki.PADDING)))
|
||||
b.MarginX = kit.Int(kit.Select("10", m.Option(wiki.MARGINX)))
|
||||
b.MarginY = kit.Int(kit.Select("10", m.Option(wiki.MARGINY)))
|
||||
|
||||
if len(arg) > 0 {
|
||||
b.Text = arg[0]
|
||||
}
|
||||
return b
|
||||
}
|
||||
func (b *Block) Data(m *ice.Message, meta interface{}) wiki.Chart {
|
||||
b.Text = kit.Select(b.Text, kit.Value(meta, kit.MDB_TEXT))
|
||||
kit.Fetch(meta, func(key string, value string) {
|
||||
switch key {
|
||||
case wiki.FG:
|
||||
b.TextData += kit.Format("%s='%s' ", wiki.FILL, value)
|
||||
case wiki.BG:
|
||||
b.RectData += kit.Format("%s='%s' ", wiki.FILL, value)
|
||||
}
|
||||
})
|
||||
kit.Fetch(kit.Value(meta, "data"), func(key string, value string) {
|
||||
b.TextData += kit.Format("%s='%s' ", key, value)
|
||||
})
|
||||
kit.Fetch(kit.Value(meta, "rect"), func(key string, value string) {
|
||||
b.RectData += kit.Format("%s='%s' ", key, value)
|
||||
})
|
||||
return b
|
||||
}
|
||||
func (b *Block) Draw(m *ice.Message, x, y int) wiki.Chart {
|
||||
float := 3
|
||||
if strings.Contains(m.Option(ice.MSG_USERUA), "iPhone") {
|
||||
float += 0
|
||||
}
|
||||
if m.Option(HIDE_BLOCK) != ice.TRUE {
|
||||
item := wiki.NewItem([]string{`<rect height="%d" width="%d" rx="4" ry="4" x="%d" y="%d"`}, b.GetHeight(), b.GetWidth(), x+b.MarginX/2, y+b.MarginY/2)
|
||||
item.Push(`fill="%s"`, b.BackGround).Push(`%v`, b.RectData).Echo("/>").Dump(m)
|
||||
}
|
||||
item := wiki.NewItem([]string{`<text x="%d" y="%d"`}, x+b.GetWidths()/2, y+b.GetHeights()/2+float)
|
||||
item.Push(`stroke="%s"`, b.FontColor).Push(`fill="%s"`, b.FontColor).Push("%v", b.TextData).Push(`>%v</text>`, b.Text).Dump(m)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *Block) GetHeight(str ...string) int {
|
||||
if b.Height != 0 {
|
||||
return b.Height
|
||||
}
|
||||
return b.FontSize + b.Padding
|
||||
}
|
||||
func (b *Block) GetWidth(str ...string) int {
|
||||
if b.Width != 0 {
|
||||
return b.Width
|
||||
}
|
||||
s := kit.Select(b.Text, str, 0)
|
||||
cn := (len(s) - len([]rune(s))) / 2
|
||||
en := len([]rune(s)) - cn
|
||||
return cn*b.FontSize + en*b.FontSize*10/16 + b.Padding
|
||||
}
|
||||
func (b *Block) GetWidths(str ...string) int {
|
||||
return b.GetWidth(str...) + b.MarginX
|
||||
}
|
||||
func (b *Block) GetHeights(str ...string) int {
|
||||
return b.GetHeight() + b.MarginY
|
||||
}
|
120
core/wiki/chart/chain.go
Normal file
120
core/wiki/chart/chain.go
Normal file
@ -0,0 +1,120 @@
|
||||
package chart
|
||||
|
||||
import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/core/wiki"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Chain struct {
|
||||
data map[string]interface{}
|
||||
Group *wiki.Group
|
||||
Block
|
||||
}
|
||||
|
||||
func (c *Chain) Init(m *ice.Message, arg ...string) wiki.Chart {
|
||||
(&c.Block).Init(m)
|
||||
|
||||
// 解析数据
|
||||
m.Option(nfs.CAT_CONTENT, arg[0])
|
||||
m.Option(lex.SPLIT_SPACE, "\t \n")
|
||||
m.Option(lex.SPLIT_BLOCK, "\t \n")
|
||||
c.data = lex.Split(m, "", kit.MDB_TEXT)
|
||||
|
||||
// 计算尺寸
|
||||
c.Height = c.size(m, c.data) * c.GetHeights()
|
||||
c.Draw(m, 0, 0)
|
||||
c.Width += 200
|
||||
m.Set(ice.MSG_RESULT)
|
||||
return c
|
||||
}
|
||||
func (c *Chain) Draw(m *ice.Message, x, y int) wiki.Chart {
|
||||
c.Group = wiki.NewGroup(m, SHIP)
|
||||
defer c.Group.Dump(m, SHIP)
|
||||
c.draw(m, c.data, x, y, &c.Block)
|
||||
return c
|
||||
}
|
||||
func (c *Chain) size(m *ice.Message, root map[string]interface{}) (height int) {
|
||||
meta := kit.GetMeta(root)
|
||||
if list, ok := root[kit.MDB_LIST].([]interface{}); ok && len(list) > 0 {
|
||||
kit.Fetch(root[kit.MDB_LIST], func(index int, value map[string]interface{}) {
|
||||
height += c.size(m, value)
|
||||
})
|
||||
} else {
|
||||
height = 1
|
||||
}
|
||||
meta[wiki.HEIGHT] = height
|
||||
return height
|
||||
}
|
||||
func (c *Chain) draw(m *ice.Message, root map[string]interface{}, x, y int, p *Block) int {
|
||||
meta := kit.GetMeta(root)
|
||||
c.Height, c.Width = 0, 0
|
||||
|
||||
if kit.Format(meta[wiki.FG]) != "" {
|
||||
items := wiki.NewItem([]string{"<g"})
|
||||
items.Push("stroke=%s", meta[wiki.FG])
|
||||
items.Push("fill=%s", meta[wiki.FG])
|
||||
items.Echo(">").Dump(m)
|
||||
defer m.Echo("</g>")
|
||||
}
|
||||
|
||||
// 当前节点
|
||||
item := &Block{
|
||||
FontSize: p.FontSize,
|
||||
Padding: p.Padding,
|
||||
MarginX: p.MarginX,
|
||||
MarginY: p.MarginY,
|
||||
}
|
||||
item.x, item.y = x, y+(kit.Int(meta[wiki.HEIGHT])-1)*c.GetHeights()/2
|
||||
item.Init(m, kit.Format(meta[kit.MDB_TEXT])).Data(m, meta)
|
||||
item.Draw(m, item.x, item.y)
|
||||
|
||||
// 画面尺寸
|
||||
if item.y+item.GetHeight()+c.MarginY > c.Height {
|
||||
c.Height = item.y + item.GetHeight() + c.MarginY
|
||||
}
|
||||
if item.x+item.GetWidth()+c.MarginX > c.Width {
|
||||
c.Width = item.x + item.GetWidth() + c.MarginX
|
||||
}
|
||||
|
||||
// 模块连线
|
||||
if p != nil && p.y != 0 {
|
||||
x1, y1 := p.x+p.GetWidths()-(p.MarginX+item.MarginX)/4, p.y+p.GetHeights()/2
|
||||
x4, y4 := item.x+(p.MarginX+item.MarginX)/4, item.y+item.GetHeights()/2
|
||||
c.Group.Echo(SHIP, `<path d="M %d,%d Q %d,%d %d,%d T %d %d"></path>`,
|
||||
x1, y1, x1+(x4-x1)/4, y1, x1+(x4-x1)/2, y1+(y4-y1)/2, x4, y4)
|
||||
}
|
||||
|
||||
// 递归节点
|
||||
h, x := 0, x+item.GetWidths()
|
||||
if kit.Fetch(root[kit.MDB_LIST], func(index int, value map[string]interface{}) {
|
||||
h += c.draw(m, value, x, y+h, item)
|
||||
}); h == 0 {
|
||||
return item.GetHeights()
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
const (
|
||||
SHIP = "ship"
|
||||
|
||||
HIDE_BLOCK = "hide-block"
|
||||
)
|
||||
const CHAIN = "chain"
|
||||
|
||||
func init() {
|
||||
wiki.AddChart(CHAIN, func(m *ice.Message) wiki.Chart {
|
||||
m.Option(wiki.STROKE_WIDTH, "1")
|
||||
m.Option(wiki.FILL, cli.BLUE)
|
||||
m.Option(wiki.MARGINX, "40")
|
||||
m.Option(wiki.MARGINY, "0")
|
||||
|
||||
m.Option(COMPACT, ice.TRUE)
|
||||
m.Option(HIDE_BLOCK, ice.TRUE)
|
||||
wiki.AddGroupOption(m, SHIP, wiki.STROKE_WIDTH, "1", wiki.STROKE, cli.CYAN, wiki.FILL, "none")
|
||||
return &Chain{}
|
||||
})
|
||||
}
|
87
core/wiki/chart/label.go
Normal file
87
core/wiki/chart/label.go
Normal file
@ -0,0 +1,87 @@
|
||||
package chart
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/core/wiki"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
data [][]string
|
||||
max map[int]int
|
||||
Block
|
||||
}
|
||||
|
||||
func (l *Label) Init(m *ice.Message, arg ...string) wiki.Chart {
|
||||
(&l.Block).Init(m)
|
||||
|
||||
// 解析数据
|
||||
l.max = map[int]int{}
|
||||
for _, v := range strings.Split(arg[0], ice.NL) {
|
||||
ls := kit.Split(v, ice.SP, ice.SP)
|
||||
l.data = append(l.data, ls)
|
||||
|
||||
for i, v := range ls {
|
||||
switch data := kit.Parse(nil, "", kit.Split(v)...).(type) {
|
||||
case map[string]interface{}:
|
||||
v = kit.Select("", data[kit.MDB_TEXT])
|
||||
}
|
||||
if w := l.GetWidth(v); w > l.max[i] {
|
||||
l.max[i] = w
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 计算尺寸
|
||||
l.Height = len(l.data) * l.GetHeights()
|
||||
for _, v := range l.max {
|
||||
l.Width += v + l.MarginX
|
||||
}
|
||||
return l
|
||||
}
|
||||
func (l *Label) Draw(m *ice.Message, x, y int) wiki.Chart {
|
||||
var item *Block
|
||||
top := y
|
||||
for _, line := range l.data {
|
||||
left := x
|
||||
for i, text := range line {
|
||||
|
||||
// 数据
|
||||
item = &Block{FontSize: l.FontSize, Padding: l.Padding, MarginX: l.MarginX, MarginY: l.MarginY}
|
||||
switch data := kit.Parse(nil, "", kit.Split(text)...).(type) {
|
||||
case map[string]interface{}:
|
||||
item.Init(m, kit.Select(text, data[kit.MDB_TEXT])).Data(m, data)
|
||||
default:
|
||||
item.Init(m, text)
|
||||
}
|
||||
|
||||
// 输出
|
||||
switch m.Option(COMPACT) {
|
||||
case "max":
|
||||
item.Width = l.Width/len(line) - l.MarginX
|
||||
case ice.TRUE:
|
||||
|
||||
default:
|
||||
item.Width = l.max[i]
|
||||
}
|
||||
item.Draw(m, left, top)
|
||||
|
||||
left += item.GetWidths()
|
||||
}
|
||||
top += item.GetHeights()
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
const (
|
||||
COMPACT = "compact"
|
||||
)
|
||||
const LABEL = "label"
|
||||
|
||||
func init() {
|
||||
wiki.AddChart(LABEL, func(m *ice.Message) wiki.Chart {
|
||||
return &Label{}
|
||||
})
|
||||
}
|
156
core/wiki/chart/sequence.go
Normal file
156
core/wiki/chart/sequence.go
Normal file
@ -0,0 +1,156 @@
|
||||
package chart
|
||||
|
||||
import (
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/core/wiki"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type Sequence struct {
|
||||
Head []string
|
||||
List [][]map[string]interface{}
|
||||
pos []int
|
||||
Block
|
||||
}
|
||||
|
||||
func (s *Sequence) push(m *ice.Message, list string, arg ...interface{}) map[string]interface{} {
|
||||
node, node_list := kit.Dict(arg...), kit.Int(list)
|
||||
s.List[node_list] = append(s.List[node_list], node)
|
||||
_max := kit.Max(len(s.List[node_list])-1, s.pos[node_list])
|
||||
node[kit.MDB_ORDER], s.pos[node_list] = _max, _max+1
|
||||
return node
|
||||
}
|
||||
func (s *Sequence) Init(m *ice.Message, arg ...string) wiki.Chart {
|
||||
(&s.Block).Init(m)
|
||||
|
||||
// 解析数据
|
||||
m.Cmd(lex.SPLIT, "", kit.Dict(nfs.CAT_CONTENT, arg[0]), func(ls []string, data map[string]interface{}) []string {
|
||||
if len(s.Head) == 0 {
|
||||
s.Head, s.pos = ls, make([]int, len(ls))
|
||||
for i := 0; i < len(ls); i++ {
|
||||
s.List = append(s.List, []map[string]interface{}{})
|
||||
}
|
||||
return ls
|
||||
}
|
||||
|
||||
from_node := s.push(m, ls[0])
|
||||
list := map[string]map[string]interface{}{ls[0]: from_node}
|
||||
for i := 1; i < len(ls)-1; i += 2 {
|
||||
to_node := list[ls[i+1]]
|
||||
if to_node == nil {
|
||||
to_node = s.push(m, ls[i+1])
|
||||
list[ls[i+1]] = to_node
|
||||
|
||||
_max := kit.Max(kit.Int(from_node[kit.MDB_ORDER]), kit.Int(to_node[kit.MDB_ORDER]))
|
||||
s.pos[kit.Int(ls[i-1])], s.pos[kit.Int(ls[i+1])] = _max+1, _max+1
|
||||
from_node[kit.MDB_ORDER], to_node[kit.MDB_ORDER] = _max, _max
|
||||
from_node[kit.MDB_TEXT], from_node[kit.MDB_NEXT] = ls[i], ls[i+1]
|
||||
} else {
|
||||
from_node[kit.MDB_ECHO], from_node[kit.MDB_PREV] = ls[i], ls[i+1]
|
||||
}
|
||||
from_node = to_node
|
||||
}
|
||||
return ls
|
||||
})
|
||||
|
||||
// 计算尺寸
|
||||
width := 0
|
||||
for _, v := range s.Head {
|
||||
width += s.Block.GetWidths(v)
|
||||
}
|
||||
rect_height := kit.Int(m.Option(RECT + "-" + wiki.HEIGHT))
|
||||
s.Width, s.Height = width, kit.Max(s.pos...)*(rect_height+s.MarginY)+s.MarginY+s.GetHeights()
|
||||
return s
|
||||
}
|
||||
func (s *Sequence) Draw(m *ice.Message, x, y int) wiki.Chart {
|
||||
g := wiki.NewGroup(m, ARROW, HEAD, LINE, RECT, NEXT, PREV, TEXT, ECHO)
|
||||
arrow_height := kit.Int(g.Option(ARROW, wiki.HEIGHT))
|
||||
arrow_width := kit.Int(g.Option(ARROW, wiki.WIDTH))
|
||||
rect_height := kit.Int(g.Option(RECT, wiki.HEIGHT))
|
||||
rect_width := kit.Int(g.Option(RECT, wiki.WIDTH))
|
||||
g.DefsArrow(NEXT, arrow_height, arrow_width)
|
||||
|
||||
height := s.Height
|
||||
s.Block.Height, s.Block.Width = 0, 0
|
||||
line_pos := make([]int, len(s.List))
|
||||
for i := range s.List {
|
||||
s.Block.Text = s.Head[i]
|
||||
s.Block.Draw(g.Get(HEAD), x, y)
|
||||
line_pos[i], x = x+s.Block.GetWidths()/2, x+s.Block.GetWidths()
|
||||
}
|
||||
|
||||
y += s.Block.GetHeight() + s.MarginY/2
|
||||
for _, x := range line_pos {
|
||||
g.EchoLine(LINE, x, y, x, height-s.MarginY/2)
|
||||
}
|
||||
|
||||
for i, x := range line_pos {
|
||||
for _, v := range s.List[i] {
|
||||
pos := kit.Int(v[kit.MDB_ORDER])
|
||||
g.EchoRect(RECT, rect_height, rect_width, x-rect_width/2, y+pos*(rect_height+s.MarginY)+s.MarginY, "2", "2")
|
||||
|
||||
yy := y + pos*(rect_height+s.MarginY) + s.MarginY + rect_height/4
|
||||
if kit.Format(v[kit.MDB_NEXT]) != "" {
|
||||
xx := line_pos[kit.Int(v[kit.MDB_NEXT])]
|
||||
if x < xx {
|
||||
g.EchoArrowLine(NEXT, x+rect_width/2, yy, xx-rect_width/2-arrow_width, yy)
|
||||
} else {
|
||||
g.EchoArrowLine(NEXT, x-rect_width/2, yy, xx+rect_width/2+arrow_width, yy)
|
||||
}
|
||||
g.EchoText(TEXT, (x+xx)/2, yy, kit.Format(v[kit.MDB_TEXT]))
|
||||
}
|
||||
|
||||
yy += rect_height / 2
|
||||
if kit.Format(v[kit.MDB_PREV]) != "" {
|
||||
xx := line_pos[kit.Int(v[kit.MDB_PREV])]
|
||||
if x < xx {
|
||||
g.EchoArrowLine(PREV, x+rect_width/2, yy, xx-rect_width/2-arrow_width, yy)
|
||||
} else {
|
||||
g.EchoArrowLine(PREV, x-rect_width/2, yy, xx+rect_width/2+arrow_width, yy)
|
||||
}
|
||||
g.EchoText(ECHO, (x+xx)/2, yy, kit.Format(v[kit.MDB_ECHO]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g.Dump(m, HEAD).Dump(m, LINE)
|
||||
g.Dump(m, RECT).Dump(m, NEXT).Dump(m, PREV)
|
||||
g.Dump(m, TEXT).Dump(m, ECHO)
|
||||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
ARROW = "arrow"
|
||||
|
||||
HEAD = "head"
|
||||
LINE = "line"
|
||||
RECT = "rect"
|
||||
NEXT = "next"
|
||||
PREV = "prev"
|
||||
TEXT = "text"
|
||||
ECHO = "echo"
|
||||
)
|
||||
|
||||
const SEQUENCE = "sequence"
|
||||
|
||||
func init() {
|
||||
wiki.AddChart(SEQUENCE, func(m *ice.Message) wiki.Chart {
|
||||
m.Option(wiki.MARGINX, "60")
|
||||
m.Option(wiki.MARGINY, "20")
|
||||
m.Option(wiki.STROKE_WIDTH, "1")
|
||||
m.Option(wiki.STROKE, cli.WHITE)
|
||||
m.Option(wiki.FILL, cli.WHITE)
|
||||
wiki.AddGroupOption(m, ARROW, wiki.HEIGHT, "8", wiki.WIDTH, "18", wiki.FILL, cli.GLASS)
|
||||
wiki.AddGroupOption(m, HEAD, wiki.FILL, cli.GLASS)
|
||||
wiki.AddGroupOption(m, LINE, wiki.STROKE_DASHARRAY, "20 4 4 4")
|
||||
wiki.AddGroupOption(m, RECT, wiki.HEIGHT, "40", wiki.WIDTH, "14")
|
||||
wiki.AddGroupOption(m, NEXT, wiki.FILL, cli.GLASS)
|
||||
wiki.AddGroupOption(m, PREV, wiki.STROKE_DASHARRAY, "10 2")
|
||||
wiki.AddGroupOption(m, TEXT, wiki.FONT_SIZE, "16")
|
||||
wiki.AddGroupOption(m, ECHO, wiki.FONT_SIZE, "12")
|
||||
return &Sequence{}
|
||||
})
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user