/// Получение размерностей заданной по id кривой
QPointF GraphicDisplay::dimensions(int id)
{
QString x_dimension(fact_prm[id].dimension[language_flag].toLower());
double x_dim = (metric_map[x_dimension]) ? metric_map[x_dimension] : 1.0;
QString y_dimension(fact_prm[id].y_dim[language_flag].toLower());
double y_dim = (metric_map[y_dimension]) ? metric_map[y_dimension] : 1.0;
return QPointF(x_dim, y_dim);
}
/// Поиск точки пересечения визира с графиком (в реальных координатах - следует переводить в экранные)
QPointF GraphicDisplay::findCrossPoint(const QPointF& pnt, const QPointF& prev_pnt, const QPointF& pnt_vf)
{
double curr_x = pnt.x(), curr_y = pnt.y(), prev_x = prev_pnt.x(), prev_y = prev_pnt.y(), y_vf = pnt_vf.y(),
x_vf = pnt_vf.x();
double y = prev_y + (curr_y - prev_y) * (x_vf - prev_x) / (curr_x - prev_x),
x = prev_x + (curr_x - prev_x) * (y_vf - prev_y) / (curr_y - prev_y);
if(curr_y - prev_y == 0.) x = curr_x;
if(curr_x - prev_x == 0.) y = curr_y;
return QPointF(x, y);
}
/// Отображение текста точки пересечения визира с графиком
void GraphicDisplay::drawViewfinderText(QPainter* painter, const QPointF& coord, const QPen& pen,
double coordinate)
{
QBrush oldBrush(pen.color());
QPen oldPen(pen.color());
painter -> setBrush(pen.color());
QColor color((pen.color() == QColor(Qt::blue)) ? Qt::darkGreen : Qt::blue);
painter -> setPen(color);
painter -> drawText(coord, QString::number(coordinate));
painter -> setPen(oldPen);
painter -> setBrush(oldBrush);
}
/// Отображение координат пересечения с визиром
void GraphicDisplay::viewCoordViewfinder(QPainter* painter, int id, const QVector<SpecPointF>& data, int index)
{
if(!v_viewfinderAction -> isChecked() && !h_viewfinderAction -> isChecked()) return;
QPointF dim(dimensions(id));
double real_y = data[index].y(), prev_ry = data[index - 1].y(),
real_x = (settings.win_type != COUNTPARAM) ? data[index].x() * dim.x() : data[index].x(),
prev_rx = (settings.win_type != COUNTPARAM) ? data[index - 1].x() * dim.x() : data[index - 1].x();
QPointF pnt(initXY(real_x, real_y)), prev_pnt(initXY(prev_rx, prev_ry)), rl_pnt(real_x, real_y),
prev_rl_pnt(prev_rx, prev_ry);
foreach(VFFrame* pf, viewfinderList)
{
QPoint screen_pnt_vf(pf -> x(), pf -> y());
QPointF pnt_vf(initXY(&screen_pnt_vf));
double prev_x = prev_rl_pnt.x(), prev_y = prev_rl_pnt.y(), curr_x = rl_pnt.x(), curr_y = rl_pnt.y();
double x_vf = pnt_vf.x(), y_vf = pnt_vf.y();
QPointF res_point(findCrossPoint(rl_pnt, prev_rl_pnt, pnt_vf));
double result_x = res_point.x(), result_y = res_point.y();
QPointF crd_scr(initXY(result_x, result_y));
if(pf -> frameShape() == QFrame::VLine && v_viewfinderAction -> isChecked() &&
prev_x <= x_vf && curr_x > x_vf)
{
QPointF coord(pf -> x() + 15, crd_scr.y() - 1.);
drawViewfinderText(painter, coord, painter -> pen(), res_point.y());
}
else if(pf -> frameShape() == QFrame::HLine && h_viewfinderAction -> isChecked() &&
prev_y <= y_vf && curr_y > y_vf)
{
QPointF coord(crd_scr.x() - 1., pf -> y() - 15.);
drawViewfinderText(painter, coord, painter -> pen(), res_point.x());
}
}
}
/// Отрисовка графика
void GraphicDisplay::drawCurves(QPainter* painter)
{
if(!paramsDisplay -> rect().isValid()) return;
painter -> setClipRect(paramsDisplay -> rect().adjusted(1, 1, -1, -1));
QMapIterator<int, QVector<SpecPointF>> iter(curveMap);
int k = 1;
bool smoothing = valueElement("diagramSmooth", false).toBool();
while(iter.hasNext())
{
iter.next(); int id = iter.key();
if(fact_prm.size() == 0 || id >= fact_prm.size()) break;
if(settings.win_type != fact_prm[id].type) continue;
QPointF dim(dimensions(id));
setColorPen(painter, id);
const QVector<SpecPointF>& data = iter.value();
QPolygonF polyline(0);
for(int j=0; j<data.size(); ++j)
{
if(!isExistPhase(data[j])) continue;
double x = (settings.win_type != COUNTPARAM) ? data[j].x() * dim.x() : data[j].x();
double y = data[j].y() * dim.y();
QPointF pnt(initXY(x, y));
if(!polyline.isEmpty())
{
if(smoothing && pnt.x() <= polyline.last().x()) continue;
setPenForLine(j);
painter -> setPen(myPen);
if(j > 0 && isExistPhase(data[j - 1]))
painter -> drawLine(polyline.last(), pnt),
viewCoordViewfinder(painter, id, data, j);
polyline.append(pnt);
}
else polyline.append(pnt);
}
drawLegend(painter, paramsDisplay -> rect(), k, id);
}
}