chart_property.go 9.4 KB
package domain

import (
	"github.com/samber/lo"
	"strconv"
)

const (
	SourceFromByteBank = "ByteBank"
	SourceFromUser     = "User"
)

var (
	RecordTable1   = "RecordTable-1"
	MetricsCard1   = "MetricsCard-1"
	ContainerCard1 = "ContainerCard-1"
	QuarterChart1  = "QuarterChart-1"
)

type ChartProperty struct {
	Title        Title        `json:"title,optional"`  // 标题
	TableAbility TableAbility `json:"table,optional"`  // 表筛选功能
	Series       []Series     `json:"series,optional"` // 系列(数据源)
	Cover        string       `json:"cover,optional"`  // 封面
	Other        Other        `json:"other,optional"`  // 其他额外配置
	//XAxis interface{} `json:"xAxis"` // X轴
	//YAxis interface{} `json:"yAxis"` // Y轴
}
type Other struct {
	Quarter   *Quarter   `json:"quarter,optional,omitempty"`   // 四分图
	Divider   *Divider   `json:"divider,optional,omitempty"`   // 分割线
	Rank      *Rank      `json:"rank,optional,omitempty"`      // 排名图
	Deviation *Deviation `json:"deviation,optional,omitempty"` // 偏差图
	Notepaper *Notepaper `json:"notepaper,optional,omitempty"` // 便签(富文本)
}
type Quarter struct {
	XAxisLabel       string          `json:"xAxisLabel"`                          // x轴标签名
	XAxisFirstLabel  string          `json:"xAxisFirstLabel"`                     // 签名1
	XAxisSecondLabel string          `json:"xAxisSecondLabel"`                    // 签名2
	XAxisFirstColor  string          `json:"xAxisFirstColor,optional,omitempty"`  // x轴标签1默认颜色
	XAxisSecondColor string          `json:"xAxisSecondColor,optional,omitempty"` // x轴标签2默认颜色
	YAxisLabel       string          `json:"yAxisLabel"`                          // y轴标签名
	YAxisFirstLabel  string          `json:"yAxisFirstLabel"`                     // y标签1
	YAxisSecondLabel string          `json:"yAxisSecondLabel"`                    // y标签2
	YAxisFirstColor  string          `json:"yAxisFirstColor,optional,omitempty"`  // y轴标签1默认颜色
	YAxisSecondColor string          `json:"yAxisSecondColor,optional,omitempty"` // y轴标签2默认颜色
	Area             string          `json:"area"`                                // 图形面积
	AreaColor        bool            `json:"areaColor"`                           // 颜色
	SeriesList       []QuarterSeries `json:"seriesList"`                          // 图形系列
	TableSwitch      bool            `json:"tableSwitch"`                         // 是否展示记录型表格
}

type QuarterSeries struct {
	SeriesValue string `json:"seriesValue"`
}

type Divider struct {
	SelectedIdx string `json:"selectedIdx,optional,omitempty"` // 选择的分割线样式
	TextSwitch  bool   `json:"textSwitch,optional,omitempty"`  // 是否展示组件文本
	Text        string `json:"text"`                           // 组件文本内容
}

type Rank struct {
	FirstLine    []RankLine `json:"firstLine,optional,omitempty"`    // 第一名设置
	SecondLine   []RankLine `json:"secondLine,optional,omitempty"`   // 第二名设置
	SortBySwitch bool       `json:"sortBySwitch,optional,omitempty"` // 排序开关
	SortBySeries string     `json:"sortBySeries,optional,omitempty"` // 排序依据
	SortByArrow  string     `json:"sortByArrow,optional,omitempty"`  // 排序方向 1-降序 2-升序
}

type RankLine struct {
	SeriesValue string `json:"seriesValue"` // 排名图序列值
	LabelSwitch bool   `json:"labelSwitch"` // 标签开关
	Label       string `json:"label"`       // 标签
	ArrowSwitch bool   `json:"arrowSwitch"` // 箭头开关
	Unit        string `json:"unit"`        // 单位
}

type Title struct {
	TitleSwitch     bool   `json:"titleSwitch,optional"`                     // 组件标题开关
	IntroduceSwitch bool   `json:"introduceSwitch,optional"`                 // 组件说明开关
	TitleType       string `json:"titleType"`                                // 标题类型
	Heading         string `json:"heading,optional"`                         // 主标题
	SubTitle        string `json:"subTitle,optional"`                        // 副标题
	ExplainType     string `json:"explainType,optional,options=[text,file]"` // text file
	ExplainTxt      string `json:"explainTxt,optional"`                      // 文字说明
	FileName        string `json:"fileName,optional"`                        // 文件名
	FileUrl         string `json:"fileUrl,optional"`                         // 组件图片/视频
	Align           string `json:"align,optional"`                           // 废弃 文本对齐方式 left center right
	HeadingAlign    string `json:"headingAlign,optional"`                    // 主标题 文本对齐方式 left center right
	SubAlign        string `json:"subAlign,optional"`                        // 副标题 文本对齐方式 left center right
}

