Beispiel #1
0
/*
 * create evenly spread out ticks along the y axis.
 * The ticks are labeled as it goes
 */
void set_yticks(struct plot *plot, int num_ticks, int first, int last, char *units)
{
	int pixels_per_tick = graph_height / num_ticks;
	int step = (last - first) / num_ticks;
	int i;
	int tick_y = 0;
	int text_x = axis_x() - 6;
	int tick_x = axis_x();
	char *anchor = "end";

	for (i = 0; i < num_ticks; i++) {
		if (i != 0) {
			snprintf(line, line_len, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" "
				 "style=\"stroke:lightgray;stroke-width:2;stroke-dasharray:9,12;\"/>\n",
				tick_x, axis_y_off(tick_y),
				axis_x_off(graph_width), axis_y_off(tick_y));
			write_check(plot->fd, line, strlen(line));
		}

		snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
			 "fill=\"black\" style=\"text-anchor: %s\">%d%s</text>\n",
			text_x,
			axis_y_off(tick_y - tick_font_size / 2),
			font_family, tick_font_size, anchor, first + step * i, units);
		write_check(plot->fd, line, strlen(line));
		tick_y += pixels_per_tick;
	}
	snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
		 "fill=\"black\" style=\"text-anchor: %s\">%d%s</text>\n",
		 text_x, axis_y_off(graph_height), font_family, tick_font_size, anchor, last, units);
	write_check(plot->fd, line, strlen(line));
}
Beispiel #2
0
/*
 * this draws a backing rectangle for the plot and it
 * also creates a new svg element so our offsets can
 * be relative to this one plot.
 */
void setup_axis(struct plot *plot)
{
	int len;
	int fd = plot->fd;
	int bump_height = tick_font_size * 3 + axis_label_font_size;
	int local_legend_width = legend_width;

	if (plot->no_legend)
		local_legend_width = 0;

	plot->total_width = axis_x_off(graph_width) + graph_left_pad / 2 + local_legend_width;
	plot->total_height = axis_y() + tick_label_pad + tick_font_size;

	if (plot->add_xlabel)
		plot->total_height += bump_height;

	/* backing rect */
	snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
		 "height=\"%d\" fill=\"white\" stroke=\"none\"/>",
		 plot->start_x_offset,
		plot->start_y_offset, plot->total_width + 40,
		plot->total_height + 20);
	len = strlen(line);
	write_check(fd, line, len);

	snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"%d\" "
		 "filter=\"url(#shadow)\" "
		 "height=\"%d\" fill=\"white\" stroke=\"none\"/>",
		 plot->start_x_offset + 15,
		plot->start_y_offset, plot->total_width, plot->total_height);
	len = strlen(line);
	write_check(fd, line, len);
	plot->total_height += 20;
	plot->total_width += 20;

	if (plot->total_height + plot->start_y_offset > final_height)
		final_height = plot->total_height + plot->start_y_offset;
	if (plot->start_x_offset + plot->total_width + 40 > final_width)
		final_width = plot->start_x_offset + plot->total_width + 40;

	/* create an svg object for all our coords to be relative against */
	snprintf(line, line_len, "<svg x=\"%d\" y=\"%d\">\n", plot->start_x_offset, plot->start_y_offset);
	write_check(fd, line, strlen(line));

	snprintf(line, 1024, "<path d=\"M%d %d h %d V %d H %d Z\" stroke=\"black\" stroke-width=\"2\" fill=\"none\"/>\n",
		 axis_x(), axis_y(),
		 graph_width + graph_inner_x_margin * 2, axis_y_off(graph_height) - graph_inner_y_margin,
		 axis_x());
	len = strlen(line);
	write_check(fd, line, len);
}
Beispiel #3
0
void set_plot_label(struct plot *plot, char *label)
{
	int len;
	int fd = plot->fd;

	snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" "
		 "font-size=\"%d\" fill=\"black\" style=\"text-anchor: %s\">%s</text>\n",
		 axis_x() + graph_width / 2,
		 plot_label_height / 2,
		font_family, plot_label_font_size, "middle", label);
	len = strlen(line);
	write_check(fd, line, len);
}
Beispiel #4
0
/*
 * create evenly spread out ticks along the xaxis.  if tick only is set
 * this just makes the ticks, otherwise it labels each tick as it goes
 */
