// ============================================================================ // // Copyright (C) 2006-2016 Talend Inc. - www.talend.com // // This source code is available under agreement available at // %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt // // You should have received a copy of the agreement // along with this program; if not, write to Talend SA // 9 rue Pages 92150 Suresnes, France // // ============================================================================ package org.talend.dataprofiler.core.ui.editor.analysis; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.common.util.EList; import org.eclipse.jface.dialogs.ProgressMonitorDialog; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITableColorProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerSorter; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; import org.talend.core.model.metadata.builder.connection.MetadataColumn; import org.talend.cwm.relational.TdColumn; import org.talend.dataprofiler.core.ImageLib; import org.talend.dataprofiler.core.PluginConstant; import org.talend.dataprofiler.core.i18n.internal.DefaultMessagesImpl; import org.talend.dataprofiler.core.ui.ColumnSortListener; import org.talend.dataprofiler.core.ui.chart.jung.JungGraphGenerator; import org.talend.dataprofiler.core.ui.editor.preview.ColumnSetIndicatorUnit; import org.talend.dataprofiler.core.ui.editor.preview.HideSeriesChartComposite; import org.talend.dataprofiler.core.ui.editor.preview.IndicatorUnit; import org.talend.dataprofiler.core.ui.editor.preview.model.ChartTypeStatesFactory; import org.talend.dataprofiler.core.ui.editor.preview.model.TableTypeStatesFactory; import org.talend.dataprofiler.core.ui.editor.preview.model.TableWithData; import org.talend.dataprofiler.core.ui.editor.preview.model.states.IChartTypeStates; import org.talend.dataprofiler.core.ui.editor.preview.model.states.table.ITableTypeStates; import org.talend.dataprofiler.core.ui.utils.TOPChartUtils; import org.talend.dataprofiler.core.ui.utils.TableUtils; import org.talend.dataquality.indicators.columnset.ColumnSetMultiValueIndicator; import org.talend.dataquality.indicators.columnset.ColumnsetPackage; import org.talend.dataquality.indicators.columnset.CountAvgNullIndicator; import org.talend.dq.analysis.AnalysisHandler; import org.talend.dq.indicators.graph.GraphBuilder; import org.talend.dq.indicators.preview.EIndicatorChartType; import org.talend.dq.nodes.indicator.type.IndicatorEnum; import orgomg.cwm.objectmodel.core.ModelElement; /** * DOC xzhao class global comment. Detailled comment */ public class CorrelationAnalysisResultPage extends AbstractAnalysisResultPage implements PropertyChangeListener { protected static Logger log = Logger.getLogger(CorrelationAnalysisResultPage.class); private Composite graphicsAndTableComp; private CorrelationAnalysisDetailsPage masterPage; private ColumnSetMultiValueIndicator columnSetMultiIndicator; private Composite chartComposite; private Composite[] previewChartCompsites; private String executeData; private Section graphicsAndTableSection = null; /** * DOC zqin ColumnAnalysisResultPage constructor comment. * * @param editor * @param id * @param title */ public CorrelationAnalysisResultPage(FormEditor editor, String id, String title) { super(editor, id, title); AnalysisEditor analysisEditor = (AnalysisEditor) editor; this.masterPage = (CorrelationAnalysisDetailsPage) analysisEditor.getMasterPage(); columnSetMultiIndicator = masterPage.getColumnSetMultiValueIndicator(); } @Override protected void createFormContent(IManagedForm managedForm) { super.createFormContent(managedForm); if (topComposite != null && !topComposite.isDisposed()) { graphicsAndTableComp = toolkit.createComposite(topComposite); graphicsAndTableComp.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING)); graphicsAndTableComp.setLayout(new GridLayout()); createResultSection(graphicsAndTableComp); form.reflow(true); } } @Override protected AnalysisHandler getAnalysisHandler() { return this.masterPage.getAnalysisHandler(); } @Override protected void createResultSection(Composite parent) { executeData = getAnalysisHandler().getExecuteData(); graphicsAndTableSection = this.createSection(form, parent, DefaultMessagesImpl.getString("ColumnCorrelationNominalIntervalResultPage.AnalysisResult"), null); //$NON-NLS-1$ Composite sectionClient = toolkit.createComposite(graphicsAndTableSection); sectionClient.setLayout(new GridLayout()); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite graphicsComp = toolkit.createComposite(sectionClient); graphicsComp.setLayoutData(new GridData(GridData.FILL_BOTH)); graphicsComp.setLayout(new GridLayout()); if (executeData == null || executeData.equals(PluginConstant.EMPTY_STRING)) { return; } else { if (canShowChartForResultPage()) { this.createGraphicsSectionPart(sectionClient); } } Composite simpleSatisticsComp = toolkit.createComposite(sectionClient); simpleSatisticsComp.setLayoutData(new GridData(GridData.FILL_BOTH)); simpleSatisticsComp.setLayout(new GridLayout()); if (executeData == null || executeData.equals(PluginConstant.EMPTY_STRING)) { return; } else { this.createSimpleStatisticsPart( sectionClient, DefaultMessagesImpl.getString("ColumnCorrelationNominalIntervalResultPage.SimpleStatistics"), columnSetMultiIndicator); //$NON-NLS-1$ } Composite tableComp = toolkit.createComposite(sectionClient); tableComp.setLayoutData(new GridData(GridData.FILL_BOTH)); tableComp.setLayout(new GridLayout()); if (executeData == null || executeData.equals(PluginConstant.EMPTY_STRING)) { return; } else { this.createTableSectionPart(sectionClient, DefaultMessagesImpl.getString("ColumnCorrelationNominalIntervalResultPage.Data"), columnSetMultiIndicator); //$NON-NLS-1$ } graphicsAndTableSection.setExpanded(true); graphicsAndTableSection.setClient(sectionClient); } protected Section createGraphicsSectionPart(Composite parentComp) { Section section = createSection(form, parentComp, DefaultMessagesImpl.getString("ColumnMasterDetailsPage.graphics"), //$NON-NLS-1$ DefaultMessagesImpl.getString("ColumnMasterDetailsPage.space")); //$NON-NLS-1$ section.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite sectionClient = toolkit.createComposite(section); sectionClient.setLayout(new GridLayout()); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).applyTo(sectionClient); chartComposite = toolkit.createComposite(sectionClient); chartComposite.setLayout(new GridLayout()); if (ColumnsetPackage.eINSTANCE.getWeakCorrelationIndicator() == columnSetMultiIndicator.eClass()) { GridData gd = new GridData(); gd.widthHint = 900; gd.heightHint = 450; chartComposite.setLayoutData(gd); GraphBuilder gBuilder = new GraphBuilder(); gBuilder.setTotalWeight(columnSetMultiIndicator.getCount()); List<Object[]> listRows = columnSetMultiIndicator.getListRows(); // MOD msjian TDQ-4781 2012-6-8: make sure exist data if (listRows != null && listRows.size() > 0) { JungGraphGenerator generator = new JungGraphGenerator(gBuilder, listRows); // MOD yyi 2009-09-09 feature 8834 generator.generate(chartComposite, false, false); } // TDQ-4781~ } else { createBubbleOrGanttChart(form, chartComposite, columnSetMultiIndicator); } section.setClient(sectionClient); return section; } private void createBubbleOrGanttChart(final ScrolledForm sForm, final Composite composite, final ColumnSetMultiValueIndicator columnSetMultiValueIndicator) { List<Composite> previewChartList = new ArrayList<Composite>(); List<ModelElement> bubOrGanttColumnList = new ArrayList<ModelElement>(); if (columnSetMultiValueIndicator instanceof CountAvgNullIndicator) { bubOrGanttColumnList = columnSetMultiValueIndicator.getNumericColumns(); } else { bubOrGanttColumnList = columnSetMultiValueIndicator.getDateColumns(); } for (ModelElement column : bubOrGanttColumnList) { final MetadataColumn tdColumn = (MetadataColumn) column; final ExpandableComposite exComp = toolkit.createExpandableComposite(composite, ExpandableComposite.TREE_NODE | ExpandableComposite.CLIENT_INDENT); exComp.setText(DefaultMessagesImpl.getString("ColumnMasterDetailsPage.column", tdColumn.getName())); //$NON-NLS-1$ exComp.setLayout(new GridLayout()); exComp.setData(columnSetMultiValueIndicator); previewChartList.add(exComp); final Composite comp = toolkit.createComposite(exComp); comp.setLayout(new GridLayout(2, false)); comp.setLayoutData(new GridData(GridData.FILL_BOTH)); if (tdColumn != null) { IRunnableWithProgress rwp = new IRunnableWithProgress() { public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { monitor.beginTask( DefaultMessagesImpl.getString( "ColumnCorrelationNominalIntervalResultPage.CreatePreview", tdColumn.getName()), IProgressMonitor.UNKNOWN); //$NON-NLS-1$ Display.getDefault().asyncExec(new Runnable() { public void run() { HideSeriesChartComposite hcc = new HideSeriesChartComposite(comp, getAnalysisHandler() .getAnalysis(), columnSetMultiValueIndicator, tdColumn, true); GridData gd = new GridData(); gd.widthHint = 800; gd.heightHint = 450; hcc.setLayoutData(gd); } }); monitor.done(); } }; try { new ProgressMonitorDialog(getSite().getShell()).run(true, false, rwp); } catch (Exception ex) { log.error(ex, ex); } } exComp.addExpansionListener(new ExpansionAdapter() { @Override public void expansionStateChanged(ExpansionEvent e) { getChartComposite().layout(); sForm.reflow(true); } }); exComp.setExpanded(true); exComp.setClient(comp); } if (!previewChartList.isEmpty()) { this.previewChartCompsites = previewChartList.toArray(new Composite[previewChartList.size()]); } } private Section createSimpleStatisticsPart(Composite parentComp, String title, ColumnSetMultiValueIndicator columnSetMultiValueIndicator) { Section section = createSection(form, parentComp, title, DefaultMessagesImpl.getString("ColumnMasterDetailsPage.space")); //$NON-NLS-1$ section.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite sectionClient = toolkit.createComposite(section); sectionClient.setLayout(new GridLayout()); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); GridDataFactory.fillDefaults().align(SWT.FILL, SWT.TOP).applyTo(sectionClient); Composite simpleComposite = toolkit.createComposite(sectionClient); simpleComposite.setLayout(new GridLayout(2, true)); simpleComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); createSimpleStatistics2(simpleComposite, columnSetMultiValueIndicator); section.setClient(sectionClient); return section; } private void createSimpleStatistics2(final Composite composite, final ColumnSetMultiValueIndicator columnSetMultiValueIndicator) { List<IndicatorUnit> units = new ArrayList<IndicatorUnit>(); units.add(new ColumnSetIndicatorUnit(IndicatorEnum.RowCountIndicatorEnum, columnSetMultiValueIndicator .getRowCountIndicator())); units.add(new ColumnSetIndicatorUnit(IndicatorEnum.DistinctCountIndicatorEnum, columnSetMultiValueIndicator .getDistinctCountIndicator())); units.add(new ColumnSetIndicatorUnit(IndicatorEnum.DuplicateCountIndicatorEnum, columnSetMultiValueIndicator .getDuplicateCountIndicator())); units.add(new ColumnSetIndicatorUnit(IndicatorEnum.UniqueIndicatorEnum, columnSetMultiValueIndicator .getUniqueCountIndicator())); EIndicatorChartType simpleStatType = EIndicatorChartType.SIMPLE_STATISTICS; // create table viewer firstly ITableTypeStates tableTypeState = TableTypeStatesFactory.getInstance().getTableState(simpleStatType, units); TableWithData chartData = new TableWithData(simpleStatType, tableTypeState.getDataEntity()); TableViewer tableviewer = tableTypeState.getTableForm(composite); tableviewer.setInput(chartData); TableUtils.addTooltipForTable(tableviewer.getTable()); // create chart if (canShowChartForResultPage()) { // then create chart IChartTypeStates chartTypeState = ChartTypeStatesFactory.getChartState(simpleStatType, units); Object chart = chartTypeState.getChart(); TOPChartUtils.getInstance().decorateChart(chart, false); if (chart != null) { TOPChartUtils.getInstance().createChartComposite(composite, SWT.NONE, chart, true); } } } private Section createTableSectionPart(Composite parentComp, String title, ColumnSetMultiValueIndicator csMultiIndicator) { Section columnSetElementSection = this.createSection(form, parentComp, title, null); Composite sectionTableComp = toolkit.createComposite(columnSetElementSection); sectionTableComp.setLayoutData(new GridData(GridData.FILL_BOTH)); sectionTableComp.setLayout(new GridLayout()); TableViewer columnsElementViewer = new TableViewer(sectionTableComp, SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER); Table table = columnsElementViewer.getTable(); List<String> tableColumnNames = getTableColumnNames(csMultiIndicator); for (String tableColumnName : tableColumnNames) { final TableColumn columnHeader = new TableColumn(table, SWT.NONE); columnHeader.setText(tableColumnName); } table.setLinesVisible(true); table.setHeaderVisible(true); TableSectionViewerProvider provider = new TableSectionViewerProvider(); List<Object[]> tableRows = csMultiIndicator.getListRows(); columnsElementViewer.setContentProvider(provider); columnsElementViewer.setLabelProvider(provider); columnsElementViewer.setInput(tableRows); for (int i = 0; i < tableColumnNames.size(); i++) { table.getColumn(i).pack(); } columnSetElementSection.setClient(sectionTableComp); // ADDED sgandon 15/03/2010 bug 11769 : setup the size of the table to avoid crash and add consistency. // MOD msjian 2011-5-30 17479: Excel Odbc connection can not run well on the correlation analysis setupTableGridDataLimitedSize(table, tableRows != null ? tableRows.size() : 0); // ~ addColumnSorters(columnsElementViewer, table.getColumns(), this.buildSorter(tableRows)); columnSetElementSection.setExpanded(false); return columnSetElementSection; } /** * get the table column names from ColumnSetMultiValueIndicator, all the column with nominal type should be ahead of * the column with other types. * * @param csMultiIndicator * @return */ private List<String> getTableColumnNames(ColumnSetMultiValueIndicator csMultiIndicator) { EList<ModelElement> nominalColumns = csMultiIndicator.getNominalColumns(); List<String> nominalColumnNames = new ArrayList<String>(); for (ModelElement me : nominalColumns) { nominalColumnNames.add(me.getName()); } List<String> nominalHeaders = new ArrayList<String>(); List<String> otherHeaders = new ArrayList<String>(); EList<String> columnHeaders = csMultiIndicator.getColumnHeaders(); for (String s : columnHeaders) { if (nominalColumnNames.contains(s)) { nominalHeaders.add(s); } else { otherHeaders.add(s); } } List<String> finalHeaders = new ArrayList<String>(); finalHeaders.addAll(nominalColumnNames); finalHeaders.addAll(otherHeaders); return finalHeaders; } /** * * DOC hcheng Comment method "addColumnSorters".For 8267. * * @param tableViewer * @param tableColumns * @param sorters */ protected void addColumnSorters(TableViewer tableViewer, TableColumn[] tableColumns, ViewerSorter[][] sorters) { for (int i = 0; i < tableColumns.length; ++i) { tableColumns[i].addSelectionListener(new ColumnSortListener(tableColumns, i, tableViewer, sorters)); } } private Color bg = new Color(null, 249, 139, 121); /** * * DOC zhaoxinyi ColumnCorrelationNominalIntervalResultPage class global comment. Detailled comment */ class TableSectionViewerProvider implements IStructuredContentProvider, ITableLabelProvider, ITableColorProvider { @SuppressWarnings("unchecked") public Object[] getElements(Object inputElement) { List<Object> columnDataSet = (List<Object>) inputElement; return columnDataSet.toArray(); } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { // no need to implement } public Image getImage(Object element) { if (element instanceof TdColumn) { return ImageLib.getImage(ImageLib.TD_COLUMN); } return null; } public void dispose() { // TODO Auto-generated method stub } public Image getColumnImage(Object element, int columnIndex) { return null; } public String getColumnText(Object element, int columnIndex) { for (int i = 0; i < ((Object[]) element).length; i++) { if (columnIndex == i) { return String.valueOf(((Object[]) element)[i]); } } return null; } public void addListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } public boolean isLabelProperty(Object element, String property) { return false; } public void removeListener(ILabelProviderListener listener) { // TODO Auto-generated method stub } public Color getBackground(Object element, int columnIndex) { Object[] elements = (Object[]) element; for (Object elem : elements) { if (elem == null || "".equals(elem)) { //$NON-NLS-1$ return bg; } } return null; } public Color getForeground(Object element, int columnIndex) { // TODO Auto-generated method stub return null; } } /* * (non-Javadoc) * * @see org.talend.dataprofiler.core.ui.editor.AbstractFormPage#setDirty(boolean) */ @Override public void setDirty(boolean isDirty) { // TODO do nothing here? } /* * (non-Javadoc) * * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent) */ public void propertyChange(PropertyChangeEvent evt) { if (PluginConstant.ISDIRTY_PROPERTY.equals(evt.getPropertyName())) { ((AnalysisEditor) this.getEditor()).firePropertyChange(IEditorPart.PROP_DIRTY); } } /* * (non-Javadoc) * * @see * org.talend.dataprofiler.core.ui.editor.analysis.AbstractAnalysisResultPage#refresh(org.talend.dataprofiler.core * .ui.editor.analysis.AbstractAnalysisMetadataPage) */ @Override public void refresh(AbstractAnalysisMetadataPage mPage) { this.masterPage = (CorrelationAnalysisDetailsPage) mPage; if (summaryComp != null && !summaryComp.isDisposed()) { summaryComp.dispose(); } if (graphicsAndTableComp != null && !graphicsAndTableComp.isDisposed()) { graphicsAndTableComp.dispose(); } createFormContent(getManagedForm()); } public Composite getChartComposite() { return chartComposite; } public Composite[] getPreviewChartCompsites() { return previewChartCompsites; } @Override public void dispose() { if (bg != null) { bg.dispose(); } super.dispose(); } private CorrelationDataSorter[][] buildSorter(List<Object[]> tableRows) { CorrelationDataSorter[][] result = null; if (tableRows != null && tableRows.size() > 0) { Object[] objs = tableRows.get(0); int length = objs.length; result = new CorrelationDataSorter[length][2]; for (int i = 0; i < length; ++i) { result[i][0] = new CorrelationDataSorter(i + 1); result[i][1] = new CorrelationDataSorter(-(i + 1)); } } return result; } }