type TableAbility struct {
	FilterSwitch  bool            `json:"filterSwitch,optional"`  // 表筛选功能开关
	DimensionList []Dimension     `json:"dimensionList,optional"` // 维度列表
	CardSwitch    bool            `json:"cardSwitch,optional"`    // 顺序标识开关
	CardIdent     string          `json:"cardIdent,optional"`     // 顺序标识
	CardOrderList []CardOrderItem `json:"cardOrderList,optional"` // 卡片列表顺序
}

type CardOrderItem struct {
	CardId string `json:"cardId,optional"`
}

type Series struct {
	// Type             string       `json:"type"`                         // 图表类型 (记录型表格:RecordTable-1 总体指标:MetricsCard-1 容器卡片:ContainerCard-1 四分图:QuarterChart-1)
	Name             string       `json:"name"`                            // 名称 (例如 指标1、指标2)
	SourceFrom       string       `json:"from,options=[ByteBank,User]"`    // 数据源类型 ByteBank:字库  User:用户自定义
	DataSourceId     int64        `json:"dataSourceId,optional,omitempty"` // 数据源ID(from值为ByteBank时有值)
	CustomText       string       `json:"customText,optional,omitempty"`   // 自定义数据文本(from值为User时有值)
	MatchExpressions []Expression `json:"matchExpressions,omitempty"`      // 条件匹配表达式(总体指标)
	TargetText       string       `json:"targetText,optional,omitempty"`   // 指标名文本
	TargetNum        string       `json:"targetNum,optional,omitempty"`    // 指标数值
	TargetUnit       string       `json:"targetUnit,optional,omitempty"`   // 指标单位
}

type Expression struct {
	Operator     string `json:"operator,options=[<,>,==,<>,<=,>=]"` // 操作符号 <,>,==,<>,<=,>=
	CompareValue string `json:"compareValue"`                       // 比较值
	ToValue      string `json:"toValue"`                            // 显示值(转为)
}

type (
	Deviation struct {
		XAxisLabel string     `json:"xAxisLabel,optional,omitempty"` // 分类标签
		TopChart   TopChart   `json:"topChart,optional,omitempty"`
		MidChart   MidChart   `json:"midChart,optional,omitempty"`
		BotChart   []BotChart `json:"botChart,optional,omitempty"`
	}
	Notepaper struct {
		Text  string `json:"text,optional,omitempty"`  // 富文本内容
		Theme string `json:"theme,optional,omitempty"` // 主题风格
	}
	TopChart struct {
		SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
		Legend      string `json:"legend,optional,omitempty"`      // 图例
		FormatType  string `json:"formatType,optional,omitempty"`  //
		FormatPoint string `json:"formatPoint,optional,omitempty"` //
	}
	MidChart struct {
		SeriesValue string `json:"seriesValue,optional,omitempty"` // 系列
		Legend      string `json:"legend,optional,omitempty"`      // 图例
		FormatType  string `json:"formatType,optional,omitempty"`  //
		FormatPoint string `json:"formatPoint,optional,omitempty"` //
	}
	BotChart struct {
		SeriesSwitch bool   `json:"seriesSwitch,optional,omitempty"` // 是否显示
		Type         string `json:"type,optional,omitempty"`         // 图表类型
		SeriesValue  string `json:"seriesValue,optional,omitempty"`  // 系列
		Legend       string `json:"legend,optional,omitempty"`       // 图例
		FormatType   string `json:"formatType,optional,omitempty"`   //
		FormatPoint  string `json:"formatPoint,optional,omitempty"`  //
	}
)

func (exp Expression) Match(value string) (result bool, toValue string) {
	fValue, ferr := strconv.ParseFloat(value, 64)
	cValue, cerr := strconv.ParseFloat(exp.CompareValue, 64)
	if ferr == nil && cerr == nil {
		if exp.FloatMatch(exp.Operator, fValue, cValue) {
			return true, exp.ToValue
		}
		return false, value
	}
	if exp.StringMatch(exp.Operator, value, exp.CompareValue) {
		return true, exp.ToValue
	}
	return false, value
}

func (exp Expression) FloatMatch(op string, v, c float64) bool {
	switch op {
	case "<":
		return v < c
	case ">":
		return v > c
	case "==":
		return v == c
	case "<>":
		return v != c
	case "<=":
		return v <= c
	case ">=":
		return v >= c
	}
	return false
}

func (exp Expression) StringMatch(op string, v, c string) bool {
	switch op {
	case "<":
		return v < c
	case ">":
		return v > c
	case "==":
		return v == c
	case "<>":
		return v != c
	case "<=":
		return v <= c
	case ">=":
		return v >= c
	}
	return false
}

type Dimension struct {
	Name  string `json:"name"`
	Value string `json:"value"`
}

func (e ChartProperty) GetFirstDataSourceId() int64 {
	for _, s := range e.Series {
		if s.DataSourceId > 0 {
			return s.DataSourceId
		}
	}
	return 0
}

func (e ChartProperty) GetAllDataSourceId() []int64 {
	var idList = make([]int64, 0)
	for _, s := range e.Series {
		if s.DataSourceId > 0 {
			idList = append(idList, s.DataSourceId)
		}
	}
	return lo.Uniq(idList)
}