Пример #1
0
func New(w, h vg.Length) *Canvas {
	buf := new(bytes.Buffer)
	c := &Canvas{
		svg: svgo.New(buf),
		w:   w,
		h:   h,
		buf: buf,
		ht:  w.Points(),
		stk: []context{context{}},
	}

	// This is like svg.Start, except it uses floats
	// and specifies the units.
	fmt.Fprintf(buf, `<?xml version="1.0"?>
<!-- Generated by SVGo and Plotinum VG -->
<svg width="%.*gin" height="%.*gin"
	xmlns="http://www.w3.org/2000/svg"
	xmlns:xlink="http://www.w3.org/1999/xlink">`+"\n",
		pr, w/vg.Inch,
		pr, h/vg.Inch,
	)

	// Swap the origin to the bottom left.
	// This must be matched with a </g> when saving,
	// before the closing </svg>.
	c.svg.Gtransform(fmt.Sprintf("scale(1, -1) translate(0, -%.*g)", pr, h.Dots(c)))

	vg.Initialize(c)
	return c
}
Пример #2
0
func drawSvgChart(w, h int, data []StockData, c *http.Conn) {
	// SVG-Ausgabe mit der HTTP-Verbindung als Stream initialisieren
	s := svg.New(c)
	// SVG-Objekt starten
	s.Start(w, h)
	// die horizontale Schrittweite pro Eintrag berechnen
	step := float(w) / float((len(data) + 1))
	// das Minimum und das Maximum ermitteln
	min, max := minMax(data)
	diff := max - min
	// Jetzt über die Einträge iterieren ...
	var lastPoint Point
	for i, d := range data {
		// ... die Koordinaten berechnen...
		x := w - int(float(i)*step)
		y := int(float(h-1) - ((d.close-min)/diff)*float(h-1))
		// ... und die Linie malen, falls es schon zwei Punkte gibt
		if i > 0 {
			s.Line(lastPoint.x, lastPoint.y, x, y, "width:1;stroke:blue")
		}
		// den berechneten Punkt als Startpunkt für die nächste Linie merken
		lastPoint = Point{x, y}
	}
	// SVG-Ausgabe beenden - fertig.
	s.End()
}
Пример #3
0
func TestCalcCanvasSize_30x27(t *testing.T) {
	f, err := os.Create("test_page.svg")
	if err != nil {
		t.Errorf("failed to create test.svg : %s\n", err)
	}
	defer f.Close()

	canvas := svg.New(f)
	defer canvas.End()

	br := make([]rune, 100, 0x28FF)
	for i := 0; i < 100; i++ {
		switch {
		case i%5 == 0:
			br[i] = 0x2800
		case i%37 == 0:
			br[i] = 0xa
		default:
			br[i] = brl.Rune(1, 2, 3, 4, 5, 6)
		}
	}
	bs := string(br)
	fmt.Println(bs)
	calcLines(bs, 30)

	DrawPage30(canvas, bs)
}
Пример #4
0
// Marshal renders the SVG to the given io.Writer.
func (c *Canvas) Marshal(w io.Writer) {
	// Initialize maps for service icons, which are used both in definition
	// and use methods for services.
	c.iconsRendered = make(map[string]bool)
	c.iconIds = make(map[string]string)

	// TODO check write errors and return an error from
	// Marshal if the write fails. The svg package does not
	// itself check or return write errors; a possible work-around
	// is to wrap the writer in a custom writer that panics
	// on error, and catch the panic here.
	width, height := c.layout()

	canvas := svg.New(w)
	canvas.Start(
		width,
		height,
		fmt.Sprintf(`style="font-family:Ubuntu, sans-serif;" viewBox="0 0 %d %d"`,
			width, height),
	)
	defer canvas.End()
	c.definition(canvas)
	c.relationsGroup(canvas)
	c.servicesGroup(canvas)
}
Пример #5
0
// API: POST /braille
func brailleHandler(w http.ResponseWriter, r *http.Request) {
	src := r.FormValue("input")
	lang := r.FormValue("lang")
	if lang == "" {
		// TODO: lang이 없거나 auto이면 언어 판단해야함
		lang = "ko"
	}
	format := r.FormValue("format")
	if format == "" {
		format = "svg"
	}

	w.Header().Set("Content-Type", "text/html; charset=utf-8")

	var bStr string

	if lang == "ko" {
		bStr, _ = brl_ko.Encode(src)
	} else if lang == "en" {
		bStr, _ = brl_en.Encode(src)
	}

	if format == "svg" {
		canvas := svg.New(w)
		defer canvas.End()
		brl_svg.DrawPage30(canvas, bStr)
	} else {
		fmt.Fprint(w, bStr)
	}
}
Пример #6
0
func showMaze(p string, e Environment, hist []Line, pts []Point) error {

	// Determine image size
	var h, w float64
	for _, line := range e.Lines {
		if line.A.X > w {
			w = line.A.X
		}
		if line.A.Y > h {
			h = line.A.Y
		}
		if line.B.X > w {
			w = line.B.X
		}
		if line.B.Y > h {
			h = line.B.Y
		}
	}

	// Create the image
	f, err := os.Create(p)
	if err != nil {
		return err
	}
	defer f.Close()

	img := svg.New(f)
	img.Start(int(w), int(h))
	defer img.End()

	// Add the maze
	if len(hist) > 0 {
		img.Circle(int(hist[0].A.X), int(hist[0].A.Y), 4, `fill="green"`) // start
	}
	img.Circle(int(e.End.X), int(e.End.Y), 4, `fill="red"`)

	for _, line := range e.Lines {
		img.Path(fmt.Sprintf("M %f %f L %f %f", line.A.X, line.A.Y, line.B.X, line.B.Y), `stroke-width="1" stroke="black" fill="none"`)
	}

	for _, line := range hist {
		img.Path(fmt.Sprintf("M %f %f L %f %f", line.A.X, line.A.Y, line.B.X, line.B.Y), `stroke-width="1" stroke="blue" fill="none"`)

	}

	for _, point := range pts {
		img.Circle(int(point.X), int(point.Y), 1, `fill="green"`)
	}
	return nil
}
Пример #7
0
func TestDraw(t *testing.T) {
	f, err := os.Create("test_label.svg")
	if err != nil {
		t.Errorf("failed to create test.svg : %s\n", err)
	}
	defer f.Close()

	canvas := svg.New(f)
	defer canvas.End()

	s := "Braille Printer"
	bs, _ := brl.Encode(s)
	DrawLabel(canvas, bs)
}
Пример #8
0
// RandomGradientColorSVG builds a square image with with x colors selected at random for each quadrant.
// the background color stays the same the other colors get mixed in a gradient color from the first one to the last one.
func RandomGradientColorSVG(w http.ResponseWriter, colors, gColors []color.RGBA, gv colors.GradientVector, width, height, xsquares int, prob float64) {

	var gradientColors []svg.Offcolor
	gradientColors = make([]svg.Offcolor, len(gColors))
	percentage := uint8(0)
	step := uint8(100 / len(gColors))
	for i, c := range gColors {
		gradientColors[i] = svg.Offcolor{
			Offset:  percentage,
			Color:   draw.RGBToHex(c.R, c.G, c.B),
			Opacity: 1,
		}
		percentage += step
	}

	canvas := svg.New(w)
	canvas.Start(width, height)
	canvas.Def()
	canvas.LinearGradient("gradientColors", gv.X1, gv.Y1, gv.X2, gv.Y2, gradientColors)
	canvas.DefEnd()
	canvas.Rect(0, 0, width, height, "fill:url(#gradientColors)")

	squares := xsquares
	quadrantSize := width / squares
	colorMap := make(map[int]color.RGBA)
	colorIndex := make(map[int]int)
	for yQ := 0; yQ < squares; yQ++ {
		y := yQ * quadrantSize
		colorMap = make(map[int]color.RGBA)
		colorIndex = make(map[int]int)
		for xQ := 0; xQ <= squares+1; xQ++ {
			x := xQ * quadrantSize
			if _, ok := colorMap[xQ]; !ok {
				colorIndex[xQ] = draw.RandomIndexFromArrayWithFreq(colors, prob)
				colorMap[xQ] = colors[colorIndex[xQ]]
			}
			if colorIndex[xQ] == 0 {
				fill := draw.FillFromRGBA(colorMap[xQ])
				canvas.Rect(x, y, quadrantSize, quadrantSize, fill)
			}

		}
	}
	canvas.End()
}
Пример #9
0
// API: POST /printq/add
//   input: text to translation
//   lang: auto|ko|en
//   key: examplekey (TODO: OAuth implementation)
func printqAddHandler(w http.ResponseWriter, r *http.Request) {
	if strings.ToUpper(r.Method) != "POST" {
		http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
		return
	}

	/*
		var authKey string
		if strings.Contains(r.Referer(), "http://localhost") ||
			strings.Contains(r.Referer(), "http://braille-printer.appspot.com") {
			authKey = EXAMPLE_AUTHKEY
		} else {
			http.Error(w, "Unauthorized", http.StatusUnauthorized)
			return
		}
	*/

	authKey := r.FormValue("key")
	if authKey == "" {
		authKey = EXAMPLE_AUTHKEY
	}
	input := r.FormValue("input")
	lang := r.FormValue("lang")
	if lang == "" {
		// TODO: lang이 없거나 auto이면 언어 판단해야함
		lang = "ko"
	}

	label := "label"

	if strings.Contains(input, "\n") {
		label = "paper"
	}

	var bStr string

	if lang == "ko" {
		bStr, _ = brl_ko.Encode(input)
	} else if lang == "en" {
		bStr, _ = brl_en.Encode(input)
	}

	buf := bytes.NewBuffer(make([]byte, 24288))

	canvas := svg.New(buf)
	defer canvas.End()
	brl_svg.DrawPage30(canvas, bStr)

	printq := PrintQ{
		Type:       label,
		Key:        authKey,
		Origin:     input,
		ResultText: bStr,
		ResultSVG:  buf.Bytes(),
		Status:     0,
		CTime:      time.Now(),
	}

	c := appengine.NewContext(r)
	_, err := datastore.Put(c, datastore.NewIncompleteKey(c, "PrintQ", nil), &printq)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
}
Пример #10
0
// Graph takes an OpenTSDB request data structure and queries OpenTSDB. Use the
// json parameter to pass JSON. Use the b64 parameter to pass base64-encoded
// JSON.
func Graph(t miniprofiler.Timer, w http.ResponseWriter, r *http.Request) (interface{}, error) {
	j := []byte(r.FormValue("json"))
	if bs := r.FormValue("b64"); bs != "" {
		b, err := base64.StdEncoding.DecodeString(bs)
		if err != nil {
			return nil, err
		}
		j = b
	}
	if len(j) == 0 {
		return nil, fmt.Errorf("either json or b64 required")
	}
	oreq, err := opentsdb.RequestFromJSON(j)
	if err != nil {
		return nil, err
	}
	if ads_v := r.FormValue("autods"); ads_v != "" {
		ads_i, err := strconv.Atoi(ads_v)
		if err != nil {
			return nil, err
		}
		if err := oreq.AutoDownsample(ads_i); err != nil {
			return nil, err
		}
	}
	ar := make(map[int]bool)
	for _, v := range r.Form["autorate"] {
		if i, err := strconv.Atoi(v); err == nil {
			ar[i] = true
		}
	}
	queries := make([]string, len(oreq.Queries))
	var start, end string
	var startT, endT time.Time
	if s, ok := oreq.Start.(string); ok && strings.Contains(s, "-ago") {
		startT, err = opentsdb.ParseTime(s)
		if err != nil {
			return nil, err
		}
		start = strings.TrimSuffix(s, "-ago")
	}
	if s, ok := oreq.End.(string); ok && strings.Contains(s, "-ago") {
		endT, err = opentsdb.ParseTime(s)
		if err != nil {
			return nil, err
		}
		end = strings.TrimSuffix(s, "-ago")
	}
	if start == "" && end == "" {
		s, sok := oreq.Start.(int64)
		e, eok := oreq.End.(int64)
		if sok && eok {
			start = fmt.Sprintf("%vs", e-s)
			startT = time.Unix(s, 0)
			endT = time.Unix(e, 0)
			if err != nil {
				return nil, err
			}
		}
	}
	if endT.Equal(time.Time{}) {
		endT = time.Now().UTC()
	}
	m_units := make(map[string]string)
	for i, q := range oreq.Queries {
		if ar[i] {

			meta, err := schedule.MetadataMetrics(q.Metric)
			if err != nil {
				return nil, err
			}
			if meta == nil {
				return nil, fmt.Errorf("no metadata for %s: cannot use auto rate", q)
			}
			if meta.Unit != "" {
				m_units[q.Metric] = meta.Unit
			}
			if meta.Rate != "" {
				switch meta.Rate {
				case metadata.Gauge:
					// ignore
				case metadata.Rate:
					q.Rate = true
				case metadata.Counter:
					q.Rate = true
					q.RateOptions = opentsdb.RateOptions{
						Counter:    true,
						ResetValue: 1,
					}
				default:
					return nil, fmt.Errorf("unknown metadata rate: %s", meta.Rate)
				}
			}
		}
		queries[i] = fmt.Sprintf(`q("%v", "%v", "%v")`, q, start, end)
		if !schedule.SystemConf.GetTSDBContext().Version().FilterSupport() {
			if err := schedule.Search.Expand(q); err != nil {
				return nil, err
			}
		}
	}
	var tr opentsdb.ResponseSet
	b, _ := json.MarshalIndent(oreq, "", "  ")
	t.StepCustomTiming("tsdb", "query", string(b), func() {
		h := schedule.SystemConf.GetTSDBHost()
		if h == "" {
			err = fmt.Errorf("tsdbHost not set")
			return
		}
		tr, err = oreq.Query(h)
	})
	if err != nil {
		return nil, err
	}
	cs, err := makeChart(tr, m_units)
	if err != nil {
		return nil, err
	}
	if _, present := r.Form["png"]; present {
		c := chart.ScatterChart{
			Title: fmt.Sprintf("%v - %v", oreq.Start, queries),
		}
		c.XRange.Time = true
		if min, err := strconv.ParseFloat(r.FormValue("min"), 64); err == nil {
			c.YRange.MinMode.Fixed = true
			c.YRange.MinMode.Value = min
		}
		if max, err := strconv.ParseFloat(r.FormValue("max"), 64); err == nil {
			c.YRange.MaxMode.Fixed = true
			c.YRange.MaxMode.Value = max
		}
		for ri, r := range cs {
			pts := make([]chart.EPoint, len(r.Data))
			for idx, v := range r.Data {
				pts[idx].X = v[0]
				pts[idx].Y = v[1]
			}
			slice.Sort(pts, func(i, j int) bool {
				return pts[i].X < pts[j].X
			})
			c.AddData(r.Name, pts, chart.PlotStyleLinesPoints, sched.Autostyle(ri))
		}
		w.Header().Set("Content-Type", "image/svg+xml")
		white := color.RGBA{0xff, 0xff, 0xff, 0xff}
		const width = 800
		const height = 600
		s := svg.New(w)
		s.Start(width, height)
		s.Rect(0, 0, width, height, "fill: #ffffff")
		sgr := svgg.AddTo(s, 0, 0, width, height, "", 12, white)
		c.Plot(sgr)
		s.End()
		return nil, nil
	}
	var a []annotate.Annotation
	warnings := []string{}
	if schedule.SystemConf.AnnotateEnabled() {
		a, err = annotateBackend.GetAnnotations(&startT, &endT)
		if err != nil {
			warnings = append(warnings, fmt.Sprintf("unable to get annotations: %v", err))
		}
	}
	return struct {
		Queries     []string
		Series      []*chartSeries
		Annotations []annotate.Annotation
		Warnings    []string
	}{
		queries,
		cs,
		a,
		warnings,
	}, nil
}
Пример #11
0
// RandomGradientColor builds a isogrid image with with x colors selected at random for each quadrant.
// the background color stays the same the other colors get mixed in a gradient color from the first one to the last one.
func RandomGradientColor(w http.ResponseWriter, colors, gColors []color.RGBA, gv colors.GradientVector, width, height, lines int, prob float64) {

	var gradientColors []svg.Offcolor
	gradientColors = make([]svg.Offcolor, len(gColors))
	percentage := uint8(0)

	step := uint8(100 / len(gColors))
	for i, c := range gColors {
		gradientColors[i] = svg.Offcolor{
			Offset:  percentage,
			Color:   draw.RGBToHex(c.R, c.G, c.B),
			Opacity: 1,
		}
		percentage += step
	}

	canvas := svg.New(w)
	canvas.Start(width, height)
	canvas.Def()
	canvas.LinearGradient("gradientColors", gv.X1, gv.Y1, gv.X2, gv.Y2, gradientColors)
	canvas.DefEnd()
	canvas.Rect(0, 0, width, height, "fill:url(#gradientColors)")

	fringeSize := width / lines
	distance := distanceTo3rdPoint(fringeSize)
	fringeSize = distance
	lines = width / fringeSize

	colorMap := make(map[int]color.RGBA)
	colorIndex := make(map[int]int)

	for xL := 0; xL <= lines; xL++ {
		colorMap = make(map[int]color.RGBA)
		colorIndex = make(map[int]int)
		for yL := -1; yL <= lines; yL++ {
			var x1, x2, y1, y2, y3 int
			if (xL % 2) == 0 {
				x1, y1, x2, y2, _, y3 = right1stTriangle(xL, yL, fringeSize, distance)
			} else {
				x1, y1, x2, y2, _, y3 = left1stTriangle(xL, yL, fringeSize, distance)
			}
			xs := []int{x2, x1, x2}
			ys := []int{y1, y2, y3}

			colorIndex[yL] = draw.RandomIndexFromArrayWithFreq(colors, prob)
			colorMap[yL] = colors[colorIndex[yL]]

			if colorIndex[yL] == 0 {
				canvas.Polygon(xs, ys, draw.FillFromRGBA(colorMap[yL]))
			}

			var x11, x12, y11, y12, y13 int
			if (xL % 2) == 0 {
				x11, y11, x12, y12, _, y13 = left2ndTriangle(xL, yL, fringeSize, distance)

				// we make sure that the previous triangle and this one touch each other in this point.
				y12 = y3
			} else {
				x11, y11, x12, y12, _, y13 = right2ndTriangle(xL, yL, fringeSize, distance)

				// we make sure that the previous triangle and this one touch each other in this point.
				y12 = y1 + fringeSize
			}
			xs1 := []int{x12, x11, x12}
			ys1 := []int{y11, y12, y13}

			colorIndex[yL] = draw.RandomIndexFromArrayWithFreq(colors, prob)
			colorMap[yL] = colors[colorIndex[yL]]

			if colorIndex[yL] == 0 {
				canvas.Polygon(xs1, ys1, draw.FillFromRGBA(colorMap[yL]))
			}
		}
	}
	canvas.End()
}
Пример #12
0
Файл: web.go Проект: NioTeX/neat
func visualizeBest(v *Web) error {

	// Create the file
	f, err := os.Create(v.makePath("network"))
	if err != nil {
		return err
	}
	defer f.Close()

	best := v.best[len(v.best)-1]
	net0, err := v.ctx.Decoder().Decode(best)
	if err != nil {
		return err
	}
	var net *network.Classic
	p, ok := net0.(decoder.Phenome)
	if !ok {
		return errors.New("Web visualizer only knows the decoder package's phenome")
	}
	net, ok = p.Network.(*network.Classic)
	if !ok {
		return errors.New("Web visualizer only knows the Clasic network")
	}

	// Create the image
	img := svg.New(f)
	w, h := 1024.0, 1280.0
	img.Start(int(w)+30, int(h)+30)
	defer img.End()

	// Write out the title
	img.Text(10, 10, fmt.Sprintf("Best Genome is %d", best.ID), `font-size="12"`)

	// Define connection heads
	img.Def()
	img.Marker("triangle_black", 0, 10, 8, 6, `viewBox="0 0 20 20" markerUnits="strokeWidth" orient="auto"`)
	img.Path("M 0 0 L 20 10 L 0 20 z", `fill="black" fill-opacity="0.8"`)
	img.MarkerEnd()
	img.Marker("triangle_red", 0, 10, 8, 6, `viewBox="0 0 20 20" markerUnits="strokeWidth" orient="auto"`)
	img.Path("M 0 0 L 20 10 L 0 20 z", `fill="red" fill-opacity="0.8"`)
	img.MarkerEnd()
	img.DefEnd()

	// Draw neurons
	for i, neuron := range net.Neurons {
		var node_color, font_color string
		switch neuron.NeuronType {
		case neat.Bias:
			node_color = "black"
			font_color = "white"
		case neat.Input:
			node_color = "paleturquoise"
			font_color = "black"
		case neat.Hidden:
			node_color = "palegreen"
			font_color = "black"
		case neat.Output:
			node_color = "thistle"
			font_color = "black"
		}
		cx := int(neuron.X*w) + 15
		cy := int((1.0-neuron.Y)*h) + 15
		img.Circle(cx, cy, 10, fmt.Sprintf(`fill="%s" stroke="black" stroke-width="1"`, node_color))
		img.Text(cx-3, cy+3, fmt.Sprintf(`%d`, i+1), fmt.Sprintf(`font-size="5pt" fill="%s"`, font_color))
	}

	// Draw synapses
	for _, synapse := range net.Synapses {
		src := net.Neurons[synapse.Source]
		tgt := net.Neurons[synapse.Target]
		fromX := int(src.X*w) + 15
		fromY := int((1.0-src.Y)*h) + 15
		toX := int(tgt.X*w) + 15
		toY := int((1.0-tgt.Y)*h) + 15

		var line_color, triangle_color string
		if synapse.Weight >= 0 {
			line_color = "black"
			triangle_color = "#triangle_black"
		} else {
			line_color = "red"
			triangle_color = "#triangle_red"
		}

		var opacity, strokewidth string
		switch {
		case synapse.Weight < 1.0 && synapse.Weight >= 0.5, synapse.Weight > -1.0 && synapse.Weight <= -0.5:
			opacity = "0.8"
			strokewidth = "0.3"
		case synapse.Weight >= 1.0, synapse.Weight <= -1.0:
			opacity = "1.0"
			strokewidth = "0.3"
		default:
			opacity = "0.5"
			strokewidth = "1.0"
		}
		img.Path(fmt.Sprintf("M %v %v L %v %v", fromX, fromY, toX, toY), fmt.Sprintf(`fill="none" stroke="%s" stroke-width="%s" stroke-opacity="%s" marker-end="%s"`, line_color, strokewidth, opacity, triangle_color))
	}

	f.WriteString(fmt.Sprintf("<P>%s</P>", strings.Replace(best.String(), "\n", "<BR/>", -1)))
	f.WriteString(fmt.Sprintf("<P>%s</P>", strings.Replace((*net).String(), "\n", "<BR/>", -1)))
	return nil
}
Пример #13
0
Файл: web.go Проект: NioTeX/neat
func visualizeSpecies(v *Web) error {

	// Create the file
	f, err := os.Create(v.makePath("species"))
	if err != nil {
		return err
	}
	defer f.Close()

	// Identify the max population size
	popSize := 0
	for _, h := range v.species {
		cnt := 0
		for _, s := range h {
			cnt += s
		}
		if cnt > popSize {
			popSize = cnt
		}
	}
	if popSize == 0 {
		return nil
	}

	// Create the image
	img := svg.New(f)
	img.Start(popSize*2+400, 460)
	defer img.End()

	//img.Text(10, 10, fmt.Sprintf("ID=%d Time/Date=%v", ?, ?), `style="font-size:12"`)
	img.Text(10, 25, fmt.Sprintf("PopSize=%d NumGenerations=%d", popSize, len(v.species)), `style="font-size:10"`)
	img.Path("M 40 340 L 540 340", `id="generation" stroke-width="1" stroke="black" fill="none"`)
	img.Textpath("Generation", "#generation", `fill="blue" font-size="12" font-family="Verdana" dy="30" startOffset="25%"`)
	img.Path("M 140 345 L 140 340", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 240 345 L 240 340", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 340 345 L 340 340", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 440 345 L 440 340", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 540 345 L 540 340", `stroke-width="1" stroke="black" fill="none"`)
	img.Text(132, 355, fmt.Sprintf("%d", len(v.species)/5*1), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(232, 355, fmt.Sprintf("%d", len(v.species)/5*2), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(332, 355, fmt.Sprintf("%d", len(v.species)/5*3), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(432, 355, fmt.Sprintf("%d", len(v.species)/5*4), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(532, 355, fmt.Sprintf("%d", len(v.species)/5*5), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(5, 75, "# of Individuals", `style="writing-mode: tb; glyph-orientation-vertical:0; fill: blue; font-size: 10; font-family: Verdana;"`)
	img.Text(15, 285, fmt.Sprintf("%d", int(float64(popSize)*0.2)), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(15, 225, fmt.Sprintf("%d", int(float64(popSize)*0.4)), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(15, 165, fmt.Sprintf("%d", int(float64(popSize)*0.6)), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(15, 105, fmt.Sprintf("%d", int(float64(popSize)*0.8)), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(15, 45, fmt.Sprintf("%d", int(float64(popSize)*1.0)), `fill="black" font-size="11" font-family="Verdana"`)

	popIncrement := 300 / popSize
	for i, generation := range v.species {
		xplot := 500/len(v.species)*i + 42

		for j, speciesCount := range generation {
			var speciesColor string
			switch j % 3 {
			case 0:
				speciesColor = "CornflowerBlue"
			case 1:
				speciesColor = "Yellow"
			case 2:
				speciesColor = "Plum"
			default:
				speciesColor = "Chartreuse"
			}
			yplotFrom := 340.0
			for k := 0; k < j; k++ {
				yplotFrom -= float64(generation[k] * popIncrement)
			}

			yplotTo := yplotFrom - float64(speciesCount*popIncrement) + 0.5
			img.Path(fmt.Sprintf("M %v %v L %v %v", xplot, yplotFrom, xplot, yplotTo), fmt.Sprintf(`stroke-width="3" stroke="%s" fill="none"`, speciesColor))
		}
	}
	return nil
}
Пример #14
0
Файл: web.go Проект: NioTeX/neat
func visualizeComplexity(v *Web) error {
	// Create the file
	f, err := os.Create(v.makePath("complexity"))
	if err != nil {
		return err
	}
	defer f.Close()

	// Create the image
	img := svg.New(f)
	img.Start(575, 375)
	defer img.End()

	// Draw and label horizontal axis
	img.Path("M 40 340 L 540 340", `id="generation" stroke-width="1" stroke="black" fill="none"`)
	img.Textpath("Generation", "#generation", `fill="blue" font-size="15" font-family="Verdana" dy="30" startOffset="40%"`)

	img.Path("M 140 345 L 140 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 240 345 L 240 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 340 345 L 340 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 440 345 L 440 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 540 345 L 540 335", `stroke-width="1" stroke="black" fill="none"`)

	generations := len(v.complexity)
	img.Text(132, 355, fmt.Sprintf("%d", generations/5*1), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(232, 355, fmt.Sprintf("%d", generations/5*2), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(332, 355, fmt.Sprintf("%d", generations/5*3), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(432, 355, fmt.Sprintf("%d", generations/5*4), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(532, 355, fmt.Sprintf("%d", generations/5*5), `fill="black" font-size="11" font-family="Verdana"`)

	// Draw and label veritical axis
	img.Path("M 40 340 L 40 40", `id="complexity" stroke-width="1" strok="black" fill="none"`)
	img.Textpath("Number of Genes", "#complexity", `fill="blue" font-size="15" font-family="Verdana" dy="-25" startOffset="40%"`)

	var complexity_max, complexity_min float64
	complexity_min = 9e10
	for _, generation := range v.complexity {
		if generation[0] < complexity_min {
			complexity_min = generation[0]
		}
		if generation[2] > complexity_max {
			complexity_max = generation[2]
		}
	}
	complexity_range := complexity_max - complexity_min

	img.Path("M 40 40 L 540 40", `id="complexity1" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%v", complexity_range+complexity_min), "#complexity1", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="90%"`)

	img.Path("M 40 100 L 540 100", `id="complexity2" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%v", int(complexity_range*0.8+complexity_min)), "#complexity2", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="70%"`)

	img.Path("M 40 160 L 540 160", `id="complexity3" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%v", int(complexity_range*0.6+complexity_min)), "#complexity3", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="50%"`)

	img.Path("M 40 220 L 540 220", `id="complexity4" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%v", int(complexity_range*0.4+complexity_min)), "#complexity4", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="30%"`)

	img.Path("M 40 280 L 540 280", `id="complexity5" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%v", int(complexity_range*0.2+complexity_min)), "#complexity5", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="10%"`)

	img.Textpath(fmt.Sprintf("%v", int(complexity_min)), "#generation", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="0%"`)

	for i, generation := range v.complexity {
		complexityMax := generation[2]
		complexityMin := generation[0]
		complexityAvg := generation[1]
		complexityChamp := generation[3]

		xplot := 500/generations*i + 40
		yplotMax := 340 - 300/complexity_range*(complexityMax-complexity_min)
		yplotMin := 340 - 300/complexity_range*(complexityMin-complexity_min)
		yplotAvg := 340 - 300/complexity_range*(complexityAvg-complexity_min)
		yplotChamp := 340 - 300/complexity_range*(complexityChamp-complexity_min)

		img.Path(fmt.Sprintf("M %v %v L %v %v L %v %v z", xplot-2, yplotChamp-2, xplot, yplotChamp-6, xplot+2, yplotChamp-2), fmt.Sprintf(`id="%d" fill="red"`, i))
		img.Circle(xplot, int(yplotAvg), 1, fmt.Sprintf(`id="%d" fill="black"`, i))
		img.Path(fmt.Sprintf("M %v %v L %v %v", xplot, yplotMin, xplot, yplotMax), `stroke-width="0.5" stroke="blue" fill="none"`)
	}
	return nil
}
Пример #15
0
Файл: web.go Проект: NioTeX/neat
func visualizeFitness(v *Web) error {
	// Create the file
	f, err := os.Create(v.makePath("fitness"))
	if err != nil {
		return err
	}
	defer f.Close()

	// Create the image
	img := svg.New(f)
	img.Start(575, 375)
	defer img.End()

	// Draw and label horizontal axis
	img.Path("M 40 340 L 540 340", `id="generation" stroke-width="1" stroke="black" fill="none"`)
	img.Textpath("Generation", "#generation", `fill="blue" font-size="15" font-family="Verdana" dy="30" startOffset="40%"`)

	img.Path("M 140 345 L 140 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 240 345 L 240 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 340 345 L 340 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 440 345 L 440 335", `stroke-width="1" stroke="black" fill="none"`)
	img.Path("M 540 345 L 540 335", `stroke-width="1" stroke="black" fill="none"`)

	generations := len(v.fitness)
	img.Text(132, 355, fmt.Sprintf("%d", generations/5*1), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(232, 355, fmt.Sprintf("%d", generations/5*2), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(332, 355, fmt.Sprintf("%d", generations/5*3), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(432, 355, fmt.Sprintf("%d", generations/5*4), `fill="black" font-size="11" font-family="Verdana"`)
	img.Text(532, 355, fmt.Sprintf("%d", generations/5*5), `fill="black" font-size="11" font-family="Verdana"`)

	// Draw and label veritical axis
	img.Path("M 40 340 L 40 40", `id="fitness" stroke-width="1" strok="black" fill="none"`)
	img.Textpath("Fitness", "#fitness", `fill="blue" font-size="15" font-family="Verdana" dy="-25" startOffset="40%"`)

	var fitness_max, fitness_min float64
	fitness_min = 9e10
	for _, generation := range v.fitness {
		if generation[0] < fitness_min {
			fitness_min = generation[0]
		}
		if generation[2] > fitness_max {
			fitness_max = generation[2]
		}
	}
	fitness_range := fitness_max - fitness_min

	img.Path("M 40 40 L 540 40", `id="fitness1" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%2f", fitness_range+fitness_min), "#fitness1", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="90%"`)

	img.Path("M 40 100 L 540 100", `id="fitness2" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%2f", (fitness_range*0.8+fitness_min)), "#fitness2", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="70%"`)

	img.Path("M 40 160 L 540 160", `id="fitness3" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%2f", (fitness_range*0.6+fitness_min)), "#fitness3", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="50%"`)

	img.Path("M 40 220 L 540 220", `id="fitness4" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%2f", (fitness_range*0.4+fitness_min)), "#fitness4", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="30%"`)

	img.Path("M 40 280 L 540 280", `id="fitness5" stroke-width="0.5" stroke="green" fill="none"`)
	img.Textpath(fmt.Sprintf("%2f", (fitness_range*0.2+fitness_min)), "#fitness5", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="10%"`)

	img.Textpath(fmt.Sprintf("%2f", (fitness_min)), "#generation", `fill="green" fill-opacity="1.0" font-size="9" font-family="Verdana" dy="8" startOffset="0%"`)

	for i, generation := range v.fitness {

		fitnessMax := generation[2]
		fitnessMin := generation[0]
		fitnessAvg := generation[1]

		xplot := 500/generations*i + 40
		yplotMax := 340 - 300/fitness_range*(fitnessMax-fitness_min)
		yplotMin := 340 - 300/fitness_range*(fitnessMin-fitness_min)
		yplotAvg := 340 - 300/fitness_range*(fitnessAvg-fitness_min)

		img.Circle(xplot, int(yplotAvg), 1, fmt.Sprintf(`id="%d" fill="black"`, i))
		img.Path(fmt.Sprintf("M %v %v L %v %v", xplot, yplotMin, xplot, yplotMax), `stroke-width="0.5" stroke="blue" fill="none"`)
	}
	return nil
}