private void dimensionConfigChanged(DimensionConfigChangeEvent dimensionChange) {
    PlotConfiguration currentPlotConfig =
        plotInstance.getCurrentPlotConfigurationClone(); // get current plot configuration

    // if domain config has changed
    if (dimensionChange.getDimension() == PlotDimension.DOMAIN) {
      getDomainConfigManagerData()
          .dimensionConfigChanged(dimensionChange); // inform domain config data

      // also inform both domain dimension configs
      DomainConfigManager domainConfigManager = currentPlotConfig.getDomainConfigManager();
      getDimensionConfigData(domainConfigManager.getDomainConfig(false))
          .dimensionConfigChanged(dimensionChange);
      getDimensionConfigData(domainConfigManager.getDomainConfig(true))
          .dimensionConfigChanged(dimensionChange);

    } else {
      // inform default dimension config data about change

      int id = dimensionChange.getSource().getId(); // fetch id of changed dimension
      DimensionConfig currentDimensionConfig =
          currentPlotConfig.getDefaultDimensionConfigById(id); // look up dimension config

      // if dimension config is still present, inform data about changes
      if (currentDimensionConfig != null) {
        DimensionConfigData dimData =
            getDimensionConfigData((DefaultDimensionConfig) currentDimensionConfig);
        dimData.dimensionConfigChanged(dimensionChange);
      } else {
        // if current dimension config is null it has been deleted afterwards in a meta change event
        debug(
            "#### CAUTION #### DIMENSION CHANGED:  current dimension config "
                + dimensionChange.getSource().getLabel()
                + " with id "
                + dimensionChange.getSource().getId()
                + " is null! Meta change event?");
        return; // do nothing and return
      }
    }

    // and process event here too
    if (dimensionChange.getType() == DimensionConfigChangeType.RANGE) {
      clearCache();
    }
  }
  public PlotData(PlotInstance plotInstance, DataTable dataTable) {
    if (plotInstance == null) {
      throw new IllegalArgumentException("null not allowed for plotInstance");
    }
    this.plotInstance = plotInstance;
    plotInstance.setPlotData(this);
    PlotConfiguration plotConfiguration = plotInstance.getMasterPlotConfiguration();
    //		if (plotConfiguration.getPrioritizedListenerCount() > 0) {
    //			plotConfiguration.clearPrioritizedListeners();
    //		}
    plotConfiguration.addPlotConfigurationListener(this, true);

    this.originalDataTable = dataTable;
    originalDataTable.addDataTableListener(this, true);

    valueMappingDataTable = new ValueMappingDataTableView(originalDataTable);
    for (int i = 0; i < valueMappingDataTable.getColumnNumber(); ++i) {
      if (valueMappingDataTable.isNominal(i)) {
        valueMappingDataTable.setMappingProvider(
            i, new NominalSortingDataTableMapping(valueMappingDataTable, i, true));
      }
    }

    // add filtered data table view to view stack
    filteredDataTableView = new FilteredDataTable(valueMappingDataTable);

    // add sorted data table view on view stack (without sort provider for now)
    sortedDataTableView = new SortedDataTableView(filteredDataTableView, null);
    sortedDataTableView.addDataTableListener(this, true);

    // init valueSourceDataMap
    for (ValueSource valueSource : plotConfiguration.getAllValueSources()) {
      ValueSourceData valueSourceData = new ValueSourceData(valueSource, plotInstance);
      valueSourceDataMap.put(valueSource.getId(), valueSourceData);
    }

    // init dimensionConfigDataMap
    for (DefaultDimensionConfig dimensionConfig :
        plotConfiguration.getDefaultDimensionConfigs().values()) {
      DimensionConfigData dimensionConfigData =
          new DimensionConfigData(plotInstance, dimensionConfig);
      dimensionConfigDataMap.put(dimensionConfig.getId(), dimensionConfigData);
    }
    DefaultDimensionConfig domainConfig;
    domainConfig = plotConfiguration.getDomainConfigManager().getDomainConfig(true);
    dimensionConfigDataMap.put(
        domainConfig.getId(), new DimensionConfigData(plotInstance, domainConfig));
    domainConfig = plotConfiguration.getDomainConfigManager().getDomainConfig(false);
    dimensionConfigDataMap.put(
        domainConfig.getId(), new DimensionConfigData(plotInstance, domainConfig));

    // init DomainConfigManagerData
    domainConfigManagerData = new DomainConfigManagerData(plotInstance);

    // init RangeAxisDataMap
    for (RangeAxisConfig rangeAxisConfig : plotConfiguration.getRangeAxisConfigs()) {
      RangeAxisData rangeAxisData = new RangeAxisData(rangeAxisConfig, plotInstance);
      rangeAxisDataMap.put(rangeAxisConfig.getId(), rangeAxisData);
    }

    clearCache();
  }
  @Override
  protected void updatePlotConfiguration() {
    // don't do anything if updates are suspended due to batch updating
    if (suspendUpdates) {
      return;
    }

    PlotConfiguration plotConfiguration = plotInstance.getMasterPlotConfiguration();

    // value when "None" is selected
    String noSelection =
        I18N.getMessage(I18N.getGUIBundle(), "gui.plotter.column.empty_selection.label");

    // stop event processing
    boolean plotConfigurationProcessedEvents = plotConfiguration.isProcessingEvents();
    plotConfiguration.setProcessEvents(false);

    // restore crosshairs
    List<AxisParallelLineConfiguration> clonedListOfDomainLines =
        new LinkedList<AxisParallelLineConfiguration>(listOfDomainLines);
    for (AxisParallelLineConfiguration lineConfig : clonedListOfDomainLines) {
      plotConfiguration.getDomainConfigManager().getCrosshairLines().addLine(lineConfig);
    }

    // x axis column selection
    if (!xAxisColumn.equals(noSelection)) {
      plotConfiguration
          .getDimensionConfig(PlotDimension.DOMAIN)
          .setDataTableColumn(
              new DataTableColumn(currentDataTable, currentDataTable.getColumnIndex(xAxisColumn)));
      plotConfiguration.getDimensionConfig(PlotDimension.DOMAIN).setLogarithmic(xAxisLogarithmic);
    } else {
      // remove config
      if (currentRangeAxisConfig != null) {
        currentRangeAxisConfig.removeRangeAxisConfigListener(rangeAxisConfigListener);
        plotConfiguration.removeRangeAxisConfig(currentRangeAxisConfig);
        currentRangeAxisConfig = null;
      }
      plotConfiguration.setProcessEvents(plotConfigurationProcessedEvents);
      return;
    }

    // y axis column selection
    if (!yAxisColumn.equals(noSelection)) {
      RangeAxisConfig newRangeAxisConfig = new RangeAxisConfig(yAxisColumn, plotConfiguration);
      newRangeAxisConfig.addRangeAxisConfigListener(rangeAxisConfigListener);
      ValueSource valueSource;
      valueSource =
          new ValueSource(
              plotConfiguration,
              new DataTableColumn(currentDataTable, currentDataTable.getColumnIndex(yAxisColumn)),
              AggregationFunctionType.count,
              false);
      SeriesFormat sFormat = new SeriesFormat();
      valueSource.setSeriesFormat(sFormat);
      newRangeAxisConfig.addValueSource(valueSource, null);
      newRangeAxisConfig.setLogarithmicAxis(yAxisLogarithmic);

      // remove old config
      if (currentRangeAxisConfig != null) {
        currentRangeAxisConfig.removeRangeAxisConfigListener(rangeAxisConfigListener);
        plotConfiguration.removeRangeAxisConfig(currentRangeAxisConfig);
      }
      currentRangeAxisConfig = newRangeAxisConfig;
      // add new config and restore crosshairs
      List<AxisParallelLineConfiguration> clonedRangeAxisLineList =
          rangeAxisCrosshairLinesMap.get(newRangeAxisConfig.getLabel());
      if (clonedRangeAxisLineList != null) {
        for (AxisParallelLineConfiguration lineConfig : clonedRangeAxisLineList) {
          newRangeAxisConfig.getCrossHairLines().addLine(lineConfig);
        }
      }
      plotConfiguration.addRangeAxisConfig(newRangeAxisConfig);
      // remember the new config so we can remove it later again
    } else {
      // remove config
      if (currentRangeAxisConfig != null) {
        currentRangeAxisConfig.removeRangeAxisConfigListener(rangeAxisConfigListener);
        plotConfiguration.removeRangeAxisConfig(currentRangeAxisConfig);
        currentRangeAxisConfig = null;
      }
    }

    // color column selection
    if (!colorColumn.equals(noSelection)) {
      plotConfiguration.setDimensionConfig(PlotDimension.COLOR, null);
      DefaultDimensionConfig dimConfig =
          new DefaultDimensionConfig(
              plotConfiguration,
              new DataTableColumn(currentDataTable, currentDataTable.getColumnIndex(colorColumn)),
              PlotDimension.COLOR);
      dimConfig.setLogarithmic(colorLogarithmic);
      plotConfiguration.setDimensionConfig(PlotDimension.COLOR, dimConfig);
    } else {
      plotConfiguration.setDimensionConfig(PlotDimension.COLOR, null);
    }

    // general settings
    plotConfiguration.setAxesFont(styleProvider.getAxesFont());
    plotConfiguration.setTitleFont(styleProvider.getTitleFont());
    plotConfiguration.getLegendConfiguration().setLegendFont(styleProvider.getLegendFont());
    plotConfiguration.addColorSchemeAndSetActive(styleProvider.getColorScheme());
    if (styleProvider.isShowLegend()) {
      plotConfiguration.getLegendConfiguration().setLegendPosition(LegendPosition.BOTTOM);
    } else {
      plotConfiguration.getLegendConfiguration().setLegendPosition(LegendPosition.NONE);
    }
    plotConfiguration.setFrameBackgroundColor(
        ColorRGB.convertToColor(styleProvider.getFrameBackgroundColor()));
    plotConfiguration.setPlotBackgroundColor(
        ColorRGB.convertToColor(styleProvider.getPlotBackgroundColor()));
    plotConfiguration.setTitleText(styleProvider.getTitleText());

    // continue event processing
    plotConfiguration.setProcessEvents(plotConfigurationProcessedEvents);
  }