public MPtrack(Table t) { super(new BorderLayout()); // -------------------------------------------------------------------- // STEP 1: setup the visualized data final Visualization vis = new Visualization(); m_vis = vis; final String group = "by_state"; VisualTable vt = vis.addTable(group, t); vis.setRendererFactory( new RendererFactory() { AbstractShapeRenderer sr = new ShapeRenderer(30); Renderer arY = new AxisRenderer(Constants.RIGHT, Constants.TOP); Renderer arX = new AxisRenderer(Constants.CENTER, Constants.FAR_BOTTOM); public Renderer getRenderer(VisualItem item) { return item.isInGroup("ylab") ? arY : item.isInGroup("xlab") ? arX : sr; } }); // -------------------------------------------------------------------- // set up the actions AxisLayout xaxis = new AxisLayout(group, "States", Constants.X_AXIS, VisiblePredicate.TRUE); AxisLayout yaxis = new AxisLayout(group, PARTY, Constants.Y_AXIS, VisiblePredicate.TRUE); // yaxis.setScale(Constants.LOG_SCALE); xaxis.setLayoutBounds(m_dataB); yaxis.setLayoutBounds(m_dataB); AxisLabelLayout ylabels = new AxisLabelLayout("ylab", yaxis, m_ylabB, 5); AxisLabelLayout xlabels = new AxisLabelLayout("xlab", xaxis, m_xlabB, 5); vis.putAction("xlabels", xlabels); int[] palette = new int[] {ColorLib.rgb(150, 150, 255)}; int[] palette2 = new int[200]; for (int i = 0; i < 200; i++) { palette2[i] = ColorLib.rgba(255, 0, 0, 2 * i); } /* DataColorAction color = new DataColorAction(group, "Party", Constants.ORDINAL, VisualItem.STROKECOLOR, palette); */ DataColorAction color2 = new DataColorAction(group, "Attendance", Constants.ORDINAL, VisualItem.FILLCOLOR, palette2); ActionList draw = new ActionList(); draw.add(color2); draw.add(xaxis); draw.add(yaxis); draw.add(ylabels); draw.add(new RepaintAction()); vis.putAction("draw", draw); ActionList update = new ActionList(); update.add(xaxis); update.add(yaxis); update.add(ylabels); update.add(new RepaintAction()); vis.putAction("update", update); UpdateListener lstnr = new UpdateListener() { public void update(Object src) { vis.run("update"); } }; // -------------------------------------------------------------------- // STEP 4: set up a display and ui components to show the visualization m_display = new Display(vis); m_display.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); m_display.setSize(700, 450); m_display.setHighQuality(true); m_display.addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent e) { displayLayout(); } }); displayLayout(); m_details = new JFastLabel(m_title); m_details.setPreferredSize(new Dimension(75, 20)); m_details.setVerticalAlignment(SwingConstants.BOTTOM); ToolTipControl ttc = new ToolTipControl("label"); Control hoverc = new ControlAdapter() { public void itemEntered(VisualItem item, MouseEvent evt) { if (item.isInGroup(group)) { item.setFillColor(item.getStrokeColor()); item.setStrokeColor(ColorLib.rgb(0, 0, 0)); item.getVisualization().repaint(); } } public void itemExited(VisualItem item, MouseEvent evt) { if (item.isInGroup(group)) { item.setFillColor(item.getEndFillColor()); item.setStrokeColor(item.getEndStrokeColor()); item.getVisualization().repaint(); } } }; m_display.addControlListener(ttc); m_display.addControlListener(hoverc); // -------------------------------------------------------------------- // STEP 5: launching the visualization this.addComponentListener(lstnr); // details Box infoBox = new Box(BoxLayout.X_AXIS); infoBox.add(Box.createHorizontalStrut(5)); infoBox.add(m_details); infoBox.add(Box.createHorizontalGlue()); infoBox.add(Box.createHorizontalStrut(5)); infoBox.add(Box.createHorizontalStrut(5)); // create dynamic queries Box radioBox = new Box(BoxLayout.X_AXIS); radioBox.add(Box.createHorizontalStrut(5)); radioBox.add(Box.createHorizontalGlue()); radioBox.add(Box.createHorizontalStrut(5)); radioBox.add(Box.createHorizontalStrut(16)); vis.run("draw"); vis.run("xlabels"); add(infoBox, BorderLayout.NORTH); add(m_display, BorderLayout.CENTER); add(radioBox, BorderLayout.SOUTH); UILib.setColor(this, ColorLib.getColor(255, 255, 255), Color.GRAY); UILib.setFont(radioBox, FontLib.getFont("Tahoma", 15)); m_details.setFont(FontLib.getFont("Tahoma", 18)); }
public Congress(Table t) { super(new BorderLayout()); // -------------------------------------------------------------------- // STEP 1: setup the visualized data final Visualization vis = new Visualization(); m_vis = vis; final String group = "by_state"; // filter to show only candidates receiving more than $100,000 Predicate p = (Predicate) ExpressionParser.parse("[" + TOTAL_RECEIPTS + "] >= 100000"); VisualTable vt = vis.addTable(group, t, p); // add a new column containing a label string showing // candidate name, party, state, year, and total receipts vt.addColumn( "label", "CONCAT(CAP(Candidate), ' (', " + "CAP([Party Designation]), '-', [State Code], " + "') ', Year, ': $', FORMAT([Total Receipts],2))"); // add calculation for senators vt.addColumn("Senate", "District <= 0"); vis.setRendererFactory( new RendererFactory() { AbstractShapeRenderer sr = new ShapeRenderer(); Renderer arY = new AxisRenderer(Constants.RIGHT, Constants.TOP); Renderer arX = new AxisRenderer(Constants.CENTER, Constants.FAR_BOTTOM); public Renderer getRenderer(VisualItem item) { return item.isInGroup("ylab") ? arY : item.isInGroup("xlab") ? arX : sr; } }); // -------------------------------------------------------------------- // STEP 2: create actions to process the visual data // set up dynamic queries, search set RangeQueryBinding receiptsQ = new RangeQueryBinding(vt, RECEIPTS); ListQueryBinding yearsQ = new ListQueryBinding(vt, "Year"); SearchQueryBinding searchQ = new SearchQueryBinding(vt, "Candidate"); // construct the filtering predicate AndPredicate filter = new AndPredicate(searchQ.getPredicate()); filter.add(yearsQ.getPredicate()); filter.add(receiptsQ.getPredicate()); // set up the actions AxisLayout xaxis = new AxisLayout(group, "State Code", Constants.X_AXIS, VisiblePredicate.TRUE); AxisLayout yaxis = new AxisLayout(group, RECEIPTS, Constants.Y_AXIS, VisiblePredicate.TRUE); // yaxis.setScale(Constants.LOG_SCALE); yaxis.setRangeModel(receiptsQ.getModel()); receiptsQ.getNumberModel().setValueRange(0, 65000000, 0, 65000000); xaxis.setLayoutBounds(m_dataB); yaxis.setLayoutBounds(m_dataB); AxisLabelLayout ylabels = new AxisLabelLayout("ylab", yaxis, m_ylabB); NumberFormat nf = NumberFormat.getCurrencyInstance(); nf.setMaximumFractionDigits(0); ylabels.setNumberFormat(nf); AxisLabelLayout xlabels = new AxisLabelLayout("xlab", xaxis, m_xlabB, 15); vis.putAction("xlabels", xlabels); // dems = blue, reps = red, other = gray int[] palette = new int[] { ColorLib.rgb(150, 150, 255), ColorLib.rgb(255, 150, 150), ColorLib.rgb(180, 180, 180) }; DataColorAction color = new DataColorAction(group, "Party", Constants.ORDINAL, VisualItem.STROKECOLOR, palette); int[] shapes = new int[] {Constants.SHAPE_RECTANGLE, Constants.SHAPE_DIAMOND}; DataShapeAction shape = new DataShapeAction(group, "Senate", shapes); Counter cntr = new Counter(group); ActionList draw = new ActionList(); draw.add(cntr); draw.add(color); draw.add(shape); draw.add(xaxis); draw.add(yaxis); draw.add(ylabels); draw.add(new ColorAction(group, VisualItem.FILLCOLOR, 0)); draw.add(new RepaintAction()); vis.putAction("draw", draw); ActionList update = new ActionList(); update.add(new VisibilityFilter(group, filter)); update.add(cntr); update.add(xaxis); update.add(yaxis); update.add(ylabels); update.add(new RepaintAction()); vis.putAction("update", update); UpdateListener lstnr = new UpdateListener() { public void update(Object src) { vis.run("update"); } }; filter.addExpressionListener(lstnr); // -------------------------------------------------------------------- // STEP 4: set up a display and ui components to show the visualization m_display = new Display(vis); m_display.setItemSorter( new ItemSorter() { public int score(VisualItem item) { int score = super.score(item); if (item.isInGroup(group)) score += item.getInt(TOTAL_RECEIPTS); return score; } }); m_display.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); m_display.setSize(700, 450); m_display.setHighQuality(true); m_display.addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent e) { displayLayout(); } }); displayLayout(); m_details = new JFastLabel(m_title); m_details.setPreferredSize(new Dimension(75, 20)); m_details.setVerticalAlignment(SwingConstants.BOTTOM); m_total.setPreferredSize(new Dimension(500, 20)); m_total.setHorizontalAlignment(SwingConstants.RIGHT); m_total.setVerticalAlignment(SwingConstants.BOTTOM); ToolTipControl ttc = new ToolTipControl("label"); Control hoverc = new ControlAdapter() { public void itemEntered(VisualItem item, MouseEvent evt) { if (item.isInGroup(group)) { m_total.setText(item.getString("label")); item.setFillColor(item.getStrokeColor()); item.setStrokeColor(ColorLib.rgb(0, 0, 0)); item.getVisualization().repaint(); } } public void itemExited(VisualItem item, MouseEvent evt) { if (item.isInGroup(group)) { m_total.setText(m_totalStr); item.setFillColor(item.getEndFillColor()); item.setStrokeColor(item.getEndStrokeColor()); item.getVisualization().repaint(); } } }; m_display.addControlListener(ttc); m_display.addControlListener(hoverc); // -------------------------------------------------------------------- // STEP 5: launching the visualization this.addComponentListener(lstnr); // details Box infoBox = new Box(BoxLayout.X_AXIS); infoBox.add(Box.createHorizontalStrut(5)); infoBox.add(m_details); infoBox.add(Box.createHorizontalGlue()); infoBox.add(Box.createHorizontalStrut(5)); infoBox.add(m_total); infoBox.add(Box.createHorizontalStrut(5)); // set up search box JSearchPanel searcher = searchQ.createSearchPanel(); searcher.setLabelText("Candidate: "); searcher.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); // create dynamic queries Box radioBox = new Box(BoxLayout.X_AXIS); radioBox.add(Box.createHorizontalStrut(5)); radioBox.add(searcher); radioBox.add(Box.createHorizontalGlue()); radioBox.add(Box.createHorizontalStrut(5)); radioBox.add(yearsQ.createRadioGroup()); radioBox.add(Box.createHorizontalStrut(16)); JRangeSlider slider = receiptsQ.createVerticalRangeSlider(); slider.setThumbColor(null); slider.setMinExtent(150000); slider.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { m_display.setHighQuality(false); } public void mouseReleased(MouseEvent e) { m_display.setHighQuality(true); m_display.repaint(); } }); vis.run("draw"); vis.run("xlabels"); add(infoBox, BorderLayout.NORTH); add(m_display, BorderLayout.CENTER); add(slider, BorderLayout.EAST); add(radioBox, BorderLayout.SOUTH); UILib.setColor(this, ColorLib.getColor(255, 255, 255), Color.GRAY); slider.setForeground(Color.LIGHT_GRAY); UILib.setFont(radioBox, FontLib.getFont("Tahoma", 15)); m_details.setFont(FontLib.getFont("Tahoma", 18)); m_total.setFont(FontLib.getFont("Tahoma", 16)); }
/* * Constructor for the class * This is where all the important stuff happens */ public TabularDataVis(Table t) { super(new BorderLayout()); /* * Step 1: Setup the Visualization */ // create a new visualization object, and assign it to the global variable final Visualization vis = new Visualization(); g_vis = vis; // create a visual abstraction of the table data (loaded in the buildFrame method) // call our data "canUrban" VisualTable vt = vis.addTable("canUrban", t); // add a new column containing a label string showing // the Geographic name and population // note: uses the prefuse expression language vt.addColumn( "label", "CONCAT([Geographic name], ' (Population: ', FORMAT([2006 Population],0), ')')"); // add a new column that divides the provinces by their geographic location (derived values) // note: uses the prefuse expression language vt.addColumn( "geographic location", "IF ([Province]='BC') THEN 1 ELSE " + "(IF ([Province] = 'AB' OR [Province] = 'SK' OR [Province] = 'MB') THEN 2 ELSE " + "(IF ([Province] = 'ON' OR [Province] = 'QC') THEN 3 ELSE" + "(IF ([Province] = 'NS' OR [Province] = 'NB' OR [Province] = 'PE' OR [Province] = 'NL') THEN 4 ELSE 5)))"); // add a new column that converts the population data to ordinal data (derived values) // note: uses the prefuse expression language vt.addColumn( "population ordinal", "IF ([2006 Population] > 5000000) THEN 7 ELSE " + "(IF ([2006 Population] > 1000000) THEN 6 ELSE " + "(IF ([2006 Population] > 250000) THEN 5 ELSE " + "(IF ([2006 Population] > 100000) THEN 4 ELSE " + "(IF ([2006 Population] > 50000) THEN 3 ELSE " + "(IF ([2006 Population] > 20000) THEN 2 ELSE 1)))))"); // create a new renderer factory for drawing the visual items vis.setRendererFactory( new RendererFactory() { // specify the default shape renderer (the actions will decide how to actually render the // visual elements) AbstractShapeRenderer sr = new ShapeRenderer(); // renderers for the axes Renderer arY = new AxisRenderer(Constants.RIGHT, Constants.TOP); Renderer arX = new AxisRenderer(Constants.CENTER, Constants.FAR_BOTTOM); // return the appropriate renderer for a given visual item public Renderer getRenderer(VisualItem item) { return item.isInGroup("ylab") ? arY : item.isInGroup("xlab") ? arX : sr; } }); /* * Step 2: Add X-Axis */ // add the x-axis AxisLayout xaxis = new AxisLayout("canUrban", "Province", Constants.X_AXIS, VisiblePredicate.TRUE); // ensure the axis spans the width of the data container xaxis.setLayoutBounds(g_dataB); // add the labels to the x-axis AxisLabelLayout xlabels = new AxisLabelLayout("xlab", xaxis, g_xlabB, 15); /* * Step 3: Add the Y-Axis and its dynamic query feature */ // dynamic query based on population data RangeQueryBinding populationQ = new RangeQueryBinding(vt, "2006 Population"); AndPredicate filter = new AndPredicate(populationQ.getPredicate()); // add the y-axis AxisLayout yaxis = new AxisLayout("canUrban", "2006 Population", Constants.Y_AXIS, VisiblePredicate.TRUE); // set the range controls on the y-axis yaxis.setRangeModel(populationQ.getModel()); populationQ.getNumberModel().setValueRange(0, 6000000, 0, 6000000); // ensure the y-axis spans the height of the data container yaxis.setLayoutBounds(g_dataB); // add the labels to the y-axis AxisLabelLayout ylabels = new AxisLabelLayout("ylab", yaxis, g_ylabB); NumberFormat nf = NumberFormat.getIntegerInstance(); nf.setMaximumFractionDigits(0); ylabels.setNumberFormat(nf); /* * Step 4: Add the search box */ // dynamic query based on Geographic name data SearchQueryBinding searchQ = new SearchQueryBinding(vt, "Geographic name"); filter.add(searchQ.getPredicate()); // reuse the same filter as the population query /* * Step 5: Colours and Shapes */ // assign a set of five perceptually distinct colours to assign to the provinces // chosen from ColorBrewer (5-class qualitative Set1) int[] palette = new int[] { ColorLib.rgb(77, 175, 74), ColorLib.rgb(55, 126, 184), ColorLib.rgb(228, 26, 28), ColorLib.rgb(152, 78, 163), ColorLib.rgb(255, 127, 0) }; // specify the stroke (exterior line) based on the ordinal data DataColorAction color = new DataColorAction( "canUrban", "geographic location", Constants.ORDINAL, VisualItem.STROKECOLOR, palette); // specify the fill (interior) as a static colour (white) ColorAction fill = new ColorAction("canUrban", VisualItem.FILLCOLOR, 0); // represent all the data points with rectangles ShapeAction shape = new ShapeAction("canUrban", Constants.SHAPE_RECTANGLE); // assign the size of the visual element based on the population data (we // converted the 2006 Population data to ordinal values) DataSizeAction size = new DataSizeAction("canUrban", "population ordinal"); // setup a counter to keep track of which data points are currently being viewed Counter cntr = new Counter("canUrban"); /* * Step 6: Create the action list for drawing the visual elements */ ActionList draw = new ActionList(); draw.add(cntr); draw.add(color); draw.add(fill); draw.add(shape); draw.add(size); draw.add(xaxis); draw.add(yaxis); draw.add(ylabels); draw.add(new RepaintAction()); vis.putAction("draw", draw); vis.putAction("xlabels", xlabels); /* * create the action list for updating the visual elements * (during interactive operations and re-sizing of the window) */ ActionList update = new ActionList(); update.add(new VisibilityFilter("canUrban", filter)); // filter performs the size/name filtering update.add(cntr); update.add(xaxis); update.add(yaxis); update.add(ylabels); update.add(new RepaintAction()); vis.putAction("update", update); // create an update listener that will update the visualization when fired UpdateListener lstnr = new UpdateListener() { public void update(Object src) { vis.run("update"); } }; // add this update listener to the filter, so that when the filter changes (i.e., // the user adjusts the axis parameters, or enters a name for filtering), the // visualization is updated filter.addExpressionListener(lstnr); /* * Step 7: Setup the Display and the other Interface components * (scroll bar, query box, tool tips) */ // create the display g_display = new Display(vis); // set the display properties g_display.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20)); g_display.setSize(700, 450); g_display.setHighQuality(true); // call the function that sets the sizes of the containers that contain // the data and the axes displayLayout(); // whenever the window is re-sized, update the layout of the axes g_display.addComponentListener( new ComponentAdapter() { public void componentResized(ComponentEvent e) { displayLayout(); } }); // title label (top left) JFastLabel g_details = new JFastLabel("Canadian Urban Population"); g_details.setPreferredSize(new Dimension(350, 20)); g_details.setVerticalAlignment(SwingConstants.BOTTOM); // total label (top right) g_total.setPreferredSize(new Dimension(350, 20)); g_total.setHorizontalAlignment(SwingConstants.RIGHT); g_total.setVerticalAlignment(SwingConstants.BOTTOM); // tool tips ToolTipControl ttc = new ToolTipControl("label"); Control hoverc = new ControlAdapter() { public void itemEntered(VisualItem item, MouseEvent evt) { if (item.isInGroup("canUrban")) { g_total.setText(item.getString("label")); item.setFillColor(item.getStrokeColor()); item.setStrokeColor(ColorLib.rgb(0, 0, 0)); item.getVisualization().repaint(); } } public void itemExited(VisualItem item, MouseEvent evt) { if (item.isInGroup("canUrban")) { g_total.setText(g_totalStr); item.setFillColor(item.getEndFillColor()); item.setStrokeColor(item.getEndStrokeColor()); item.getVisualization().repaint(); } } }; g_display.addControlListener(ttc); g_display.addControlListener(hoverc); // vertical slider for adjusting the population filter JRangeSlider slider = populationQ.createVerticalRangeSlider(); slider.setThumbColor(null); slider.setToolTipText("drag the arrows to filter the data"); // smallest window: 200,000 slider.setMinExtent(200000); slider.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent e) { g_display.setHighQuality(false); } public void mouseReleased(MouseEvent e) { g_display.setHighQuality(true); g_display.repaint(); } }); // search box JSearchPanel searcher = searchQ.createSearchPanel(); searcher.setLabelText("Urban Centre: "); searcher.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); /* * Step 8: Create Containers for the Interface Elements */ // add the listener to this component this.addComponentListener(lstnr); // container for elements at the top of the screen Box topContainer = new Box(BoxLayout.X_AXIS); topContainer.add(Box.createHorizontalStrut(5)); topContainer.add(g_details); topContainer.add(Box.createHorizontalGlue()); topContainer.add(Box.createHorizontalStrut(5)); topContainer.add(g_total); topContainer.add(Box.createHorizontalStrut(5)); // container for elements at the bottom of the screen Box bottomContainer = new Box(BoxLayout.X_AXIS); bottomContainer.add(Box.createHorizontalStrut(5)); bottomContainer.add(searcher); bottomContainer.add(Box.createHorizontalGlue()); bottomContainer.add(Box.createHorizontalStrut(5)); bottomContainer.add(Box.createHorizontalStrut(16)); // fonts, colours, etc. UILib.setColor(this, ColorLib.getColor(255, 255, 255), Color.GRAY); slider.setForeground(Color.LIGHT_GRAY); UILib.setFont(bottomContainer, FontLib.getFont("Tahoma", 15)); g_details.setFont(FontLib.getFont("Tahoma", 18)); g_total.setFont(FontLib.getFont("Tahoma", 16)); // add the containers to the JPanel add(topContainer, BorderLayout.NORTH); add(g_display, BorderLayout.CENTER); add(slider, BorderLayout.EAST); add(bottomContainer, BorderLayout.SOUTH); /* * Step 9: Start the Visualization */ vis.run("draw"); vis.run("xlabels"); }