use of org.knime.base.node.viz.histogram.HistogramLayout in project knime-core by knime.
the class BarDataModel method updateBarWidth.
/**
* @param startX the x coordinate
* @param newWidth the new bar width
* @param barElementColors all element colors which define the order
* the elements should be drawn
* @param baseLine the base line
* @param calculator the hilite shape calculator
*/
public void updateBarWidth(final int startX, final int newWidth, final List<Color> barElementColors, final int baseLine, final HistogramHiliteCalculator calculator) {
final Rectangle2D barRectangle = getShape();
if (barRectangle == null) {
return;
}
final HistogramLayout layout = calculator.getLayout();
final boolean drawElementsBefore = isPresentable();
final int yCoord = (int) barRectangle.getY();
final int barHeight = (int) barRectangle.getHeight();
final Rectangle rect = new Rectangle(startX, yCoord, newWidth, barHeight);
setRectangle(rect, baseLine, calculator);
final int barWidth = (int) barRectangle.getWidth();
final int barX = (int) barRectangle.getX();
final int noOfElements = getNoOfElements();
setPresentable(elementsFitInBar(layout, barElementColors, noOfElements, barWidth, barHeight), calculator);
if (!isPresentable()) {
// if the elements doesn't fit any way return here
return;
}
if (!drawElementsBefore) {
// if the elements couldn't be draw before but now recalculate
// them
setElementRectangle(baseLine, barElementColors, calculator);
return;
}
if (HistogramLayout.STACKED.equals(layout)) {
for (final Color elementColor : barElementColors) {
final BarElementDataModel element = getElement(elementColor);
if (element != null) {
element.updateElementWidth(barX, barWidth, calculator);
}
}
} else if (HistogramLayout.SIDE_BY_SIDE.equals(layout)) {
int xCoord = barX;
final int elementWidth = calculateSideBySideElementWidth(barElementColors, barWidth);
for (final Color elementColor : barElementColors) {
final BarElementDataModel element = getElement(elementColor);
if (element != null) {
element.updateElementWidth(xCoord, elementWidth, calculator);
}
// add the bar width and the space between bars to the current
// x coordinate
xCoord += elementWidth + AbstractHistogramVizModel.SPACE_BETWEEN_ELEMENTS;
}
} else {
throw new IllegalArgumentException("Layout " + layout + " not supported");
}
return;
}
use of org.knime.base.node.viz.histogram.HistogramLayout in project knime-core by knime.
the class BinDataModel method setBarRectangle.
/**
* Sets the rectangle for all bars in this bin.
* @param baseLine the x coordinate of the base line (0) on the screen
* @param barElementColors all element colors which define the order
* the elements should be drawn
* @param aggrColumns the aggregation column array which indicates
* the order of the bars
*/
private void setBarRectangle(final int baseLine, final List<Color> barElementColors, final Collection<? extends ColorColumn> aggrColumns, final HistogramHiliteCalculator calculator) {
if (m_binRectangle == null) {
final Collection<BarDataModel> bars = m_bars.values();
// also reset the bar rectangle
for (final BarDataModel bar : bars) {
bar.setBarRectangle(null, baseLine, barElementColors, calculator);
}
return;
}
final AggregationMethod aggrMethod = calculator.getAggrMethod();
final HistogramLayout layout = calculator.getLayout();
final int binWidth = (int) m_binRectangle.getWidth();
final int noOfBars = aggrColumns.size();
m_presentable = elementsFitInBin(noOfBars, binWidth);
if (!m_presentable) {
return;
}
// calculate the height
final int binHeight = (int) m_binRectangle.getHeight();
final double maxAggrVal = Math.max(getMaxAggregationValue(aggrMethod, layout), 0);
final double minAggrVal = Math.min(getMinAggregationValue(aggrMethod, layout), 0);
final double valRange = maxAggrVal + Math.abs(minAggrVal);
if (valRange <= 0) {
m_presentable = false;
return;
}
final int barWidth = calculateBarWidth(binWidth, noOfBars);
final double heightPerVal = binHeight / valRange;
final int binX = (int) m_binRectangle.getX();
int xCoord = binX;
for (final ColorColumn aggrColumn : aggrColumns) {
final BarDataModel bar = m_bars.get(aggrColumn.getColor());
if (bar != null) {
// set the rectangle only for the bars which are available
// in this bin
final double barMaxAggrVal = Math.max(bar.getMaxAggregationValue(aggrMethod, layout), 0);
final double barMinAggrVal = Math.min(bar.getMinAggregationValue(aggrMethod, layout), 0);
final double aggrVal = barMaxAggrVal + Math.abs(barMinAggrVal);
final int yCoord = (int) (baseLine - (barMaxAggrVal * heightPerVal));
final int barHeight = (int) (aggrVal * heightPerVal);
final Rectangle barRect = new Rectangle(xCoord, yCoord, barWidth, barHeight);
bar.setBarRectangle(barRect, baseLine, barElementColors, calculator);
}
// add the bar width and the space between bars to the current
// x coordinate
xCoord += barWidth + AbstractHistogramVizModel.SPACE_BETWEEN_BARS;
}
}
use of org.knime.base.node.viz.histogram.HistogramLayout in project knime-core by knime.
the class BarDataModel method setElementRectangle.
/**
* @param baseLine the x coordinate of the base line (0) on the screen
* @param barElementColors all element colors which define the order
* the elements should be drawn
*/
private void setElementRectangle(final int baseLine, final List<Color> barElementColors, final HistogramHiliteCalculator calculator) {
final Rectangle2D barRectangle = getShape();
if (barRectangle == null) {
// also reset the element rectangles
final Collection<BarElementDataModel> elements = getElements();
for (final BarElementDataModel element : elements) {
element.setRectangle(null, calculator);
}
return;
}
final AggregationMethod aggrMethod = calculator.getAggrMethod();
final HistogramLayout layout = calculator.getLayout();
final double maxAggrVal = getMaxAggregationValue(aggrMethod, layout);
final double minAggrVal = getMinAggregationValue(aggrMethod, layout);
double valRange;
if (minAggrVal < 0 && maxAggrVal > 0) {
// if the bar contains negative and positive elements
// we have to add the min and max aggregation value
// to get the full range
valRange = maxAggrVal + Math.abs(minAggrVal);
} else {
// if the bar contains either negative or positive elements
// simply take the maximum since one of them is zero
valRange = Math.max(Math.abs(maxAggrVal), Math.abs(minAggrVal));
}
final int barHeight = (int) barRectangle.getHeight();
final int barWidth = (int) barRectangle.getWidth();
final int noOfElements = getNoOfElements();
setPresentable(elementsFitInBar(layout, barElementColors, noOfElements, barWidth, barHeight), calculator);
if (!isPresentable()) {
return;
}
if (HistogramLayout.STACKED.equals(layout)) {
setStackedRectangles(barRectangle, barElementColors, valRange, aggrMethod, calculator);
} else if (HistogramLayout.SIDE_BY_SIDE.equals(layout)) {
setSideBySideRectangles(barRectangle, barElementColors, valRange, aggrMethod, baseLine, calculator);
} else {
throw new IllegalArgumentException("Layout " + layout + " not supported");
}
return;
}
use of org.knime.base.node.viz.histogram.HistogramLayout in project knime-core by knime.
the class AbstractHistogramPlotter method setHistogramBinRectangle.
/**
* Calculates and sets the drawing rectangle of each bin.
* @param xCoordinates The <code>Coordinate</code> object which contains
* the start position of an bar on the x axis
* @param yCoordinates The <code>Coordinate</code> object which contains
* the start position of an bar on the y axis
*/
private static void setHistogramBinRectangle(final AbstractHistogramVizModel vizModel, final Coordinate xCoordinates, final Coordinate yCoordinates) {
final Dimension drawingSpace = vizModel.getDrawingSpace();
final int binWidth = vizModel.getBinWidth();
final AggregationMethod aggrMethod = vizModel.getAggregationMethod();
final List<Color> barElementColors = vizModel.getRowColors();
final Collection<ColorColumn> aggrColumns = vizModel.getAggrColumns();
final HistogramLayout layout = vizModel.getHistogramLayout();
final HistogramHiliteCalculator calculator = vizModel.getHiliteCalculator();
final double drawingWidth = drawingSpace.getWidth();
final double drawingHeight = drawingSpace.getHeight();
final int baseLine = (int) (drawingHeight - yCoordinates.calculateMappedValue(new DoubleCell(0), drawingHeight));
// this is the minimum size of a bar with an aggregation value > 0
final int minHeight = Math.max((int) HistogramDrawingPane.getBarStrokeWidth(), AbstractHistogramVizModel.MINIMUM_BAR_HEIGHT);
// final int binWidth = getBinWidth();
for (final BinDataModel bin : vizModel.getBins()) {
final DataCell captionCell = bin.getXAxisCaptionCell();
final double labelCoord = xCoordinates.calculateMappedValue(captionCell, drawingWidth);
if (labelCoord < 0) {
// this bin is not on the x axis (because it is empty and the
// empty bins shouldn't be displayed) so we simply set the
// rectangle to null and continue
bin.setBinRectangle(null, baseLine, barElementColors, aggrColumns, calculator);
continue;
}
// if the maximum value is negative use 0 to end at the base line
final double maxAggrVal = Math.max(bin.getMaxAggregationValue(aggrMethod, layout), 0);
// if the minimum value is positive use 0 to start at the base line
final double minAggrVal = Math.min(bin.getMinAggregationValue(aggrMethod, layout), 0);
// subtract half of the bar width from the start position to place
// the middle point of the bar on the mapped coordinate position
final int xCoord = (int) (labelCoord - (binWidth / 2.0));
final int upperY = (int) (drawingHeight - yCoordinates.calculateMappedValue(new DoubleCell(maxAggrVal), drawingHeight));
final int lowerY = (int) (drawingHeight - yCoordinates.calculateMappedValue(new DoubleCell(minAggrVal), drawingHeight));
final Rectangle binRect = calculateBorderRectangle(xCoord, lowerY, upperY, minHeight, binWidth, maxAggrVal, baseLine);
bin.setBinRectangle(binRect, baseLine, barElementColors, aggrColumns, calculator);
}
// end of for loop over the x axis coordinates
}
use of org.knime.base.node.viz.histogram.HistogramLayout in project knime-core by knime.
the class HistogramDrawingPane method paintContent.
// **********************************************
/*--------- the drawing methods ----------------*/
// **********************************************
/**
* {@inheritDoc}
*/
@Override
public void paintContent(final Graphics g) {
final Graphics2D g2 = (Graphics2D) g;
final Rectangle2D bounds = getBounds();
String msg = m_infoMsg;
final AbstractHistogramVizModel vizModel = m_vizModel;
if (vizModel == null || vizModel.getBins() == null) {
// if we have no bins and no info message display a no bars info
if (msg == null) {
msg = "No bins to display";
}
}
// check if we have to display an information message
if (msg != null) {
DrawingUtils.drawMessage(g2, INFO_MSG_FONT, msg, bounds);
return;
}
if (m_updatePropertiesPanel && m_properties != null) {
m_properties.updateHistogramSettings(vizModel);
m_updatePropertiesPanel = false;
}
// check if we have to draw the grid lines
if (vizModel.isShowGridLines() && m_gridLines != null) {
for (final int gridLine : m_gridLines) {
DrawingUtils.paintHorizontalLine(g2, 0, gridLine, (int) bounds.getWidth(), GRID_LINE_COLOR, GRID_LINE_STROKE);
}
}
// get all variables which are needed multiple times
final AggregationMethod aggrMethod = vizModel.getAggregationMethod();
// final Collection<ColorColumn> aggrColumns =
// vizModel.getAggrColumns();
final HistogramLayout layout = vizModel.getHistogramLayout();
// if the user has selected more then one aggregation column we have to
// draw the bar outline to how him which bar belongs to which aggregation
// column
final boolean drawBinOutline = vizModel.isShowBinOutline();
final boolean drawBarOutline = vizModel.isShowBarOutline();
// (aggrColumns != null
// && aggrColumns.size() > 1)
// || HistogramLayout.SIDE_BY_SIDE.equals(
// m_vizModel.getHistogramLayout());
final boolean showElementOutline = vizModel.isShowElementOutline();
final LabelDisplayPolicy labelDisplayPolicy = vizModel.getLabelDisplayPolicy();
final boolean showLabelVertical = vizModel.isShowLabelVertical();
final float barOutlineAlpha;
if (HistogramLayout.SIDE_BY_SIDE.equals(vizModel.getHistogramLayout())) {
barOutlineAlpha = BAR_SIDE_BY_SIDE_SURROUNDING_ALPHA;
} else {
barOutlineAlpha = BAR_STACKED_SURROUNDING_ALPHA;
}
// loop over all bins and paint them
for (final BinDataModel bin : vizModel.getBins()) {
if (drawBinOutline) {
DrawingUtils.drawRectangle(g2, bin.getSurroundingRectangle(), BIN_SURROUNDING_COLOR, BIN_SURROUNDING_STROKE);
}
if (!bin.isPresentable()) {
// the bars doen't fit in this bin so we have to
// fill the complete bin in black to show it to the user
DrawingUtils.drawBlock(g2, bin.getBinRectangle(), OVERLOADED_ELEMENT_FILLING, OVERLOADED_ELEMENT_ALPHA);
if (bin.isSelected()) {
DrawingUtils.drawRectangle(g2, bin.getBinRectangle(), ELEMENT_SELECTED_OUTLINE_COLOR, ELEMENT_SELECTED_OUTLINE_STROKE);
}
if (bin instanceof InteractiveBinDataModel) {
final InteractiveBinDataModel interactiveBin = (InteractiveBinDataModel) bin;
drawHiliteRect(g2, interactiveBin.getHiliteRectangle());
}
continue;
}
final Collection<BarDataModel> bars = bin.getBars();
for (final BarDataModel bar : bars) {
if (drawBarOutline) {
// draw the outline of the bar if we have multiple
// aggregation columns
DrawingUtils.drawBlock(g2, bar.getSurroundingRectangle(), bar.getColor(), barOutlineAlpha);
}
if (bar.isPresentable()) {
drawElements(g2, bar.getElements(), showElementOutline);
} else {
// the elements doen't fit in this bar so we have to
// fill the complete bar to show it to the user
final Rectangle2D barRectangle = bar.getShape();
DrawingUtils.drawBlock(g2, barRectangle, OVERLOADED_ELEMENT_FILLING, OVERLOADED_ELEMENT_ALPHA);
if (bar.isSelected()) {
DrawingUtils.drawRectangle(g2, barRectangle, ELEMENT_SELECTED_OUTLINE_COLOR, ELEMENT_SELECTED_OUTLINE_STROKE);
}
if (bar instanceof InteractiveBarDataModel) {
final InteractiveBarDataModel interactiveBar = (InteractiveBarDataModel) bar;
drawHiliteRect(g2, interactiveBar.getHiliteShape());
}
}
// draw the bar label at last to have them on top
drawLabels(g2, bar, aggrMethod, layout, bounds, labelDisplayPolicy, showLabelVertical);
}
// end of bar loop
}
// check if we have to draw the base line
if (m_baseLine != null) {
DrawingUtils.paintHorizontalLine(g2, 0, m_baseLine.intValue(), (int) bounds.getWidth(), BASE_LINE_COLOR, BASE_LINE_STROKE);
}
return;
}
Aggregations