FileDocCategorySizeDatePackage
DisplayGraph.javaAPI DocAndroid 1.5 API16200Wed May 06 22:41:08 BST 2009com.android.ddmuilib.log.event

DisplayGraph

public class DisplayGraph extends EventDisplay

Fields Summary
Constructors Summary
public DisplayGraph(String name)

        super(name);
    
Methods Summary
public org.eclipse.swt.widgets.ControlcreateComposite(org.eclipse.swt.widgets.Composite parent, com.android.ddmlib.log.EventLogParser logParser, ILogColumnListener listener)
Creates the UI for the event display.

param
parent the parent composite.
param
logParser the current log parser.
return
the created control (which may have children).

        String title = getChartTitle(logParser);
        return createCompositeChart(parent, logParser, title);
    
private java.lang.StringgetChartTitle(com.android.ddmlib.log.EventLogParser logParser)
Returns a meaningful chart title based on the value of {@link #mValueDescriptorCheck}.

param
logParser the logParser.
return
the chart title.

        if (mValueDescriptors.size() > 0) {
            String chartDesc = null;
            switch (mValueDescriptorCheck) {
                case EVENT_CHECK_SAME_TAG:
                    if (logParser != null) {
                        chartDesc = logParser.getTagMap().get(mValueDescriptors.get(0).eventTag);
                    }
                    break;
                case EVENT_CHECK_SAME_VALUE:
                    if (logParser != null) {
                        chartDesc = String.format("%1$s / %2$s",
                                logParser.getTagMap().get(mValueDescriptors.get(0).eventTag),
                                mValueDescriptors.get(0).valueName);
                    }
                    break;
            }

            if (chartDesc != null) {
                return String.format("%1$s - %2$s", mName, chartDesc);
            }
        }

        return mName;
    
intgetDisplayType()
Gets display type

return
display type as an integer

        return DISPLAY_TYPE_GRAPH;
    
private org.jfree.data.time.TimeSeriesCollectiongetOccurrenceDataSet()
Returns the {@link TimeSeriesCollection} for the occurrence display. If the data set is not yet created, it is first allocated and set up into the {@link org.jfree.chart.JFreeChart} object.

        if (mOccurrenceDataSet == null) {
            mOccurrenceDataSet = new TimeSeriesCollection();

            XYPlot xyPlot = mChart.getXYPlot();
            xyPlot.setDataset(mDataSetCount, mOccurrenceDataSet);

            OccurrenceRenderer renderer = new OccurrenceRenderer();
            renderer.setBaseShapesVisible(false);
            xyPlot.setRenderer(mDataSetCount, renderer);

            mDataSetCount++;
        }

        return mOccurrenceDataSet;
    
private java.lang.StringgetSeriesLabel(com.android.ddmlib.log.EventContainer event, OccurrenceDisplayDescriptor descriptor)
Return the series label for this event. This only contains the pid information.

param
event the {@link EventContainer}
param
descriptor the {@link OccurrenceDisplayDescriptor}
return
the series label.
throws
InvalidTypeException

        if (descriptor.seriesValueIndex != -1) {
            if (descriptor.includePid == false) {
                return event.getValueAsString(descriptor.seriesValueIndex);
            } else {
                return String.format("%1$s (%2$d)",
                        event.getValueAsString(descriptor.seriesValueIndex), event.pid);
            }
        }

        return Integer.toString(event.pid);
    
private org.jfree.data.time.TimeSeriesCollectiongetValueDataset(EventValueDescription.ValueType type, boolean accumulateValues)
Returns a {@link TimeSeriesCollection} for a specific {@link com.android.ddmlib.log.EventValueDescription.ValueType}. If the data set is not yet created, it is first allocated and set up into the {@link org.jfree.chart.JFreeChart} object.

param
type the {@link com.android.ddmlib.log.EventValueDescription.ValueType} of the data set.
param
accumulateValues

        TimeSeriesCollection dataset = mValueTypeDataSetMap.get(type);
        if (dataset == null) {
            // create the data set and store it in the map
            dataset = new TimeSeriesCollection();
            mValueTypeDataSetMap.put(type, dataset);

            // create the renderer and configure it depending on the ValueType
            AbstractXYItemRenderer renderer;
            if (type == EventValueDescription.ValueType.PERCENT && accumulateValues) {
                renderer = new XYAreaRenderer();
            } else {
                XYLineAndShapeRenderer r = new XYLineAndShapeRenderer();
                r.setBaseShapesVisible(type != EventValueDescription.ValueType.PERCENT);

                renderer = r;
            }

            // set both the dataset and the renderer in the plot object.
            XYPlot xyPlot = mChart.getXYPlot();
            xyPlot.setDataset(mDataSetCount, dataset);
            xyPlot.setRenderer(mDataSetCount, renderer);

            // put a new axis label, and configure it.
            NumberAxis axis = new NumberAxis(type.toString());

            if (type == EventValueDescription.ValueType.PERCENT) {
                // force percent range to be (0,100) fixed.
                axis.setAutoRange(false);
                axis.setRange(0., 100.);
            }

            // for the index, we ignore the occurrence dataset
            int count = mDataSetCount;
            if (mOccurrenceDataSet != null) {
                count--;
            }

            xyPlot.setRangeAxis(count, axis);
            if ((count % 2) == 0) {
                xyPlot.setRangeAxisLocation(count, AxisLocation.BOTTOM_OR_LEFT);
            } else {
                xyPlot.setRangeAxisLocation(count, AxisLocation.TOP_OR_RIGHT);
            }

            // now we link the dataset and the axis
            xyPlot.mapDatasetToRangeAxis(mDataSetCount, count);

            mDataSetCount++;
        }

        return dataset;
    
voidnewEvent(com.android.ddmlib.log.EventContainer event, com.android.ddmlib.log.EventLogParser logParser)
Adds event to the display.

        ArrayList<ValueDisplayDescriptor> valueDescriptors =
                new ArrayList<ValueDisplayDescriptor>();

        ArrayList<OccurrenceDisplayDescriptor> occurrenceDescriptors =
                new ArrayList<OccurrenceDisplayDescriptor>();

        if (filterEvent(event, valueDescriptors, occurrenceDescriptors)) {
            updateChart(event, logParser, valueDescriptors, occurrenceDescriptors);
        }
    
voidresetUI()
Resets the display.

        Collection<TimeSeriesCollection> datasets = mValueTypeDataSetMap.values();
        for (TimeSeriesCollection dataset : datasets) {
            dataset.removeAllSeries();
        }
        if (mOccurrenceDataSet != null) {
            mOccurrenceDataSet.removeAllSeries();
        }
        mValueDescriptorSeriesMap.clear();
        mOcurrenceDescriptorSeriesMap.clear();
    
protected voidsetNewLogParser(com.android.ddmlib.log.EventLogParser logParser)
Sets the current {@link EventLogParser} object.

        if (mChart != null) {
            mChart.setTitle(getChartTitle(logParser));
        }
    
private voidupdateChart(com.android.ddmlib.log.EventContainer event, com.android.ddmlib.log.EventLogParser logParser, java.util.ArrayList valueDescriptors, java.util.ArrayList occurrenceDescriptors)
Updates the chart with the {@link EventContainer} by adding the values/occurrences defined by the {@link ValueDisplayDescriptor} and {@link OccurrenceDisplayDescriptor} objects from the two lists.

This method is only called when at least one of the descriptor list is non empty.

param
event
param
logParser
param
valueDescriptors
param
occurrenceDescriptors

        Map<Integer, String> tagMap = logParser.getTagMap();

        Millisecond millisecondTime = null;
        long msec = -1;

        // If the event container is a cpu container (tag == 2721), and there is no descriptor
        // for the total CPU load, then we do accumulate all the values.
        boolean accumulateValues = false;
        double accumulatedValue = 0;

        if (event.mTag == 2721) {
            accumulateValues = true;
            for (ValueDisplayDescriptor descriptor : valueDescriptors) {
                accumulateValues &= (descriptor.valueIndex != 0);
            }
        }

        for (ValueDisplayDescriptor descriptor : valueDescriptors) {
            try {
                // get the hashmap for this descriptor
                HashMap<Integer, TimeSeries> map = mValueDescriptorSeriesMap.get(descriptor);

                // if it's not there yet, we create it.
                if (map == null) {
                    map = new HashMap<Integer, TimeSeries>();
                    mValueDescriptorSeriesMap.put(descriptor, map);
                }

                // get the TimeSeries for this pid
                TimeSeries timeSeries = map.get(event.pid);

                // if it doesn't exist yet, we create it
                if (timeSeries == null) {
                    // get the series name
                    String seriesFullName = null;
                    String seriesLabel = getSeriesLabel(event, descriptor);

                    switch (mValueDescriptorCheck) {
                        case EVENT_CHECK_SAME_TAG:
                            seriesFullName = String.format("%1$s / %2$s", seriesLabel,
                                    descriptor.valueName);
                            break;
                        case EVENT_CHECK_SAME_VALUE:
                            seriesFullName = String.format("%1$s", seriesLabel);
                            break;
                        default:
                            seriesFullName = String.format("%1$s / %2$s: %3$s", seriesLabel,
                                    tagMap.get(descriptor.eventTag),
                                    descriptor.valueName);
                            break;
                    }

                    // get the data set for this ValueType
                    TimeSeriesCollection dataset = getValueDataset(
                            logParser.getEventInfoMap().get(event.mTag)[descriptor.valueIndex]
                                                                        .getValueType(),
                            accumulateValues);

                    // create the series
                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
                    if (mMaximumChartItemAge != -1) {
                        timeSeries.setMaximumItemAge(mMaximumChartItemAge * 1000);
                    }

                    dataset.addSeries(timeSeries);

                    // add it to the map.
                    map.put(event.pid, timeSeries);
                }

                // update the timeSeries.

                // get the value from the event
                double value = event.getValueAsDouble(descriptor.valueIndex);

                // accumulate the values if needed.
                if (accumulateValues) {
                    accumulatedValue += value;
                    value = accumulatedValue;
                }

                // get the time
                if (millisecondTime == null) {
                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
                    millisecondTime = new Millisecond(new Date(msec));
                }

                // add the value to the time series
                timeSeries.addOrUpdate(millisecondTime, value);
            } catch (InvalidTypeException e) {
                // just ignore this descriptor if there's a type mismatch
            }
        }

        for (OccurrenceDisplayDescriptor descriptor : occurrenceDescriptors) {
            try {
                // get the hashmap for this descriptor
                HashMap<Integer, TimeSeries> map = mOcurrenceDescriptorSeriesMap.get(descriptor);

                // if it's not there yet, we create it.
                if (map == null) {
                    map = new HashMap<Integer, TimeSeries>();
                    mOcurrenceDescriptorSeriesMap.put(descriptor, map);
                }

                // get the TimeSeries for this pid
                TimeSeries timeSeries = map.get(event.pid);

                // if it doesn't exist yet, we create it.
                if (timeSeries == null) {
                    String seriesLabel = getSeriesLabel(event, descriptor);

                    String seriesFullName = String.format("[%1$s:%2$s]",
                            tagMap.get(descriptor.eventTag), seriesLabel);

                    timeSeries = new TimeSeries(seriesFullName, Millisecond.class);
                    if (mMaximumChartItemAge != -1) {
                        timeSeries.setMaximumItemAge(mMaximumChartItemAge);
                    }

                    getOccurrenceDataSet().addSeries(timeSeries);

                    map.put(event.pid, timeSeries);
                }

                // update the series

                // get the time
                if (millisecondTime == null) {
                    msec = (long)event.sec * 1000L + (event.nsec / 1000000L);
                    millisecondTime = new Millisecond(new Date(msec));
                }

                // add the value to the time series
                timeSeries.addOrUpdate(millisecondTime, 0); // the value is unused
            } catch (InvalidTypeException e) {
                // just ignore this descriptor if there's a type mismatch
            }
        }

        // go through all the series and remove old values.
        if (msec != -1 && mMaximumChartItemAge != -1) {
            Collection<HashMap<Integer, TimeSeries>> pidMapValues =
                mValueDescriptorSeriesMap.values();

            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
                Collection<TimeSeries> seriesCollection = pidMapValue.values();

                for (TimeSeries timeSeries : seriesCollection) {
                    timeSeries.removeAgedItems(msec, true);
                }
            }

            pidMapValues = mOcurrenceDescriptorSeriesMap.values();
            for (HashMap<Integer, TimeSeries> pidMapValue : pidMapValues) {
                Collection<TimeSeries> seriesCollection = pidMapValue.values();

                for (TimeSeries timeSeries : seriesCollection) {
                    timeSeries.removeAgedItems(msec, true);
                }
            }
        }