Просмотр исходного кода

SVI Переделка кода

SVI 1 неделя назад
Родитель
Сommit
86395d4cdc

+ 1 - 1
lev0/types/iactor.go

@@ -3,5 +3,5 @@ package types
 // IActor -- интерфейс актора
 type IActor interface {
 	IElemBase
-	IElemUseGroupLink
+	IElemGroupLink
 }

+ 11 - 0
lev0/types/idrawer.go

@@ -0,0 +1,11 @@
+package types
+
+import (
+	svg "github.com/ajstarks/svgo"
+)
+
+// IDrawer -- интерфейс рисовальщик элемента
+type IDrawer interface {
+	// Draw -- рисует себя на холсте
+	Draw(canvas *svg.SVG)
+}

+ 0 - 14
lev0/types/ielem_drawer.go

@@ -1,14 +0,0 @@
-package types
-
-import (
-	svg "github.com/ajstarks/svgo"
-
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
-)
-
-// IElemDrawer -- интерфейс элемента схемы для рисования
-type IElemDrawer interface {
-	IElemUseGroupLink
-	// Draw -- рисует с контролем источника и получателя
-	Draw(canvas *svg.SVG, elem map[alias.Id]IElemDrawer)
-}

+ 2 - 2
lev0/types/ielem_use_group_link.go → lev0/types/ielem_group_link.go

@@ -2,8 +2,8 @@ package types
 
 import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 
