com.swirlds.common.formatting.TextHistogram Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of swirlds-common Show documentation
Show all versions of swirlds-common Show documentation
Swirlds is a software platform designed to build fully-distributed applications that harness the power of the cloud without servers. Now you can develop applications with fairness in decision making, speed, trust and reliability, at a fraction of the cost of traditional server-based platforms.
/*
* Copyright (C) 2023-2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.swirlds.common.formatting;
import static com.swirlds.common.formatting.StringFormattingUtils.commaSeparatedNumber;
import static com.swirlds.common.formatting.TextEffect.BRIGHT_RED;
import static com.swirlds.common.formatting.TextEffect.BRIGHT_YELLOW;
import static com.swirlds.common.formatting.TextEffect.GRAY;
import com.swirlds.common.units.DataUnit;
import com.swirlds.common.units.Unit;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Function;
/**
* This class is capable of drawing histograms using text.
*
* @param
* the type of the data being plotted
*/
public class TextHistogram {
private static final int DEFAULT_HISTOGRAM_WIDTH = 32;
private static final String HISTOGRAM_CHARACTER = "*";
private boolean colorEnabled = true;
private boolean showValues = true;
private int width = DEFAULT_HISTOGRAM_WIDTH;
private Function timestampExtractor;
private final Function valueExtractor;
private Unit> valueUnit;
private final List data;
/**
* Create a new text histogram.
*
* @param data
* the data to plot
*/
public TextHistogram(@NonNull final List data, @NonNull final Function valueExtractor) {
Objects.requireNonNull(data, "data must not be null");
Objects.requireNonNull(valueExtractor, "valueExtractor must not be null");
this.data = data;
this.valueExtractor = valueExtractor;
}
/**
* Set if color should be enabled. Has no effect if color is disabled globally.
*
* @param colorEnabled
* if color should be enabled
* @return this object
*/
public TextHistogram setColorEnabled(final boolean colorEnabled) {
this.colorEnabled = colorEnabled;
return this;
}
/**
* Set if the values should be shown.
*
* @param showValues
* if the values should be shown
* @return this object
*/
public TextHistogram setShowValues(final boolean showValues) {
this.showValues = showValues;
return this;
}
/**
* Set the unit for the value. Ignored if values are not shown.
*
* @param valueUnit
* the unit for the value
* @return this object
*/
public TextHistogram setValueUnit(final Unit> valueUnit) {
this.valueUnit = valueUnit;
return this;
}
/**
* Set the maximum width of the histogram bars, in characters.
*
* @param width
* the width of the histogram
* @return this object
*/
public TextHistogram setWidth(final int width) {
this.width = width;
return this;
}
/**
* Set the function to use to extract the timestamp from the data. If unset then no timestamp
* is displayed.
*
* @param timestampExtractor
* the function to use to extract the timestamp
* @return this object
*/
public TextHistogram setTimestampExtractor(final Function timestampExtractor) {
this.timestampExtractor = timestampExtractor;
return this;
}
/**
* Render the histogram to a string.
*
* @return the histogram in string form
*/
public String render() {
final StringBuilder sb = new StringBuilder();
render(sb);
return sb.toString();
}
/**
* Render the histogram to a string builder.
*
* @param sb
* the string builder to write to
*/
public void render(final StringBuilder sb) {
long max = 0;
for (final T datum : data) {
max = Math.max(max, valueExtractor.apply(datum));
}
final TextTable table = new TextTable()
.setBordersEnabled(false)
.setColumnHorizontalAlignment(1, HorizontalAlignment.ALIGNED_RIGHT);
final UnitFormatter valueFormatter;
if (valueUnit != null) {
valueFormatter =
new UnitFormatter(DataUnit.UNIT_BYTES).setAbbreviate(true).setDecimalPlaces(1);
} else {
valueFormatter = null;
}
for (final T datum : data) {
final List row = new ArrayList<>();
if (timestampExtractor != null) {
final String timestamp = timestampExtractor.apply(datum).toString();
if (colorEnabled) {
row.add(GRAY.apply(timestamp));
} else {
row.add(timestamp);
}
}
if (showValues) {
final String value;
if (valueFormatter != null) {
valueFormatter.setQuantity(valueExtractor.apply(datum));
value = valueFormatter.render();
} else {
value = commaSeparatedNumber(valueExtractor.apply(datum));
}
if (colorEnabled) {
row.add(BRIGHT_RED.apply(value));
} else {
row.add(value);
}
}
final long value = valueExtractor.apply(datum);
final int barLength = max == 0 ? 0 : (int) (((double) value) / max * width);
final String bar = HISTOGRAM_CHARACTER.repeat(barLength);
if (colorEnabled) {
row.add(BRIGHT_YELLOW.apply(bar));
} else {
row.add(bar);
}
table.addRow(row.toArray());
}
table.render(sb);
}
}