github.com/covergates/covergates@v0.2.2-0.20201009050117-42ef8a19fb95/modules/charts/treemap.go (about)

     1  package charts
     2  
     3  import (
     4  	"io"
     5  	"sort"
     6  
     7  	svgchart "github.com/blueworrybear/svg-charts"
     8  	"github.com/covergates/covergates/core"
     9  )
    10  
    11  type diffFiles struct {
    12  	names []string
    13  	files map[string]*core.File
    14  }
    15  
    16  const (
    17  	colorIncrease = "#16C36D"
    18  	colorDecrease = "#C3161B"
    19  	colorNoChange = "#ADC7C5"
    20  )
    21  
    22  // CoverageDiffTreeMap for two coverage reports
    23  type CoverageDiffTreeMap struct {
    24  	oldFiles map[string]*core.File
    25  	newFiles map[string]*core.File
    26  }
    27  
    28  // NewCoverageDiffTreeMap with two coverage reports
    29  func NewCoverageDiffTreeMap(old, new *core.Report) *CoverageDiffTreeMap {
    30  	oldFiles := make(map[string]*core.File)
    31  	newFiles := make(map[string]*core.File)
    32  	for _, file := range reportFileSlice(old) {
    33  		oldFiles[file.Name] = file
    34  	}
    35  	for _, file := range reportFileSlice(new) {
    36  		newFiles[file.Name] = file
    37  	}
    38  	return &CoverageDiffTreeMap{
    39  		oldFiles: oldFiles,
    40  		newFiles: newFiles,
    41  	}
    42  }
    43  
    44  func reportFileSlice(r *core.Report) []*core.File {
    45  	s := make([]*core.File, 0)
    46  	for _, cov := range r.Coverages {
    47  		for _, file := range cov.Files {
    48  			s = append(s, file)
    49  		}
    50  	}
    51  	return s
    52  }
    53  
    54  // Render chart to writer
    55  func (c *CoverageDiffTreeMap) Render(w io.Writer) error {
    56  	colors := make([]string, 0)
    57  	labels := make([]string, 0)
    58  	data := make([]interface{}, 0)
    59  	names := make([]string, 0)
    60  	for name := range c.newFiles {
    61  		names = append(names, name)
    62  	}
    63  	diffFiles := &diffFiles{
    64  		names: names,
    65  		files: c.newFiles,
    66  	}
    67  	sort.Sort(diffFiles)
    68  	for _, name := range diffFiles.names {
    69  		newFile := c.newFiles[name]
    70  		oldCover := 0.0
    71  		oldFile, ok := c.oldFiles[name]
    72  		if ok {
    73  			oldCover = oldFile.StatementCoverage
    74  		}
    75  		diff := newFile.StatementCoverage - oldCover
    76  		color := colorNoChange
    77  		label := ""
    78  		if diff > 0 {
    79  			color = colorIncrease
    80  		} else if diff < 0 {
    81  			color = colorDecrease
    82  		}
    83  		if diff != 0 {
    84  			label = name
    85  		}
    86  		colors = append(colors, color)
    87  		labels = append(labels, label)
    88  		data = append(data, len(newFile.StatementHits))
    89  	}
    90  	svg, err := svgchart.NewSVGChart(
    91  		svgchart.Options{
    92  			Series: []*svgchart.SeriesOption{
    93  				{
    94  					Data:   svgchart.SeriesData(data...),
    95  					Colors: colors,
    96  				},
    97  			},
    98  			Chart: &svgchart.ChartOptions{
    99  				Type:   "treemap",
   100  				Width:  600,
   101  				Height: 400,
   102  			},
   103  			Labels: labels,
   104  			LabelOption: &svgchart.LabelOptions{
   105  				FontSize: 12,
   106  				Color:    "#FFFFFF",
   107  			},
   108  		},
   109  	)
   110  	if err != nil {
   111  		return err
   112  	}
   113  	return svg.Render(w)
   114  }
   115  
   116  func (f *diffFiles) Len() int { return len(f.names) }
   117  func (f *diffFiles) Less(i, j int) bool {
   118  	return f.files[f.names[i]].Name < f.files[f.names[j]].Name
   119  }
   120  func (f *diffFiles) Swap(i, j int) {
   121  	f.names[i], f.names[j] = f.names[j], f.names[i]
   122  }