public hasUnsavedChanges()

in src/core/prototypes/state.ts [132:345]


  public hasUnsavedChanges() {
    const origin = this.chartOrigin;
    const chart = this.chart;

    const currentProperties = chart.properties;
    const originProperties = origin.properties;

    try {
      expect_deep_approximately_equals(
        currentProperties,
        originProperties,
        defaultDifferenceApproximation,
        true
      );
    } catch {
      return true;
    }

    if (origin.constraints.length !== chart.constraints.length) {
      return true;
    } else {
      for (let index = 0; index < origin.constraints.length; index++) {
        const originConstringts = origin.constraints[index];
        const current = chart.constraints[index];
        expect_deep_approximately_equals(
          originConstringts,
          current,
          defaultDifferenceApproximation,
          true
        );
      }
    }

    const chartElements = [...forEachObject(chart)];
    const originElements = [...forEachObject(origin)];

    // forEachObject retuns all objects in the chart
    // if any object was added or removed to the chart it means chart has changes
    // don't need to compare in details
    if (chartElements.length != originElements.length) {
      return true;
    } else {
      for (let index = 0; index < chartElements.length; index++) {
        const currentElement = chartElements[index];
        const originElement = originElements[index];

        if (currentElement.kind != originElement.kind) {
          return true;
        }
        if (currentElement.glyph?.classID != originElement.glyph?.classID) {
          return true;
        }
        if (currentElement.object?._id != originElement.object?._id) {
          return true;
        }
        if (currentElement.scale?._id != originElement.scale?._id) {
          return true;
        }
        if (
          currentElement.kind == ObjectItemKind.ChartElement &&
          currentElement.kind == ObjectItemKind.ChartElement
        ) {
          if (currentElement.chartElement && originElement.chartElement) {
            if (
              currentElement.chartElement._id != originElement.chartElement._id
            ) {
              return true;
            }
            if (
              currentElement.chartElement.classID !=
              originElement.chartElement.classID
            ) {
              return true;
            }
          }
          if (
            Prototypes.isType(
              currentElement.chartElement.classID,
              "plot-segment"
            ) &&
            Prototypes.isType(
              originElement.chartElement.classID,
              "plot-segment"
            )
          ) {
            const currentPlotSegment = currentElement.chartElement as Specification.PlotSegment;
            const originPlotSegment = originElement.chartElement as Specification.PlotSegment;

            if (currentPlotSegment.glyph != originPlotSegment.glyph) {
              return true;
            }

            if (currentPlotSegment.table != originPlotSegment.table) {
              return true;
            }

            try {
              expect_deep_approximately_equals(
                currentPlotSegment.filter,
                originPlotSegment.filter,
                defaultDifferenceApproximation,
                true
              );
              expect_deep_approximately_equals(
                currentPlotSegment.groupBy,
                originPlotSegment.groupBy,
                defaultDifferenceApproximation,
                true
              );
              expect_deep_approximately_equals(
                currentPlotSegment.order,
                originPlotSegment.order,
                defaultDifferenceApproximation,
                true
              );
              expect_deep_approximately_equals(
                currentPlotSegment.mappings,
                originPlotSegment.mappings,
                defaultDifferenceApproximation,
                true
              );
              expect_deep_approximately_equals(
                currentPlotSegment.properties,
                originPlotSegment.properties,
                defaultDifferenceApproximation,
                true
              );
            } catch (ex) {
              console.log(ex);
              return true;
            }
          }

          try {
            const currentProperties = currentElement.chartElement.properties;
            const originProperties = originElement.chartElement.properties;

            expect_deep_approximately_equals(
              currentProperties,
              originProperties,
              defaultDifferenceApproximation,
              true
            );
          } catch (ex) {
            console.log(ex);
            return true;
          }
        }

        if (
          currentElement.kind == ObjectItemKind.Glyph &&
          originElement.kind == ObjectItemKind.Glyph
        ) {
          if (currentElement.glyph.table != originElement.glyph.table) {
            return true;
          }
        }

        if (
          currentElement.kind == ObjectItemKind.Mark &&
          originElement.kind == ObjectItemKind.Mark
        ) {
          if (currentElement.mark?.classID != originElement.mark?.classID) {
            return true;
          }
          try {
            const currentProperties = currentElement.mark.properties;
            const originProperties = originElement.mark.properties;

            expect_deep_approximately_equals(
              currentProperties,
              originProperties,
              defaultDifferenceApproximation,
              true
            );
          } catch (ex) {
            console.log(ex);
            return true;
          }
        }

        try {
          const currentMappings = currentElement.object.mappings;
          const originMappings = originElement.object.mappings;
          expect_deep_approximately_equals(
            currentMappings,
            originMappings,
            defaultDifferenceApproximation,
            true
          );
        } catch (ex) {
          console.log(ex);
          return true;
        }

        //scale mappings
        try {
          const currentProperties = currentElement.object?.properties;
          const originProperties = originElement.object?.properties;
          expect_deep_approximately_equals(
            currentProperties,
            originProperties,
            defaultDifferenceApproximation,
            true
          );
        } catch (ex) {
          console.log(ex);
          return true;
        }
      }
    }

    return false;
  }