-// IElemUseGroupLink -- интерфейс группы ссылок
-type IElemUseGroupLink interface {
+// IElemGroupLink -- интерфейс группы ссылок
+type IElemGroupLink interface {
 	IElemBase
 	// Links -- ссылки актора
 	Links() []alias.Id

+ 1 - 0
lev0/types/ielem_label.go

@@ -7,6 +7,7 @@ import (
 // IElemLabel -- надпись
 type IElemLabel interface {
 	IElemBase
+	IDrawer
 	// Get -- возвращает метку
 	Get() alias.Label
 	// String -- возвращает строку

+ 3 - 1
lev0/types/ielem_use_case.go

@@ -6,5 +6,7 @@ import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 type IElemUseCase interface {
 	IElemBase
 	// Links -- ссылки вариантов использования
-	Links() []alias.Id
+	Links() map[alias.Id]IElemLinker
+	// Label -- метка варианта использования
+	Label() IElemLabel
 }

+ 12 - 0
lev0/types/ielem_use_group.go

@@ -0,0 +1,12 @@
+package types
+
+import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
+
+// IElemUseGroup -- интерфейс группы вариантов использования
+type IElemUseGroup interface {
+	IElemBase
+	// Links -- заглушка на связи между объектами
+	Links() []alias.Id
+	// Size -- возвращает размер
+	Size() ISize
+}

+ 2 - 2
lev0/types/ioffset.go

@@ -10,6 +10,6 @@ type IOffset interface {
 	Y() alias.CoordY
 	// Int -- возвращает смещение
 	Int() (int, int)
-	// Val -- возвращает смещение
-	Val() (alias.CoordX, alias.CoordY)
+	// Get -- возвращает смещение
+	Get() (alias.CoordX, alias.CoordY)
 }

+ 17 - 0
lev0/types/isize.go

@@ -0,0 +1,17 @@
+package types
+
+import "gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
+
+// ISize -- интерфейс для размера
+type ISize interface{
+	// Get -- возвращает размер
+	Get() (alias.SizeX, alias.SizeY)
+	// Int -- возвращает размер
+	Int()(int,int)
+	// W -- возвращает размер по Х
+	W() alias.SizeX
+	// H -- возвращает размер по Y
+	H() alias.SizeY
+	// SelfCheck -- проверяет корректность размера
+	SelfCheck()
+}

+ 15 - 3
lev1/elem_label/elem_label.go

@@ -2,10 +2,12 @@
 package elem_label
 
 import (
+	svg "github.com/ajstarks/svgo"
+	"gitp78su.ipnodns.ru/svi/kern/v3"
+
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
-	"gitp78su.ipnodns.ru/svi/kern/v3"
 )
 
 // ElemLabel -- текстовая метка для отображения
@@ -20,7 +22,7 @@ var (
 )
 
 // NewElemLabel -- возвращает новую метку
-func NewElemLabel(label alias.Label, coord  types.ICoord, offset types.IOffset) types.IElemLabel {
+func NewElemLabel(label alias.Label, coord types.ICoord, offset types.IOffset) types.IElemLabel {
 	sf := &ElemLabel{
 		IElemBase: elem_base.NewElemBase(coord, "elem_label"),
 		Val_:      label,
@@ -30,6 +32,17 @@ func NewElemLabel(label alias.Label, coord  types.ICoord, offset types.IOffset)
 	return sf
 }
 
+// Draw -- отрисовка метки
+func (sf *ElemLabel) Draw(canvas *svg.SVG) {
+	strLabel := sf.String()
+	if strLabel != "" {
+		x, y := sf.Offset_.Int()
+		offX := int(sf.Offset_.X())
+		canvas.Text(x+offX, y-8, strLabel,
+			"font-size: 14px; font-family: Courier; fill: black")
+	}
+}
+
 // SelfCheck -- самопроверка типа
 func (sf *ElemLabel) SelfCheck() {
 	sf.IElemBase.SelfCheck()
@@ -43,7 +56,6 @@ func (sf *ElemLabel) String() string {
 	return string(sf.Val_)
 }
 
-
 // Get -- возвращает метку
 //
 //go:fix inline

+ 78 - 0
lev1/elem_use_case/elem_use_case.go

@@ -0,0 +1,78 @@
+// package elem_use_case -- вариант использования
+package elem_use_case
+
+import (
+	"fmt"
+
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
+	"gitp78su.ipnodns.ru/svi/kern/v3"
+)
+
+// UseCase -- вариант использования
+type UseCase struct {
+	types.IElemBase
+	Size_  types.ISize                       `yaml:"size"`
+	Links_ map[alias.Id]types.IElemGroupLink `yaml:"links"` // Список ссылок
+}
+
+var (
+	hassert = kern.GetFnHassert()
+)
+
+// NewUseCase -- возвращает новый вариант использования
+func NewUseCase(elemBase types.IElemBase, size types.ISize,
+	links map[alias.Id]types.IElemGroupLink) *UseCase {
+	// id := elemBase.Id()
+	// _links0, isOk := elemBase.Elem_["links"]
+	// hassert(isOk, "NewUseCase(): id=%q, links not found", id)
+	// _links, isOk := _links0.([]interface{})
+	// hassert(isOk, "NewUseCase(): id=%q, `links`(%+v) not []interface{}", id, _links0)
+	// for _, _id := range _links {
+	// 	id0, isOk := _id.(string)
+	// 	hassert(isOk, "NewUseCase(): id=%q, `link`(%T, %+v) not string", id, _id, _id)
+	// 	id1 := alias.Id(id0)
+	// 	hassert(id1 != "", "NewUseCase(): id=%q, `link` is empty", id)
+	// 	links = append(links, id1)
+	// }
+	sf := &UseCase{
+		IElemBase: elemBase,
+		Size_:     size,
+		Links_:    links,
+	}
+	sf.SelfCheck()
+	return sf
+}
+
+// SelfCheck -- самопроверка
+func (sf *UseCase) SelfCheck() {
+	sf.IElemBase.SelfCheck()
+	hassert(sf.Size_ != nil, "UseCase.SelfCheck(): Size_ == nil")
+	var msgErr string
+	// Нет ссылок
+	if len(sf.Links_) == 0 {
+		return
+	}
+	// Проверить, что ссылки реально существует
+	for id, link := range sf.Links_ {
+		if link.Type() != cons.TypeUseLink {
+			msgErr += fmt.Sprintf("id=%q, не тип %q, тип=%q\n", id, cons.TypeUseLink, link.Type())
+			continue
+		}
+		ln, isOk := link.(types.IElemLinker)
+		if !isOk {
+			msgErr += fmt.Sprintf("id=%q, не тип `link`, link=%#v\n", id, link)
+			continue
+		}
+		// Проверить что ссылка взаимная
+		if !(ln.SrcId() == sf.Id() || ln.DstId() == sf.Id()) {
+			msgErr += fmt.Sprintf("id=%q, ссылка не взаимная\nsrc=%q, dst=%q\n", id, ln.SrcId(), ln.DstId())
+		}
+	}
+}
+
+// Links -- ссылки вариантов использования
+func (sf *UseCase) Links() map[alias.Id]types.IElemGroupLink {
+	return sf.Links_
+}

+ 21 - 13
pkg/elems/use_group/use_group.go → lev1/elem_use_group/elem_use_group.go

@@ -1,18 +1,16 @@
-// package use_group -- группа вариантов использования
-package use_group
+// package elem_use_group -- группа вариантов использования
+package elem_use_group
 
 import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
-	"gitp78su.ipnodns.ru/svi/goarch/lev1/size"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
 	"gitp78su.ipnodns.ru/svi/kern/v3"
 )
 
 // UseGroup -- группа вариантов использования
 type UseGroup struct {
-	ElemBase_ *elem_base.ElemBase
-	Size_     *size.Size
+	types.IElemBase
+	Size_ types.ISize
 }
 
 var (
@@ -20,22 +18,32 @@ var (
 )
 
 // NewUseGroup -- возвращает новую группу вариант использования
-func NewUseGroup(elemBase *elem_base.ElemBase, size *size.Size) *UseGroup {
-	hassert(elemBase != nil, "NewUseGroup(): elemBase is nil")
-	hassert(size != nil, "NewUseGroup(): size is nil")
+func NewUseGroup(elemBase types.IElemBase, size types.ISize) types.IElemUseGroup {
 	sf := &UseGroup{
-		ElemBase_: elemBase,
+		IElemBase: elemBase,
 		Size_:     size,
 	}
+	sf.SelfCheck()
 	return sf
 }
 
+// Size -- возвращает размер
+//
+//go:fix inline
+func (sf *UseGroup) Size() types.ISize {
+	return sf.Size_
+}
+
+
 // Links -- заглушка на связи между объектами
+//
+//go:fix inline
 func (sf *UseGroup) Links() []alias.Id {
-	return []alias.Id{sf.ElemBase_.Id_}
+	return []alias.Id{sf.IElemBase.Id()}
 }
 
 // Check -- заглушка под проверку
-func (sf *UseGroup) Check(map[alias.Id]types.IElemDrawer) string {
-	return ""
+func (sf *UseGroup) SelfCheck() {
+	hassert(sf.IElemBase != nil, "NewUseGroup(): IElemBase is nil")
+	hassert(sf.Size_ != nil, "NewUseGroup(): Size_ is nil")
 }

+ 17 - 3
lev1/offset/offset.go

@@ -3,6 +3,7 @@ package offset
 
 import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
 )
 
 // Offset -- смещение точки
@@ -12,7 +13,7 @@ type Offset struct {
 }
 
 // NewOffset -- возвращает новое смещение
-func NewOffset(x alias.CoordX, y alias.CoordY) *Offset {
+func NewOffset(x alias.CoordX, y alias.CoordY) types.IOffset {
 	sf := &Offset{
 		X_: x,
 		Y_: y,
@@ -20,17 +21,30 @@ func NewOffset(x alias.CoordX, y alias.CoordY) *Offset {
 	return sf
 }
 
-// Coord -- возвращает координаты
-func (sf *Offset) Offset() (alias.CoordX, alias.CoordY) {
+// Int -- возвращает смещение
+//
+//go:fix inline
+func (sf *Offset) Int() (int, int) {
+	return int(sf.X_), int(sf.Y_)
+}
+
+// Get -- возвращает смещение
+//
+//go:fix inline
+func (sf *Offset) Get() (alias.CoordX, alias.CoordY) {
 	return sf.X_, sf.Y_
 }
 
 // X -- возвращает координату X
+//
+//go:fix inline
 func (sf *Offset) X() alias.CoordX {
 	return sf.X_
 }
 
 // Y -- возвращает координату Y
+//
+//go:fix inline
 func (sf *Offset) Y() alias.CoordY {
 	return sf.Y_
 }

+ 29 - 5
lev1/size/size.go

@@ -3,23 +3,42 @@ package size
 
 import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
+	"gitp78su.ipnodns.ru/svi/kern/v3"
 )
 
 // Size -- размер области
 type Size struct {
-	W_ alias.SizeX `yaml:"w"` // Высота
-	H_ alias.SizeY `yaml:"h"` // Ширина
+	W_ alias.SizeX
+	H_ alias.SizeY
 }
 
+var(
+	hassert=kern.GetFnHassert()
+)
+
+
 // NewSize -- возвращает новый размер
-func NewSize(w alias.SizeX, h alias.SizeY) *Size {
+func NewSize(w alias.SizeX, h alias.SizeY) types.ISize {
 	sf := &Size{
 		W_: w,
 		H_: h,
 	}
+	sf.SelfCheck()
 	return sf
 }
 
+// SelfCheck -- проверяет корректность размера
+func (sf *Size) SelfCheck() {
+	hassert(sf.H_>=0, "Size.SelfCheck(): H_(%v)<0",sf.H_)
+	hassert(sf.W_>=0, "Size.SelfCheck(): W_(%v)<0",sf.W_)
+}
+
+
+
+
+
+
 // W -- возвращает ширину
 func (sf *Size) W() alias.SizeX {
 	return sf.W_
@@ -30,7 +49,12 @@ func (sf *Size) H() alias.SizeY {
 	return sf.H_
 }
 
-// Size -- возвращает размер
-func (sf *Size) Size() (alias.SizeX, alias.SizeY) {
+// Get -- возвращает размер
+func (sf *Size) Get() (alias.SizeX, alias.SizeY) {
 	return sf.W_, sf.H_
 }
+
+// Int -- возвращает размер
+func (sf *Size) Int() (int, int) {
+	return int(sf.W_), int(sf.H_)
+}

+ 50 - 0
lev1/view_use_case/view_use_case.go

@@ -0,0 +1,50 @@
+// package view_use_case -- отображение вариант использования
+package view_use_case
+
+import (
+	svg "github.com/ajstarks/svgo"
+
+	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
+)
+
+// ViewUseCase -- вариант использования
+type ViewUseCase struct {
+	types.IElemUseCase
+	Size_ types.ISize
+}
+
+
+// NewViewUseCase -- возвращает новый вариант использования
+func NewViewUseCase(useCase types.IElemUseCase) *ViewUseCase {
+	sf := &ViewUseCase{
+		IElemUseCase: useCase,
+	}
+	sf.SelfCheck()
+	return sf
+}
+
+// SelfCheck -- проверяет корректность элемента
+func (sf *ViewUseCase) SelfCheck() {
+	sf.IElemUseCase.SelfCheck()
+	sf.Size_.SelfCheck()
+}
+
+// Draw -- рисует вариант использования
+func (sf *ViewUseCase) Draw(canvas *svg.SVG) {
+	x, y := sf.Coord().Int()
+	// offX := int(sf.Label().Offset().X())
+	w, h := sf.Size_.Int()
+	// Овал
+	canvas.Ellipse(x+70, y, w, h, "fill:none;stroke:black")
+	// strLabel := sf.Label().String()
+	sf.Label().Draw(canvas)
+	// if strLabel != "" {
+	// 	canvas.Text(x+offX, y+6, strLabel, "font-size: 14px; font-family: Courier; fill: black")
+	// }
+	// if msgErr := sf.Check(mapElem); msgErr != "" {
+	// 	canvas.Group("Ошибка")
+	// 	canvas.Title(msgErr)
+	// 	canvas.Image(x-20, y-20, 16, 16, "/static/img/warning.png")
+	// }
+	canvas.Gend()
+}

+ 5 - 5
lev2/mod_http/serv_http.go

@@ -17,10 +17,10 @@ import (
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
 	"gitp78su.ipnodns.ru/svi/goarch/lev1/coord"
 	"gitp78su.ipnodns.ru/svi/goarch/lev1/size"
+	"gitp78su.ipnodns.ru/svi/goarch/lev1/view_use_case"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/canvas"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_actor"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_link"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_use_case"
 	"gitp78su.ipnodns.ru/svi/goarch/pkg/views/view_use_group"
 	"gitp78su.ipnodns.ru/svi/kern/v3"
 	"gitp78su.ipnodns.ru/svi/kern/v3/kc/log_buf"
@@ -48,8 +48,8 @@ type ModHttp struct {
 	diaMode    string       // Режим диаграммы
 	oldBinArch []byte       // Кеш старой архитектуры
 	canvSize   CanvasSize   // Размер холста
-	size       *size.Size   // Размер холста в его координатах
-	pos        *coord.Coord // Координаты холста
+	size       types.ISize  // Размер холста в его координатах
+	pos        types.ICoord // Координаты холста
 }
 
 // NewModHttp -- возвращает новый сервис
@@ -166,7 +166,7 @@ func (sf *ModHttp) postArch(ctx *fiber.Ctx) error {
 
 // Формирует варианты использования
 func (sf *ModHttp) useCase(canvas *svg.SVG, lstElem []map[string]interface{}) error {
-	mapDraw := make(map[alias.Id]types.IElemDrawer)
+	mapDraw := make(map[alias.Id]types.IDrawer)
 	for _, elem := range lstElem {
 		_id, isOk := elem["id"]
 		if !isOk {
@@ -194,7 +194,7 @@ func (sf *ModHttp) useCase(canvas *svg.SVG, lstElem []map[string]interface{}) er
 			return fmt.Errorf("ServHttp.useCase(): id=%q, field 'type'(%+v) not string<br>%+v", id, _type, string(binElem))
 		}
 		var (
-			drawer types.IElemDrawer
+			drawer types.IDrawer
 		)
 		switch strType {
 		case cons.TypeUseActor: // Нарисовать актора

+ 0 - 84
pkg/elems/use_case/use_case.go

@@ -1,84 +0,0 @@
-// package use_case -- вариант использования
-package use_case
-
-import (
-	"fmt"
-
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/cons"
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
-	"gitp78su.ipnodns.ru/svi/goarch/lev1/size"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/elem_base"
-	"gitp78su.ipnodns.ru/svi/kern/v3"
-)
-
-// UseCase -- вариант использования
-type UseCase struct {
-	ElemBase_ *elem_base.ElemBase `yaml:"elem_base"`
-	Size_     *size.Size          `yaml:"size"`
-	Links_    []alias.Id          `yaml:"links"` // Список ссылок
-}
-
-var (
-	hassert = kern.GetFnHassert()
-)
-
-// NewUseCase -- возвращает новый вариант использования
-func NewUseCase(elemBase *elem_base.ElemBase, size_ *size.Size) (*UseCase, error) {
-	hassert(elemBase != nil, "NewUseCase(): elemBase==nil")
-	id := elemBase.Id_
-	_links0, isOk := elemBase.Elem_["links"]
-	hassert(isOk, "NewUseCase(): id=%q, links not found", id)
-	_links, isOk := _links0.([]interface{})
-	hassert(isOk, "NewUseCase(): id=%q, `links`(%+v) not []interface{}", id, _links0)
-	var links []alias.Id
-	for _, _id := range _links {
-		id0, isOk := _id.(string)
-		hassert(isOk, "NewUseCase(): id=%q, `link`(%T, %+v) not string", id, _id, _id)
-		id1 := alias.Id(id0)
-		hassert(id1 != "", "NewUseCase(): id=%q, `link` is empty", id)
-		links = append(links, id1)
-	}
-	sf := &UseCase{
-		ElemBase_: elemBase,
-		Size_:     size_,
-		Links_:    links,
-	}
-	return sf, nil
-}
-
-// Check -- проверяет корректность элемента
-func (sf *UseCase) Check(mapElem map[alias.Id]types.IElemDrawer) string {
-	var msgErr string
-	// Нет ссылок
-	if len(sf.Links_) == 0 {
-		return fmt.Sprintf("id=%q, нет собственных ссылок", sf.ElemBase_.Id_)
-	}
-	// Проверить, что ссылки реально существует
-	for _, id := range sf.Links_ {
-		link, ok := mapElem[id]
-		if !ok {
-			msgErr += fmt.Sprintf("id=%q, собственная ссылка не существует\n", id)
-			continue
-		}
-		if link.Type() != cons.TypeUseLink {
-			msgErr += fmt.Sprintf("id=%q, не тип %q, тип=%q\n", id, cons.TypeUseLink, link.Type())
-			continue
-		}
-		ln, isOk := link.(types.IElemLinker)
-		if !isOk {
-			msgErr += fmt.Sprintf("id=%q, не тип `link`, link=%#v\n", id, link)
-			continue
-		}
-		// Проверить что ссылка взаимная
-		if !(ln.SrcId() == sf.ElemBase_.Id_ || ln.DstId() == sf.ElemBase_.Id_) {
-			msgErr += fmt.Sprintf("id=%q, ссылка не взаимная\nsrc=%q, dst=%q\n", id, ln.SrcId(), ln.DstId())
-		}
-	}
-	return msgErr
-}
-
-// Links -- ссылки вариантов использования
-func (sf *UseCase) Links() []alias.Id {
-	return sf.Links_
-}

+ 1 - 1
pkg/elems/use_group_link/use_group_link.go

@@ -49,7 +49,7 @@ func NewUseGroupLink(elemBase *elem_base.ElemBase, id alias.Id, label_ alias.Lab
 }
 
 // Check -- проверяет ошибки связей
-func (sf *UseGroupLink) Check(mapElem map[alias.Id]types.IElemDrawer) string {
+func (sf *UseGroupLink) Check(mapElem map[alias.Id]types.IDrawer) string {
 	var msgErr string
 	if len(sf.Links_) == 0 {
 		msgErr = "Список ссылок(links) пуст\n"

+ 3 - 3
pkg/elems/use_link/use_link.go

@@ -62,7 +62,7 @@ func (sf *UseLink) Links() []alias.Id {
 }
 
 // Check -- проверяет связи между объектами
-func (sf *UseLink) Check(mapDrawer map[alias.Id]types.IElemDrawer) string {
+func (sf *UseLink) Check(mapDrawer map[alias.Id]types.IDrawer) string {
 	if sf.Dst_ == sf.Src_ {
 		return fmt.Sprintf("ВНИМАНИЕ! Источник и получатель совпадают\nsrc=%v, dst=%v\n", sf.Src_, sf.Dst_)
 	}
@@ -79,7 +79,7 @@ func (sf *UseLink) Check(mapDrawer map[alias.Id]types.IElemDrawer) string {
 }
 
 // проверить связь получателя
-func (sf *UseLink) checkDst(mapDrawer map[alias.Id]types.IElemDrawer) string {
+func (sf *UseLink) checkDst(mapDrawer map[alias.Id]types.IDrawer) string {
 	if sf.Dst_ == "" {
 		return "ОШИБКА получатель `dst` не задан"
 	}
@@ -135,7 +135,7 @@ func (sf *UseLink) checkDst(mapDrawer map[alias.Id]types.IElemDrawer) string {
 }
 
 // Проверяет связь источника
-func (sf *UseLink) checkSrc(mapDrawer map[alias.Id]types.IElemDrawer) string {
+func (sf *UseLink) checkSrc(mapDrawer map[alias.Id]types.IDrawer) string {
 	if sf.Src_ == "" {
 		return "ВНИМАНИЕ! Источник связи не задан(src)\n"
 	}

+ 1 - 1
pkg/views/view_actor/view_actor.go

@@ -31,7 +31,7 @@ func NewViewActor(actor *actor.Actor, elem map[string]interface{}) *ViewActor {
 }
 
 // Draw -- рисует фигуру актора
-func (sf *ViewActor) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IElemDrawer) {
+func (sf *ViewActor) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IDrawer) {
 	x := int(sf.Actor_.Label_.Coord_.X_)
 	y := int(sf.Actor_.Label_.Coord_.Y_)
 	offX := int(sf.Actor_.Label_.Offset_.X_)

+ 1 - 1
pkg/views/view_link/view_link.go

@@ -29,7 +29,7 @@ func NewViewLink(useLink *use_link.UseLink) *Link {
 }
 
 // Draw -- рисует связь между объектами
-func (sf *Link) Draw(canvas *svg.SVG, mapDrawer map[alias.Id]types.IElemDrawer) {
+func (sf *Link) Draw(canvas *svg.SVG, mapDrawer map[alias.Id]types.IDrawer) {
 	_x, _y := sf.UseLink_.ElemBase_.Label_.Coord_.Coord()
 	x := int(_x)
 	y := int(_y)

+ 0 - 50
pkg/views/view_use_case/view_use_case.go

@@ -1,50 +0,0 @@
-// package view_use_case -- отображение вариант использования
-package view_use_case
-
-import (
-	svg "github.com/ajstarks/svgo"
-
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/use_case"
-	"gitp78su.ipnodns.ru/svi/kern/v3"
-)
-
-// ViewUseCase -- вариант использования
-type ViewUseCase struct {
-	UseCase_ *use_case.UseCase
-}
-
-var (
-	hassert = kern.GetFnHassert()
-)
-
-// NewViewUseCase -- возвращает новый вариант использования
-func NewViewUseCase(useCase *use_case.UseCase, elem map[string]interface{}) *ViewUseCase {
-	hassert(useCase != nil, "NewViewUseCase(): useCase=nil")
-	sf := &ViewUseCase{
-		UseCase_: useCase,
-	}
-	return sf
-}
-
-// Draw -- рисует вариант использования
-func (sf *ViewUseCase) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IElemDrawer) {
-	x := int(sf.UseCase_.ElemBase_.Label_.Coord_.X_)
-	y := int(sf.UseCase_.ElemBase_.Label_.Coord_.Y_)
-	offX := int(sf.UseCase_.ElemBase_.Label_.Offset_.X_)
-	w := int(sf.UseCase_.Size_.W_)
-	h := int(sf.UseCase_.Size_.H_)
-	// Овал
-	canvas.Ellipse(x+70, y, w, h, "fill:none;stroke:black")
-	strLabel := string(sf.UseCase_.ElemBase_.Label_.Val_)
-	if strLabel != "" {
-		canvas.Text(x+offX, y+6, strLabel, "font-size: 14px; font-family: Courier; fill: black")
-	}
-	if msgErr := sf.Check(mapElem); msgErr != "" {
-		canvas.Group("Ошибка")
-		canvas.Title(msgErr)
-		canvas.Image(x-20, y-20, 16, 16, "/static/img/warning.png")
-		canvas.Gend()
-	}
-}

+ 17 - 16
pkg/views/view_use_group/view_use_group.go

@@ -3,16 +3,15 @@ package view_use_group
 
 import (
 	svg "github.com/ajstarks/svgo"
+	"gitp78su.ipnodns.ru/svi/kern/v3"
 
-	"gitp78su.ipnodns.ru/svi/goarch/lev0/alias"
 	"gitp78su.ipnodns.ru/svi/goarch/lev0/types"
-	"gitp78su.ipnodns.ru/svi/goarch/pkg/elems/use_group"
-	"gitp78su.ipnodns.ru/svi/kern/v3"
 )
 
 // ViewUseGroup -- отображение группы вариантов использования
 type ViewUseGroup struct {
-	UseGroup *use_group.UseGroup
+	types.IElemUseGroup
+	Label_ types.IElemLabel
 }
 
 var (
@@ -20,27 +19,29 @@ var (
 )
 
 // NewViewUseGroup -- возвращает новое отображение группы вариант использования
-func NewViewUseGroup(useGroup *use_group.UseGroup, elem map[string]interface{}) *ViewUseGroup {
+func NewViewUseGroup(useGroup types.IElemUseGroup, label types.IElemLabel) types.IDrawer {
 	hassert(useGroup != nil, "NewViewUseGroup(): useGroup == nil")
 	sf := &ViewUseGroup{
-		UseGroup: useGroup,
+		IElemUseGroup: useGroup,
+		Label_:        label,
 	}
+	sf.SelfCheck()
 	return sf
 }
 
+// SelfCheck -- проверяет корректность элемента
+func (sf *ViewUseGroup) SelfCheck() {
+	hassert(sf.IElemUseGroup != nil, "ViewUseGroup.SelfCheck(): IElemUseGroup == nil")
+	hassert(sf.Label_ != nil, "ViewUseGroup.SelfCheck(): Label_ == nil")
+}
+
 // Draw -- рисует группу вариантов использования
-func (sf *ViewUseGroup) Draw(canvas *svg.SVG, mapElem map[alias.Id]types.IElemDrawer) {
-	x := int(sf.UseGroup.ElemBase_.Label_.Coord_.X_)
-	y := int(sf.UseGroup.ElemBase_.Label_.Coord_.X_)
-	offX := int(sf.UseGroup.ElemBase_.Label_.Offset_.X_)
-	w := int(sf.UseGroup.Size_.W_)
-	h := int(sf.UseGroup.Size_.H_)
+func (sf *ViewUseGroup) Draw(canvas *svg.SVG) {
+	x, y := sf.Coord().Int()
+	w, h := sf.Size().Int()
 	// Главный квадрат
 	canvas.Rect(x, y, w, h, "fill:none;stroke:black")
 	// Заголовок
 	canvas.Rect(x, y-26, h/2, 26, "fill:none;stroke:black")
-	strLabel := string(sf.UseGroup.ElemBase_.Label_.Val_)
-	if strLabel != "" {
-		canvas.Text(x+offX, y-8, strLabel, "font-size: 14px; font-family: Courier; fill: black")
-	}
+	sf.Label_.Draw(canvas)
 }