private IntervalXYDataset getHistrogrammedDataAttributes(
     String[] attributes, long barsize, long timesize) {
   IntervalXYDataset dataset = null;
   if (no_intervals) {
     dataset = new XYSeriesCollection();
   } else {
     dataset = new YIntervalSeriesCollection();
   }
   for (int index = 0; index < attributes.length; index++) {
     Histogram histogram = new Histogram(barsize);
     String attribute = attributes[index];
     for (ProcessInstance pi : mylog.getInstances()) {
       Date begin;
       try {
         begin = pi.getAuditTrailEntryList().get(0).getTimestamp();
       } catch (Exception e) {
         Message.add(e.getMessage(), Message.ERROR);
         return null;
       } // starting time of process instance
       int j = 0;
       for (AuditTrailEntry ate : pi.getListOfATEs()) {
         if (ate.getAttributes().containsKey(attribute)) {
           Double val;
           val = Double.valueOf(ate.getAttributes().get(attribute));
           if (xbox.getSelectedIndex() == 2) {
             histogram.addValue(j, val);
           }
           if (xbox.getSelectedIndex() == 3) {
             histogram.addValue(timediff(begin, ate.getTimestamp()), val);
           }
           j++;
         }
       }
     }
     if (no_intervals) {
       ((XYSeriesCollection) dataset).addSeries(histogram.getXYSeries(attribute, timesize));
     } else {
       ((YIntervalSeriesCollection) dataset)
           .addSeries(histogram.getYIntervalSeries(attribute, timesize));
     }
   }
   return dataset;
 }
  @Analyzer(
      name = "Event Data Attribute Visualizer",
      names = {"Log"})
  public JComponent analyze(LogReader log) {
    /*
     * this plugin takes a log, shows a list of available data-attributes
     * and a list of cases After selecting a data-attribute (and possibly a
     * case) a graph is made of the value of the data-attribute against
     * either time or against the sequence of events.
     *
     * input: log with data attributes gui-input: select a data-attribute,
     * choose time or event-sequence, and possibly a case
     *
     * internally : if not caseselected -> scatterplot of values against
     * time/event-number else show graph for value against time/event-number
     *
     * createGraph : check number / string
     */
    mylog = log;
    mainPanel = new JPanel();
    mainPanel.setLayout(new BorderLayout());

    chartPanel = new JPanel();
    chartPanel.setLayout(new BoxLayout(chartPanel, BoxLayout.PAGE_AXIS));

    optionsPanel = new JPanel();
    optionsPanel.setLayout(new SpringLayout());

    JLabel attributelabel = new JLabel("Select attributes to use");
    attributeslist = new JList(getAttributes());
    attributeslist.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    attributeslist.setLayoutOrientation(JList.VERTICAL);
    optionsPanel.add(attributelabel);
    optionsPanel.add(attributeslist);

    JLabel xlabel = new JLabel("Chart type");
    String[] xvalues = new String[4];
    xvalues[0] = " Attribute values against event sequence";
    xvalues[1] = "Attribute values against timestamps";
    xvalues[2] = "Average attribute values against event sequence";
    xvalues[3] = "Average attribute values against timestamps";
    xbox = new JComboBox(xvalues);
    xbox.setMaximumSize(xbox.preferredSize());
    xbox.setSelectedIndex(1);

    xbox.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            JComboBox cb = (JComboBox) e.getSource();
            if (cb.getSelectedIndex() == 3) {
              BSpinner.setVisible(true);
            } else {
              BSpinner.setVisible(false);
            }
          };
        });

    optionsPanel.add(xlabel);
    optionsPanel.add(xbox);

    JLabel timelabel = new JLabel("show time by ");
    String[] timevalues = new String[4];
    timevalues[0] = "second";
    timevalues[1] = "minute";
    timevalues[2] = "hour";
    timevalues[3] = "day";
    timebox = new JComboBox(timevalues);
    timebox.setMaximumSize(timebox.preferredSize());
    timebox.setSelectedIndex(1);
    optionsPanel.add(timelabel);
    optionsPanel.add(timebox);

    SpinnerModel Bmodel = new SpinnerNumberModel(10, 2, 1000000, 1);
    BSpinner = new JSpinner(Bmodel);
    JLabel BLabel = new JLabel("Select histogram barsize");
    JLabel B2Label = new JLabel("used for average against timestamps");
    BSpinner.setMaximumSize(BSpinner.preferredSize());
    BSpinner.setVisible(false);
    optionsPanel.add(BLabel);
    optionsPanel.add(B2Label);
    optionsPanel.add(BSpinner);

    JButton updatebutton = new JButton("update");
    updatebutton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent e) {

            Object[] sels = attributeslist.getSelectedValues();
            String[] els = new String[sels.length];
            for (int i = 0; i < sels.length; i++) {
              els[i] = sels[i].toString();
            }

            long timesize = 1000;
            switch (timebox.getSelectedIndex()) {
              case 0:
                timesize = 1000;
                break;
              case 1:
                timesize = 1000 * 60;
                break;
              case 2:
                timesize = 1000 * 60 * 60;
                break;
              case 3:
                timesize = 1000 * 60 * 60 * 24;
                break;
            }

            String xname = null;
            JFreeChart mychart = null;
            if (xbox.getSelectedIndex() == 0) {
              data = getDataAttributes(els, false, timesize);
              xname = "Event sequence";
              mychart =
                  ChartFactory.createScatterPlot(
                      "Scatterplot of all values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
            } else if (xbox.getSelectedIndex() == 1) {
              data = getDataAttributes(els, true, timesize);
              xname = "Time(" + timebox.getSelectedItem() + ") since beginning of the process";
              mychart =
                  ChartFactory.createScatterPlot(
                      "Scatterplot of all values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
            } else if (xbox.getSelectedIndex() == 2) {
              xname = "Event sequence";
              data = getHistrogrammedDataAttributes(els, 1, 1);
              mychart =
                  ChartFactory.createXYLineChart(
                      "Average values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
              mychart.setBackgroundPaint(Color.white);
              XYPlot plot = mychart.getXYPlot();

              plot.setBackgroundPaint(Color.white);
              plot.setDomainGridlinePaint(Color.white);
              plot.setRangeGridlinePaint(Color.white);

              DeviationRenderer renderer = new DeviationRenderer(true, true);
              renderer.setSeriesStroke(
                  0, new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
              renderer.setSeriesStroke(0, new BasicStroke(2.0f));
              renderer.setSeriesStroke(1, new BasicStroke(2.0f));
              renderer.setSeriesStroke(2, new BasicStroke(2.0f));
              renderer.setSeriesStroke(3, new BasicStroke(2.0f));
              renderer.setSeriesFillPaint(0, Color.red);
              renderer.setSeriesFillPaint(1, Color.blue);
              renderer.setSeriesFillPaint(2, Color.green);
              renderer.setSeriesFillPaint(3, Color.orange);
              plot.setRenderer(renderer);
              // change the auto tick unit selection to integer units
              // only...
              NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
              // yAxis.setAutoRangeIncludesZero(false);
              yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

              NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
              xAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
            } else {
              xname = "Time(" + timebox.getSelectedItem() + "s) since beginning of the process";
              data =
                  getHistrogrammedDataAttributes(
                      els, ((Integer) BSpinner.getValue()) * timesize, timesize);
              mychart =
                  ChartFactory.createXYLineChart(
                      "Average values",
                      xname,
                      "attribute value",
                      data,
                      PlotOrientation.VERTICAL,
                      true,
                      true,
                      false);
              mychart.setBackgroundPaint(Color.white);
              XYPlot plot = mychart.getXYPlot();

              plot.setBackgroundPaint(Color.white);
              plot.setDomainGridlinePaint(Color.white);
              plot.setRangeGridlinePaint(Color.white);

              DeviationRenderer renderer = new DeviationRenderer(true, true);
              renderer.setSeriesStroke(
                  0, new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
              renderer.setSeriesStroke(0, new BasicStroke(2.0f));
              renderer.setSeriesStroke(1, new BasicStroke(2.0f));
              renderer.setSeriesStroke(2, new BasicStroke(2.0f));
              renderer.setSeriesStroke(3, new BasicStroke(2.0f));
              renderer.setSeriesFillPaint(0, Color.red);
              renderer.setSeriesFillPaint(1, Color.blue);
              renderer.setSeriesFillPaint(2, Color.green);
              renderer.setSeriesFillPaint(3, Color.orange);
              plot.setRenderer(renderer);
              // change the auto tick unit selection to integer units
              // only...
              NumberAxis yAxis = (NumberAxis) plot.getRangeAxis();
              // yAxis.setAutoRangeIncludesZero(false);
              yAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
            }

            ChartPanel mychartpanel = new ChartPanel(mychart);
            mychartpanel.setBackground(Color.white);
            chartPanel.removeAll();
            chartPanel.add(mychartpanel);
            chartPanel.updateUI();
          };
        });
    optionsPanel.add(updatebutton);

    JSplitPane splitPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, optionsPanel, chartPanel);

    SpringUtils.makeCompactGrid(
        optionsPanel,
        10,
        1, // rows, cols
        6,
        2, // initX, initY
        6,
        2); // xPad, yPad

    mainPanel.add(splitPanel, BorderLayout.CENTER);
    return mainPanel;
  }