org.xapagy.ui.tempdyn.GraphEvolution.java Source code

Java tutorial

Introduction

Here is the source code for org.xapagy.ui.tempdyn.GraphEvolution.java

Source

/*
       
This file is part of the Xapagy Cognitive Architecture 
Copyright (C) 2008-2017 Ladislau Boloni
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.
    
You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
       
*/
package org.xapagy.ui.tempdyn;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Stroke;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.List;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

import org.xapagy.agents.Agent;
import org.xapagy.instances.Instance;
import org.xapagy.instances.VerbInstance;
import org.xapagy.parameters.Parameters;
import org.xapagy.set.EnergyColors;
import org.xapagy.ui.prettyprint.PpChoice;
import org.xapagy.ui.smartprint.SpInstance;
import org.xapagy.ui.smartprint.XapiPrint;
import org.xapagy.ui.tempdyn.tdComponent.tdComponentType;

/**
 * @author Ladislau Boloni
 * Created on: Aug 11, 2013
 */
public class GraphEvolution {

    public static List<SimpleEntry<Color, Stroke>> lineStylesColorful = null;
    public static List<SimpleEntry<Color, Stroke>> lineStylesConservative = null;

    static {
        GraphEvolution.initializeLineStyles();
    }

    /**
     * Generates the graph which plots the three choice scores (independent,
     * dependent and mood) for the evolution of a choice in time.
     * 
     * @param tdc
     *            - encompasses the selected choice
     * @param database
     *            - the database of values collected
     * @param agent
     * @param index
     *            - a list of time points which will be plotted on the x axis
     * @param choiceRange
     *            - the y axis will be [0, choiceRange]
     */
    public static void graphChoiceEvolution(tdComponent tdc, tdDataBase database, Agent agent, List<Double> index,
            double choiceRange) {
        String label = PpChoice.ppConcise(tdc.getChoice(), agent);

        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        // focus and memory
        xysc.addSeries(new XYSeries("ChoiceScoreIndependent"));
        xysc.addSeries(new XYSeries("ChoiceScoreDependent"));
        xysc.addSeries(new XYSeries("ChoiceScoreMood"));
        // Fill in the values
        for (Double time : index) {
            double dtime = time;
            double valueChoiceScoreIndependent = database.getChoiceScoreDependent(tdc.getIdentifier(), time);
            xysc.getSeries("ChoiceScoreIndependent").add(dtime, valueChoiceScoreIndependent);
            double valueChoiceScoreDependent = database.getChoiceScoreDependent(tdc.getIdentifier(), time);
            xysc.getSeries("ChoiceScoreDependent").add(dtime, valueChoiceScoreDependent);
            double valueChoiceScoreMood = database.getChoiceScoreDependent(tdc.getIdentifier(), time);
            xysc.getSeries("ChoiceScoreMood").add(dtime, valueChoiceScoreMood);
        }
        //
        // ok, now let us create a graph
        //
        JPanel panel = new JPanel();
        // create a layout
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        SequentialGroup sgv = layout.createSequentialGroup();
        layout.setVerticalGroup(sgv);
        ParallelGroup pgh = layout.createParallelGroup();
        layout.setHorizontalGroup(pgh);
        //
        // the graph with the focus and the memory
        //
        XYSeriesCollection xysFM = new XYSeriesCollection();
        xysFM.addSeries(xysc.getSeries("ChoiceScoreIndependent"));
        xysFM.addSeries(xysc.getSeries("ChoiceScoreDependent"));
        xysFM.addSeries(xysc.getSeries("ChoiceScoreMood"));
        JFreeChart chart = ChartFactory.createXYLineChart(label + " - Choice", "Time", "Value", xysFM,
                PlotOrientation.VERTICAL, true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesColorful);
        ChartPanel cp = new ChartPanel(chart);
        sgv.addComponent(cp);
        pgh.addComponent(cp);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Graphs the evolution of the links of all types (PRED, SUCC, SUMMARY,
     * CONTEXT etc) between two Vis.
     * 
     * @param fromVi
     * @param toVi
     * @param tdb
     * @param agent
     * @param index
     *            - a list of time points which will be plotted on the x axis
     */
    public static void graphLinksBetweenVis(tdComponent fromVi, tdComponent toVi, tdDataBase tdb, Agent agent,
            List<Double> index) {
        String label = "Links between " + fromVi.getIdentifier() + " and " + toVi.getIdentifier();
        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        // add a series for each link type
        for (String linkName : agent.getLinks().getLinkTypeNames()) {
            XYSeries linkSeries = new XYSeries(linkName);
            xysc.addSeries(linkSeries);
            // now fill in the series with values
            for (Double time : index) {
                double dtime = time;
                double linkValue = tdb.getLinkValue(fromVi.getIdentifier(), toVi.getIdentifier(), linkName, time);
                linkSeries.add(dtime, linkValue);
            }
        }
        //
        // ok, now let us create a graph
        //
        JPanel panel = new JPanel();
        // create a layout
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        SequentialGroup sgv = layout.createSequentialGroup();
        layout.setVerticalGroup(sgv);
        ParallelGroup pgh = layout.createParallelGroup();
        layout.setHorizontalGroup(pgh);
        JFreeChart chart = ChartFactory.createXYLineChart(label, "Time", "Value", xysc, PlotOrientation.VERTICAL,
                true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesColorful);
        ChartPanel cp = new ChartPanel(chart);
        sgv.addComponent(cp);
        pgh.addComponent(cp);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Graphs which plots the evolution of all the links from a given VI. If the
     * linkType is not null, it filters based on that, otherwise, it plots all
     * the link types
     * 
     * @param fromVi
     * @param linkType
     * @param tdb
     * @param agent
     * @param index
     */
    public static void graphLinksFromAVi(tdComponent fromVi, String linkType, tdDataBase tdb, Agent agent,
            List<Double> index) {
        String label;
        if (linkType != null) {
            label = "Links of type " + linkType + " from " + fromVi.getIdentifier();
        } else {
            label = "Links of all types from " + fromVi.getIdentifier();
        }
        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        List<tdComponent> linkedVis = tdb.getFocusVis();

        List<String> types = new ArrayList<>();
        if (linkType != null) {
            types.add(linkType);
        } else {
            types.addAll(agent.getLinks().getLinkTypeNames());
        }

        // add a series for each VI - if not null
        for (tdComponent toVi : linkedVis) {
            for (String linkName : types) {
                boolean addDecision = false;
                String id;
                if (linkType != null) {
                    id = toVi.getIdentifier() + "-" + toVi.getLastPrettyPrint();
                } else {
                    id = linkName + " to " + toVi.getIdentifier() + "-" + toVi.getLastPrettyPrint();
                }
                XYSeries linkSeries = new XYSeries(id);
                // now fill in the series with values
                for (Double time : index) {
                    double dtime = time;
                    double linkValue = tdb.getLinkValue(fromVi.getIdentifier(), toVi.getIdentifier(), linkName,
                            time);
                    if (linkValue != 0.0) {
                        addDecision = true;
                    }
                    linkSeries.add(dtime, linkValue);
                }
                if (addDecision) {
                    xysc.addSeries(linkSeries);
                }
            }
        }
        //
        // ok, now let us create a graph
        //
        JPanel panel = new JPanel();
        // create a layout
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        SequentialGroup sgv = layout.createSequentialGroup();
        layout.setVerticalGroup(sgv);
        ParallelGroup pgh = layout.createParallelGroup();
        layout.setHorizontalGroup(pgh);
        JFreeChart chart = ChartFactory.createXYLineChart(label, "Time", "Value", xysc, PlotOrientation.VERTICAL,
                true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesColorful);
        ChartPanel cp = new ChartPanel(chart);
        sgv.addComponent(cp);
        pgh.addComponent(cp);
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * This function generates a frame into which a number of graphs are
     * arranged horizontally. Each graph describes the time series values for a
     * given in-focus object. We have: the focus (with all the energy colors -
     * salience / energy), the memory (with all the energy colors - salience /
     * energy), and a list of shadows (with all the energy colors - salience /
     * energy).
     * 
     * @param tdc
     * @param database
     * @param agent
     * @param index
     *            - the index of time values
     * @param isInstance
     *            - true for instances
     * @param shadowComponents
     *            - how many components will we enter in the graph
     * @param shadowRange
     *            - the range of the y plot on the shadows - needs to be unique.
     * 
     * 
     */
    public static void graphFMSComposite(tdComponent tdc, tdDataBase database, Agent agent, List<Double> index,
            int shadowComponents, double shadowRange, GraphEvolutionDescriptor ged) {
        String label = tdc.getLastPrettyPrint();
        // FIXME: this is a tiny bit iffy: we are getting the shadows based on a
        // certain energy color
        String ecx = EnergyColors.SHI_GENERIC;
        List<String> shadowList = database.getShadowComponents(tdc.getIdentifier(), ecx, shadowComponents);
        //
        // ok, now let us create a graph
        //
        JPanel panel = new JPanel();
        // create a layout
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        SequentialGroup sgv = layout.createSequentialGroup();
        layout.setVerticalGroup(sgv);
        ParallelGroup pgh = layout.createParallelGroup();
        layout.setHorizontalGroup(pgh);
        //
        // the graph with the focus values
        //
        if (ged.graphFocusEnergy || ged.graphFocusSalience) {
            JFreeChart chart = chartFocusEvolution(tdc, label, database, agent, index, ged);
            ChartPanel cp = new ChartPanel(chart);
            sgv.addComponent(cp);
            pgh.addComponent(cp);
        }
        //
        // the graph with the memory values
        //
        if (ged.graphMemoryEnergy || ged.graphMemorySalience) {
            JFreeChart chart = chartMemoryEvolution(tdc, label, database, agent, index, ged);
            ChartPanel cp = new ChartPanel(chart);
            sgv.addComponent(cp);
            pgh.addComponent(cp);
        }
        //
        // the graphs with the shadow components
        //
        if (ged.graphShadowEnergy || ged.graphShadowSalience) {
            for (String sh : shadowList) {
                JFreeChart chart = chartShadowEvolution(tdc, sh, database, agent, index, shadowRange, ged);
                ChartPanel cp = new ChartPanel(chart);
                sgv.addComponent(cp);
                pgh.addComponent(cp);
            }
        }
        JFrame frame = new JFrame();
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    /**
     * Generate a timeline based on ticks for every da timestep
     * 
     * @param database
     * @param agent
     * @param startFrom
     * @return
     */
    public static List<Double> getTimelineDaSteps(tdDataBase database, Agent agent, double startFrom) {
        Parameters p = agent.getParameters();
        double timeStepOfDAs = p.get("A_GENERAL", "G_GENERAL", "N_TIME_STEP_OF_DAS");
        double timeStart = database.getTimeStart();
        if (startFrom > 0) {
            timeStart = startFrom;
        }
        double timeEnd = database.getTimeEnd();
        //
        // determine ticks on the X axis
        //
        List<Double> index = new ArrayList<>();
        for (double time = timeStart; time <= timeEnd; time = time + timeStepOfDAs) {
            index.add(time);
        }
        return index;
    }

    /**
     * Initializes
     */
    public static void initializeLineStyles() {
        /**
         * Conservative line styles: gray and black various thicknesses
         */
        GraphEvolution.lineStylesConservative = new ArrayList<>();
        List<Color> colors = new ArrayList<>();
        colors.add(Color.black);
        colors.add(Color.gray);
        List<Stroke> strokes = new ArrayList<>();
        strokes.add(new BasicStroke(3.0f));
        strokes.add(new BasicStroke(1.0f));
        for (Color color : colors) {
            for (Stroke stroke : strokes) {
                GraphEvolution.lineStylesConservative.add(new SimpleEntry<>(color, stroke));
            }
        }
        /**
         * Colorful line styles: striking colors
         */
        GraphEvolution.lineStylesColorful = new ArrayList<>();
        colors = new ArrayList<>();
        colors.add(Color.black);
        colors.add(Color.blue);
        colors.add(Color.red);
        colors.add(Color.green);
        colors.add(Color.magenta);
        colors.add(Color.orange);
        for (Stroke stroke : strokes) {
            for (Color color : colors) {
                GraphEvolution.lineStylesColorful.add(new SimpleEntry<>(color, stroke));
            }
        }
    }

    /**
     * Creates a chart the style we like.
     * 
     * @param chart
     */
    public static void setChartProperties(JFreeChart chart, List<SimpleEntry<Color, Stroke>> lineStyles) {
        // set the background and title font
        chart.setBackgroundPaint(Color.white);
        chart.getTitle().setFont(new Font("Tahoma", Font.BOLD, 14));
        // set the background and the grid all white
        XYPlot plot = chart.getXYPlot();
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        plot.setBackgroundPaint(Color.white);
        // now
        plot.setOutlineStroke(null);

        XYItemRenderer rend = plot.getRenderer();
        Stroke stroke = new BasicStroke(2.0f);
        rend.setBaseStroke(stroke);
        // rend.setDrawSeriesLineAsPath(true);

        // stroke = new BasicStroke(2.0f, BasicStroke.CAP_ROUND,
        // BasicStroke.JOIN_ROUND, 10, new float[] {10, 10}, 0);
        // strokes.add(stroke);
        // stroke = new BasicStroke(2.0f, BasicStroke.CAP_ROUND,
        // BasicStroke.JOIN_ROUND, 10, new float[] {2, 4}, 0);
        // strokes.add(stroke);
        int seriesCount = plot.getSeriesCount();
        for (int i = 0; i != seriesCount; i++) {
            SimpleEntry<Color, Stroke> lineStyle = lineStyles.get(i % lineStyles.size());
            rend.setSeriesStroke(i, lineStyle.getValue());
            rend.setSeriesPaint(i, lineStyle.getKey());
        }
    }

    /**
     * 
     * Returns a chart of the evolution of the focus component tdc
     * 
     * @param tdc
     * @param label
     * @param database
     * @param agent
     * @param index
     * @param ged
     * @return
     */
    public static JFreeChart chartFocusEvolution(tdComponent tdc, String label, tdDataBase database, Agent agent,
            List<Double> index, GraphEvolutionDescriptor ged) {
        List<String> focusEnergyColors = null;
        switch (tdc.getType()) {
        case INSTANCE:
            focusEnergyColors = ged.focusInstanceEnergyColors;
            break;
        case VI:
            focusEnergyColors = ged.focusViEnergyColors;
            break;
        case CHOICE:
            focusEnergyColors = null;
            break;
        }

        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        // focus energy values (if needed)
        if (ged.graphFocusEnergy) {
            for (String ec : focusEnergyColors) {
                xysc.addSeries(new XYSeries("FocusEnergy_" + ec));
            }
        }
        // focus salience values (if needed)
        if (ged.graphFocusSalience) {
            for (String ec : focusEnergyColors) {
                xysc.addSeries(new XYSeries("FocusSalience_" + ec));
            }
        }
        //
        // Fill in the values into the xysc
        //
        for (Double time : index) {
            double dtime = time;
            if (ged.graphFocusEnergy) {
                for (String ec : focusEnergyColors) {
                    double value = database.getEnergy(tdc.getIdentifier(), ec, time);
                    xysc.getSeries("FocusEnergy_" + ec).add(dtime, value);
                }
            }
            // focus salience values (if needed)
            if (ged.graphFocusSalience) {
                for (String ec : focusEnergyColors) {
                    double value = database.getSalience(tdc.getIdentifier(), ec, time);
                    xysc.getSeries("FocusSalience_" + ec).add(dtime, value);
                }
            }
        }
        JFreeChart chart = ChartFactory.createXYLineChart(label + " - Focus", "Time", "Value", xysc,
                PlotOrientation.VERTICAL, true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesConservative);
        return chart;
    }

    /**
     * Returns a chart of the evolution of the memory component tdc
     * 
     * @param tdc
     * @param label
     * @param database
     * @param agent
     * @param index
     * @param ged
     * @return
     */
    public static JFreeChart chartMemoryEvolution(tdComponent tdc, String label, tdDataBase database, Agent agent,
            List<Double> index, GraphEvolutionDescriptor ged) {
        List<String> memoryColors = null;
        if (tdc.getType() == tdComponentType.INSTANCE) {
            memoryColors = ged.memoryInstanceEnergyColors;
        } else {
            memoryColors = ged.memoryViEnergyColors;
        }

        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        // memory energy values (if needed)
        if (ged.graphMemoryEnergy) {
            for (String ec : memoryColors) {
                xysc.addSeries(new XYSeries("MemoryEnergy_" + ec));
            }
        }
        // memory salience values (if needed)
        if (ged.graphMemorySalience) {
            for (String ec : memoryColors) {
                xysc.addSeries(new XYSeries("MemorySalience_" + ec));
            }
        }
        //
        // Fill in the values into the xysc
        //
        for (Double time : index) {
            double dtime = time;
            // memory energy values (if needed)
            if (ged.graphMemoryEnergy) {
                for (String ec : memoryColors) {
                    double value = database.getEnergy(tdc.getIdentifier(), ec, time);
                    xysc.getSeries("MemoryEnergy_" + ec).add(dtime, value);
                }
            }
            // memory salience values (if needed)
            if (ged.graphMemorySalience) {
                for (String ec : memoryColors) {
                    double value = database.getSalience(tdc.getIdentifier(), ec, time);
                    xysc.getSeries("MemorySalience_" + ec).add(dtime, value);
                }
            }
        }
        //
        // the chart with the memory values
        //
        JFreeChart chart = ChartFactory.createXYLineChart(label + " - memory", "Time", "Value", xysc,
                PlotOrientation.VERTICAL, true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesConservative);
        return chart;
    }

    /**
     * Returns a chart for the evolution of the shadowing of the component tdc with sh.
     * 
     * @param tdc
     * @param sh
     * @param database
     * @param agent
     * @param index
     * @param shadowRange
     * @param ged
     * @return
     */
    public static JFreeChart chartShadowEvolution(tdComponent tdc, String sh, tdDataBase database, Agent agent,
            List<Double> index, double shadowRange, GraphEvolutionDescriptor ged) {
        List<String> shadowColors = null;
        if (tdc.getType() == tdComponentType.INSTANCE) {
            shadowColors = ged.shadowInstanceEnergyColors;
        } else {
            shadowColors = ged.shadowViEnergyColors;
        }
        // create a general purpose xy collection for jfreechart
        XYSeriesCollection xysc = new XYSeriesCollection();
        // shadow energy values (if needed)
        if (ged.graphShadowEnergy) {
            for (String ec : shadowColors) {
                xysc.addSeries(new XYSeries("ShadowEnergy_" + ec + "_" + sh));
            }
        }
        // shadow salience values (if needed)
        if (ged.graphShadowSalience) {
            for (String ec : shadowColors) {
                xysc.addSeries(new XYSeries("ShadowSalience_" + ec + "_" + sh));
            }
        }
        //
        // Fill in the values into the xysc
        //
        for (Double time : index) {
            double dtime = time;
            // shadow energy values (if needed)
            if (ged.graphShadowEnergy) {
                for (String ec : shadowColors) {
                    double value = database.getEnergy(tdc.getIdentifier(), sh, ec, time);
                    xysc.getSeries("ShadowEnergy_" + ec + "_" + sh).add(dtime, value);
                }
            }
            // shadow salience values (if needed)
            if (ged.graphShadowSalience) {
                for (String ec : shadowColors) {
                    double value = database.getSalience(tdc.getIdentifier(), sh, ec, time);
                    xysc.getSeries("ShadowSalience_" + ec + "_" + sh).add(dtime, value);
                }
            }
        }
        XYSeriesCollection xysSH = new XYSeriesCollection();
        // shadow energy (if needed)
        if (ged.graphShadowEnergy) {
            for (String ec : shadowColors) {
                xysSH.addSeries(xysc.getSeries("ShadowEnergy_" + ec + "_" + sh));
            }
        }
        // shadow salience (if needed)
        if (ged.graphShadowSalience) {
            for (String ec : shadowColors) {
                xysSH.addSeries(xysc.getSeries("ShadowSalience_" + ec + "_" + sh));
            }
        }
        // FIND a label
        String shadowLabel = "Shadow:" + sh;
        if (tdc.getType() == tdComponentType.INSTANCE) {
            Instance instance = agent.getAutobiographicalMemory().getInstance(sh);
            shadowLabel += " - " + SpInstance.spc(instance, agent);
        } else {
            VerbInstance vi = agent.getAutobiographicalMemory().getVerbInstance(sh);
            shadowLabel += " - " + XapiPrint.ppsViXapiForm(vi, agent);
        }
        JFreeChart chart = ChartFactory.createXYLineChart(shadowLabel, "Time", "Value", xysSH,
                PlotOrientation.VERTICAL, true, false, false);
        GraphEvolution.setChartProperties(chart, GraphEvolution.lineStylesConservative);
        XYPlot plot = chart.getXYPlot();
        plot.getRangeAxis(0).setRange(0, shadowRange);
        return chart;
    }

}