Important: Please read the Qt Code of Conduct -

Graphs overlay of changes in values

  • Hello everyone, I've tried some different algorithms, but I can't find the right one.

    What i have:
    Devices that have "slots" in which there are graphs of changes of these "slots".
    Further, I have sub-scenes, this is a combination of devices with different "slots" and different graphics in them, and finally, I have a scene, of course it is a combination of sub-scenes.

    What i need:
    Put the scene together according to certain principles:
    If a device occurs only once among all sub-scenes of the scene, then the graphs of its slots are simply extended for the entire duration of the scene from the extreme points (green lines)
    alt text

    If a device occurs in two or more sub-scenes in one line, the graphs of the same slots are summed up and extended - the beginning of the first sub-scene to the beginning of the scene (orange line), the end to the next scene (green line), and the end of the last to the end of the scene (pink line)
    alt text

    The most difficult option, when one device can meet in several sub-scenes on different lines, in this case, the intersection of the sub-scenes (blue rectangle) must add up according to a certain type (multiplication, subtraction, maximum value), for example, the maximum value and fill the voids (the priority depends on lines).
    alt text
    On exit need get a graph like this
    alt text

    The merge should be done as follows, graphics are QVector <QPoint>, there is such code

      QVector<SubScene*> subscenes(subscenes_);
      std::sort(subscenes.begin(), subscenes.end(), [&](SubScene *ss1, SubScene *ss2) { return ss1->GetLineIndex() > ss2->GetLineIndex(); });
      for (int i(line_count_ - 1); i >= 0; i--) {
        Q_FOREACH(SubScene *a_subscene, subscenes) {
          if (a_subscene->GetLineIndex() == i)
            Q_FOREACH(Device *a_device, a_subscene->GetDevices())
              Q_FOREACH(Slot *a_slot, *a_device->GetSlots())
                if (!a_slot->GetGraphic().isEmpty()) {
                  QVector<QPoint> slot_graphic(a_slot->GetGraphic());
                  QVector<QPoint> low_graphic(scene_graphic.value(a_device, QMap<a_slot, QVector<QPoint>>()).value(a_slot, QVector<QPoint>>({ QPoint(start, -1), QPoint(start + duration, -1) })));
                  scene_graphic[a_device].insert(a_slot, CombineGraphics(low_graphic, slot_graphic, a_subscene->GetOverlayType()));

    Sub-scenes are on the lines, respectively, the overlay goes from bottom to top, like in layers in Photoshop, the values ​​can only be than 0 and more. By default, if a chart has not been added yet, a default chart with values ​​of -1 is transmitted, these values ​​are considered "flags" of the chart extension. It turns out during the passage of the above cycle, the intervals between the graphs should be with values ​​of -1, because the values ​​of the slots can be from 0 and higher, respectively, 0 is taken as the existing schedule, which should not be, also the intervals should not be extended immediately by the normal value, for example 50, because where there is no graph, it should be superimposed on 0, not 50, so after the cycle, the addition is another cycle, deleting points -1 and replacing them with points with a value (it is, the code has not been inserted)

    I tried to do something similar through QPolygon, but apparently this is impossible, correct if not right.
    Only "max value" overlay works correctly, by QPolygon::united method

Log in to reply