ensure consistent ordering of data
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
96
main.go
96
main.go
@@ -36,10 +36,35 @@ type Record struct {
|
||||
Wsdc json.RawMessage `json:"Western Sydney Data Centre"`
|
||||
}
|
||||
|
||||
type KeyValue struct {
|
||||
Key string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
var sha1ver string // sha1 revision used to build the program
|
||||
var buildTime string // when the executable was built
|
||||
|
||||
// Add a new key-value pair to the slice
|
||||
func addData(data []KeyValue, key string, value interface{}) []KeyValue {
|
||||
return append(data, KeyValue{Key: key, Value: value})
|
||||
}
|
||||
|
||||
// Find a value by key
|
||||
func findData(data []KeyValue, key string) (interface{}, bool) {
|
||||
for _, kv := range data {
|
||||
if kv.Key == key {
|
||||
return kv.Value, true
|
||||
}
|
||||
}
|
||||
return nil, false // Return false if key not found
|
||||
}
|
||||
|
||||
func GenerateAvgVcpusCharts(f *excelize.File, data any, name string) {
|
||||
var err error
|
||||
rydeAvgCpu := make(map[string]interface{})
|
||||
wsdcAvgCpu := make(map[string]interface{})
|
||||
//rydeAvgCpu := make(map[string]interface{})
|
||||
rydeAvgCpu := []KeyValue{}
|
||||
//wsdcAvgCpu := make(map[string]interface{})
|
||||
wsdcAvgCpu := []KeyValue{}
|
||||
var avgCpuColumns []string
|
||||
|
||||
// Access AvgCpu using reflection
|
||||
@@ -75,8 +100,11 @@ func GenerateAvgVcpusCharts(f *excelize.File, data any, name string) {
|
||||
}
|
||||
}
|
||||
|
||||
rydeAvgCpu[fieldName] = rydeData
|
||||
wsdcAvgCpu[fieldName] = wsdcData
|
||||
rydeAvgCpu = addData(rydeAvgCpu, fieldName, rydeData)
|
||||
wsdcAvgCpu = addData(wsdcAvgCpu, fieldName, wsdcData)
|
||||
|
||||
//rydeAvgCpu[fieldName] = rydeData
|
||||
//wsdcAvgCpu[fieldName] = wsdcData
|
||||
avgCpuColumns = append(avgCpuColumns, fieldName)
|
||||
}
|
||||
|
||||
@@ -88,7 +116,8 @@ func GenerateAvgVcpusCharts(f *excelize.File, data any, name string) {
|
||||
|
||||
func GenerateCharts(f *excelize.File, data any, name string, location string) {
|
||||
var err error
|
||||
parsedData := make(map[string]interface{})
|
||||
//parsedData := make(map[string]interface{})
|
||||
parsedData := []KeyValue{}
|
||||
var dataColumns = []string{"RCC", "WSDC"}
|
||||
|
||||
// Create interfaces to hold unmarshaled data
|
||||
@@ -117,21 +146,24 @@ func GenerateCharts(f *excelize.File, data any, name string, location string) {
|
||||
}
|
||||
|
||||
// store the data together
|
||||
parsedData["RCC"] = rcc
|
||||
parsedData["WSDC"] = wsdc
|
||||
parsedData = addData(parsedData, "RCC", rcc)
|
||||
parsedData = addData(parsedData, "WSDC", wsdc)
|
||||
//parsedData["RCC"] = rcc
|
||||
//parsedData["WSDC"] = wsdc
|
||||
//prettyPrint(parsedData)
|
||||
|
||||
// Generate worksheet and graph
|
||||
AvgChart(f, name, location, dataColumns, parsedData)
|
||||
}
|
||||
|
||||
func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuColumns []string, data map[string]interface{}) {
|
||||
func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuColumns []string, data []KeyValue) {
|
||||
var err error
|
||||
var chartSeries []excelize.ChartSeries
|
||||
var dataDates []string
|
||||
var col int
|
||||
var row int
|
||||
|
||||
fmt.Printf("Creating worksheet %s\n", worksheetName)
|
||||
_, err = f.NewSheet(worksheetName)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
@@ -144,12 +176,14 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
f.SetCellValue(worksheetName, cell, avgCpuColumns[i])
|
||||
}
|
||||
|
||||
// Get the values for the dates column
|
||||
// Get the values for the dates column using the first object in data
|
||||
for _, v := range data {
|
||||
for date := range v.(map[string]interface{}) {
|
||||
dataDates = append(dataDates, date)
|
||||
if dateMap, ok := v.Value.(map[string]interface{}); ok {
|
||||
for date := range dateMap {
|
||||
dataDates = append(dataDates, date)
|
||||
}
|
||||
}
|
||||
break
|
||||
break // Assuming you only need the dates from the first entry
|
||||
}
|
||||
|
||||
// Sort dates using the custom function
|
||||
@@ -165,22 +199,27 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
f.SetCellValue(worksheetName, cell, dataDates[i])
|
||||
}
|
||||
|
||||
for pool, v := range data { // iterate each resource pool type
|
||||
// Iterate over each KeyValue in the data slice (resource pool types)
|
||||
for _, poolKv := range data {
|
||||
pool := poolKv.Key // The pool name
|
||||
|
||||
// Find the column that matches, add one to account for the date column
|
||||
col = slices.Index(avgCpuColumns, pool) + 1
|
||||
//fmt.Printf("Pool: %s, column: %d\n", pool, col)
|
||||
fmt.Printf("Pool: %s, column: %d\n", pool, col)
|
||||
|
||||
for date, val := range v.(map[string]interface{}) { // use type assertion to loop over map[string]interface{}
|
||||
//fmt.Printf("val: %v\n", val)
|
||||
// Type assertion to confirm that poolKv.Value is a map[string]interface{}
|
||||
if dateMap, ok := poolKv.Value.(map[string]interface{}); ok {
|
||||
for date, val := range dateMap {
|
||||
fmt.Printf("Date: %s, Value: %v\n", date, val)
|
||||
|
||||
// Find the correct row, add one to account for sheet heading
|
||||
row = slices.Index(dataDates, date) + 1
|
||||
// Find the correct row, add one to account for sheet heading
|
||||
row = slices.Index(dataDates, date) + 1
|
||||
|
||||
cell := string(rune('A'+col)) + strconv.Itoa(row+1)
|
||||
//fmt.Printf("Adding value %f (%s) to %s]\n", val, date, cell)
|
||||
f.SetCellValue(worksheetName, cell, val)
|
||||
cell := string(rune('A'+col)) + strconv.Itoa(row+1)
|
||||
//fmt.Printf("Adding value %f (%s) to %s]\n", val, date, cell)
|
||||
f.SetCellValue(worksheetName, cell, val)
|
||||
}
|
||||
}
|
||||
|
||||
// Create the chartseries for this resource pool
|
||||
thisChartSeries := excelize.ChartSeries{
|
||||
Name: "'" + worksheetName + "'!$" + string(rune('A'+col)) + "$1", // Reference the cell containing the resource pool name, eg Tin in $B$1
|
||||
@@ -220,6 +259,11 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
XAxis: excelize.ChartAxis{
|
||||
MajorGridLines: true,
|
||||
MinorGridLines: true,
|
||||
Title: []excelize.RichTextRun{
|
||||
{
|
||||
Text: "Month Year",
|
||||
},
|
||||
},
|
||||
Font: excelize.Font{
|
||||
Color: "000000",
|
||||
},
|
||||
@@ -227,6 +271,11 @@ func AvgChart(f *excelize.File, worksheetName string, location string, avgCpuCol
|
||||
YAxis: excelize.ChartAxis{
|
||||
MajorGridLines: true,
|
||||
MinorGridLines: true,
|
||||
Title: []excelize.RichTextRun{
|
||||
{
|
||||
Text: "Count/Size",
|
||||
},
|
||||
},
|
||||
Font: excelize.Font{
|
||||
Color: "000000",
|
||||
},
|
||||
@@ -248,6 +297,9 @@ func main() {
|
||||
outputFile := flag.String("output", "book1.xlsx", "The filename to use when writing excel workbook")
|
||||
flag.Parse()
|
||||
|
||||
fmt.Println("Excel chart generation utility, written by Nathan Coad (nathan.coad@dell.com)")
|
||||
fmt.Printf("Built on %s from sha1 %s\n", buildTime, sha1ver)
|
||||
|
||||
// Create the workbook
|
||||
f := excelize.NewFile()
|
||||
defer func() {
|
||||
|
Reference in New Issue
Block a user