void set_xticks(struct plot *plot, int num_ticks, int first, int last)
{
	int pixels_per_tick;
	double step;
	int i;
	int tick_y = axis_y_off(graph_tick_len) + graph_inner_y_margin;
	int tick_x = axis_x();
	int tick_only = plot->add_xlabel == 0;

	int text_y = axis_y() + tick_label_pad;

	char *middle = "middle";
	char *start = "start";

	step = find_step(first, last, num_ticks);
	/*
	 * We don't want last two ticks to be too close together so subtract
	 * 20% of the step from the interval
	 */
	num_ticks = (double)(last - first - step) / step + 1;
	pixels_per_tick = graph_width * step / (double)(last - first);

	for (i = 0; i < num_ticks; i++) {
		char *anchor;
		if (i != 0) {
			snprintf(line, line_len, "<rect x=\"%d\" y=\"%d\" width=\"2\" height=\"%d\" style=\"stroke:none;fill:black;\"/>\n",
				tick_x, tick_y, graph_tick_len);
			write_check(plot->fd, line, strlen(line));
			anchor = middle;
		} else {
			anchor = start;
		}

		if (!tick_only) {
			if (step >= 1)
				snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
					"fill=\"black\" style=\"text-anchor: %s\">%d</text>\n",
					tick_x, text_y, font_family, tick_font_size, anchor,
					(int)(first + step * i));
			else
				snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
					"fill=\"black\" style=\"text-anchor: %s\">%.2f</text>\n",
					tick_x, text_y, font_family, tick_font_size, anchor,
					first + step * i);
			write_check(plot->fd, line, strlen(line));
		}
		tick_x += pixels_per_tick;
	}

	if (!tick_only) {
		if (step >= 1)
			snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
				"fill=\"black\" style=\"text-anchor: middle\">%d</text>\n",
				axis_x_off(graph_width - 2),
				text_y, font_family, tick_font_size, last);
		else
			snprintf(line, line_len, "<text x=\"%d\" y=\"%d\" font-family=\"%s\" font-size=\"%d\" "
				"fill=\"black\" style=\"text-anchor: middle\">%.2f</text>\n",
				axis_x_off(graph_width - 2),
				text_y, font_family, tick_font_size, (double)last);
		write_check(plot->fd, line, strlen(line));
	}
}
Beispiel #5
0
QImage Plotter::makePlot()
{
  QImage img=QImage(width,height,QImage::Format_RGB32);
  img.fill(0xffffff);
  QPainter painter(&img);
  painter.setFont(QFont(painter.font().family(),_fs));
  //Отступы
  QFontMetrics metrics(painter.font());
  std::vector<int> lens;
  foreach(QString str,_text_y)
    lens.push_back(str.size());

  float ident_left;
  std::vector<int>::const_iterator it, it2;
  for(int i=0;i<lens.size(); i++)
  {
    it2 = std::max_element(lens.begin(), lens.end());
    if(lens.at(i)==*it2)
    {
      ident_left=metrics.width(_text_y[i])+metrics.width(_text_y[i])/5;
      break;
    }
  }

  float ident_right=metrics.width(_text_x[_text_x.size()-1])+metrics.width(_text_x[_text_x.size()-1])/5;

  //Шаги и отступы снизу и сверху
  float step_x=(width-ident_right-ident_left)/_text_x.size();
  float step_y=height/(_text_y.size()+1);
  float ident_bottom=step_y+_fs;
  float ident_top=step_y+_fs;
  step_y=(height-ident_top-ident_bottom)/(_text_y.size());
  //Оси
  QLineF axis_x(ident_left,height-ident_bottom,width-ident_right,height-ident_bottom);
  QLineF axis_y(ident_left,height-ident_bottom,ident_left,ident_top);

  //Черточки и подписи
  QVector<QLineF> x_hyphen;
  float hx_size=step_x/10;
  float hy_size=step_y/10;
  QList<QRectF> text_x_pos;

  QStringList sl_x = _text_x.split(";",QString::SkipEmptyParts);
  for(int i=0; i<sl_x.size();i++)
  {
    if(i<sl_x.size()-1)
      x_hyphen.append(QLineF(ident_left+(i+1)*step_x,height-ident_bottom-hx_size,ident_left+(i+1)*step_x,height-ident_bottom));

    QFontMetrics metrics(painter.font());

    if(i==sl_x.size()-1)
    {
      text_x_pos.append(QRectF(ident_left+(i+1)*step_x,height-ident_bottom+_fs+hy_size*2,step_x,ident_bottom-_fs-hy_size*2));
      //text_x_pos.append(QRectF(x,y,w,h))
    }
    else
    {
      //text_x_pos.append(QPointF(ident_left+(i+1)*step_x-metrics.width(text_x[i])/2,height-ident_bottom+font+hy_size*2))
      text_x_pos.append(QRectF(ident_left+(i+1)*step_x-metrics.width(sl_x[i])/2,height-ident_bottom+_fs+hy_size*2,step_x,ident_bottom-_fs-hy_size*2));
    }
  }

  QVector<QLineF> y_hyphen;
  QList<QPointF> text_y_pos;
  QStringList sl_y = _text_y.split(";",QString::SkipEmptyParts);
  for(int i=0; i<sl_y.size();i++)
  {
    if(i<sl_y.size()-1)
      y_hyphen.append(QLineF(ident_left,height-ident_bottom-(i+1)*step_y,ident_left+hy_size,height-ident_bottom-(i+1)*step_y));

    QFontMetrics metrics(painter.font());

    if(i==sl_y.size()-1)
      text_y_pos.append(QPointF(ident_left-metrics.width(sl_y[i])/2,ident_top/2+_fs/2));
    else
      text_y_pos.append(QPointF(ident_left-metrics.width(sl_y[i])-hy_size,height-ident_bottom-(i+1)*step_y+_fs/2));
  }

  //Точки графика
  QVector<QPoint> graph_points;
  QVector<QLineF> dot_line_x;
  QVector<QLineF> dot_line_y;

  int dataCount = scriptEngine->evaluate("results.length").toInteger();


  for(int i=0;i<dataCount; i++)
  {
    QScriptValue index = QScriptValue(i);
    scriptEngine->globalObject().setProperty("index",index);
    float curResult = (float)scriptEngine->evaluate("results[index]").toNumber();

    graph_points.append(QPoint(ident_left+step_x*(i+1),height-(ident_bottom+curResult*step_y)));
    dot_line_x.append(QLineF(QPointF(ident_left,graph_points[graph_points.size()-1].y()),graph_points[graph_points.size()-1]));
    dot_line_y.append(QLineF(QPointF(graph_points[graph_points.size()-1].x(),height-ident_bottom),graph_points[graph_points.size()-1]));
  }

  //Перья для рисования
  QPen axis_pen(Qt::black);
  axis_pen.setWidth(4);

  QPen dot_pen(Qt::black);
  dot_pen.setWidth(1);
  dot_pen.setStyle(Qt::DotLine);

  QPen main_pen(Qt::black);
  main_pen.setWidth(2);

  QPen point_pen(Qt::red);
  point_pen.setWidth(4);

  //Рисуем
  //Оси
  painter.setRenderHint(QPainter::Antialiasing);
  painter.setPen(axis_pen);
  painter.drawLine(axis_x);
  painter.drawLine(axis_y);
  //Черточки и подписи
  painter.setPen(main_pen);
  painter.drawLines(x_hyphen);
  painter.drawLines(y_hyphen);
  for(int i=0; i<text_x_pos.size(); i++)
  {
    if(i==text_x_pos.size()-1)
    {
      QFont nf(painter.font());
      nf.setWeight(QFont::Bold);
      painter.setFont(nf);
      painter.drawText(text_x_pos[i],QString(sl_x[i]));
      nf.setWeight(QFont::Normal);
      painter.setFont(nf);
    }
    else
      painter.drawText(text_x_pos[i],Qt::TextWordWrap,QString(sl_x[i]));
  }

  for(int i=0;i<text_y_pos.size();i++)
  {
    if(i==text_y_pos.size()-1)
    {
      QFont nf(painter.font());
      nf.setWeight(QFont::Bold);
      painter.setFont(nf);
      painter.drawText(text_y_pos[i],QString(sl_y[i]));
      nf.setWeight(QFont::Normal);
      painter.setFont(nf);
    }
    else
      painter.drawText(text_y_pos[i],QString(sl_y[i]));
  }
  //График
  QPolygon p(graph_points);
  painter.drawPolyline(p);
  //Пунктирные линии
  painter.setRenderHint(QPainter::Antialiasing,false);
  painter.setPen(dot_pen);
  painter.drawLines(dot_line_x);
  painter.drawLines(dot_line_y);
  //Точки графика
  painter.setRenderHint(QPainter::Antialiasing);
  painter.setPen(point_pen);
  painter.drawPoints(p);
  return img;
}