Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
tech.tablesaw.plotting.StandardColors Maven / Gradle / Ivy
/*
* 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 tech.tablesaw.plotting;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
import com.opencsv.CSVReader;
import javax.annotation.Nullable;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
*
*/
public class StandardColors {
static final ImmutableMultimap colorMap = ImmutableMultimap.copyOf(loadColors());
static ImmutableList neutralColors = ImmutableList.copyOf(loadNeutrals());
/**
* Loads the standard colors from a file
*
* @return
*/
static Multimap loadColors() {
Multimap standards = LinkedListMultimap.create();
InputStream resourceAsStream = StandardColors.class.getResourceAsStream("/colors.txt");
String[] nextLine;
try (CSVReader reader = new CSVReader(new InputStreamReader(resourceAsStream))) {
// Add the rows
while ((nextLine = reader.readNext()) != null) {
for (String colorData : nextLine) {
String[] colorSplit = colorData.trim().split(" ");
String vHue = colorSplit[0];
String valueChroma = colorSplit[1];
String[] valueAndChroma = valueChroma.split("/");
int vValue = Integer.parseInt(valueAndChroma[0]);
int vChroma = Integer.parseInt(valueAndChroma[1]);
String vHex = colorSplit[2];
StandardColor color = new StandardColor(vHue, vChroma, vValue, vHex);
if (!color.hue().equals(Hue.Neutral)) {
standards.put(color.hue(), color);
}
}
}
} catch (IOException e) {
throw new UncheckedIOException("Unable to read predefined colors file", e);
}
return standards;
}
static List loadNeutrals() {
ArrayList neutrals = new ArrayList<>();
InputStream resourceAsStream = StandardColors.class.getResourceAsStream("/colors.txt");
String[] nextLine;
try (CSVReader reader = new CSVReader(new InputStreamReader(resourceAsStream))) {
// Add the rows
while ((nextLine = reader.readNext()) != null) {
for (String colorData : nextLine) {
String[] colorSplit = colorData.trim().split(" ");
String vHue = colorSplit[0];
String valueChroma = colorSplit[1];
String[] valueAndChroma = valueChroma.split("/");
int vValue = Integer.parseInt(valueAndChroma[0]);
int vChroma = Integer.parseInt(valueAndChroma[1]);
String vHex = colorSplit[2];
StandardColor color = new StandardColor(vHue, vChroma, vValue, vHex);
if (color.hue().equals(Hue.Neutral)) {
neutrals.add(color);
}
}
}
} catch (IOException ex) {
throw new IllegalStateException("Unable to read predefined colors file", ex);
}
return neutrals;
}
static ImmutableList getNeutralColors() {
return neutralColors;
}
static Set getHues() {
return colorMap.keySet();
}
static ImmutableCollection getColors(Hue hue) {
return colorMap.get(hue);
}
public static List getFilteredColors(Hue hue, Range chromaRange, Range
valueRange) {
List filtered = new ArrayList<>();
ImmutableCollection colors = colorMap.get(hue);
for (StandardColor color : colors) {
if (chromaRange.contains(color.chroma()) && valueRange.contains(color.value())) {
filtered.add(color);
}
}
return filtered;
}
static Color[] allGreys() {
List colors = new ArrayList<>(11);
colors.add(Color.WHITE);
for (StandardColor color : neutralColors) {
colors.add(color.asColor());
}
colors.add(Color.BLACK);
return colors.toArray(new Color[11]);
}
static Color[] ggPlotGreys() {
List colors = new ArrayList<>(9);
for (StandardColor color : neutralColors.subList(1, neutralColors.size())) {
colors.add(color.asColor());
}
colors.add(Color.BLACK);
return colors.toArray(new Color[9]);
}
static Color[] ggPlotGreys(int size) {
size = Math.min(size, 9);
List colors = new ArrayList<>(size);
int start = (neutralColors.size() - size) + 1;
for (StandardColor color : neutralColors.subList(start, neutralColors.size())) {
colors.add(color.asColor());
}
colors.add(Color.BLACK);
return colors.toArray(new Color[size]);
}
static Color[] ggPlotGreys6() {
int size = 6;
List colors = new ArrayList<>(size);
colors.add(Color.WHITE);
colors.add(neutralColors.get(2).asColor());
colors.add(neutralColors.get(4).asColor());
colors.add(neutralColors.get(6).asColor());
colors.add(neutralColors.get(8).asColor());
colors.add(Color.BLACK);
return colors.toArray(new Color[size]);
}
/**
* Returns n hues, chosen to maximize the visual distance between them. We exclude grays from the list
*/
static List randomHues(int n) {
List resultList = new ArrayList<>(n);
int huesAvailable = Hue.values().length - 1; // we're going to take out the "neutral hue" aka gray
int maxDistance = huesAvailable / n;
Random random = new Random();
int starting = random.nextInt(huesAvailable);
List hues = new ArrayList<>(huesAvailable);
for (int i = starting; i < huesAvailable; i++) {
if (Hue.values()[i] != Hue.Neutral) {
hues.add(Hue.values()[i]);
}
}
for (int i = 0; i < starting; i++) {
if (Hue.values()[i] != Hue.Neutral) {
hues.add(Hue.values()[i]);
}
}
for (int j = 0; j < huesAvailable && resultList.size() < n; j = j + maxDistance) {
resultList.add(hues.get(j));
}
return resultList;
}
public static List randomColors(int n) {
Random random = new Random();
List hues = randomHues(n);
List colors = new ArrayList<>(n);
Range chromaRange = Range.closed(4, 12);
Range valueRange = Range.closed(4, 8);
for (Hue hue : hues) {
List standardColors = getFilteredColors(hue, chromaRange, valueRange);
StandardColor randomColor = standardColors.get(random.nextInt(standardColors.size()));
colors.add(randomColor.asColor());
}
return colors;
}
public static Color[] standardColorArray() {
List standardColors = standardColors();
return standardColors().toArray(new Color[standardColors.size()]);
}
public static List standardColors() {
List colors = new ArrayList<>();
colors.add(color(Hue.Red_5, 14, 4));
colors.add(color(Hue.Yellow_2_5, 12, 8));
colors.add(color(Hue.Purple_7_5, 10, 4));
colors.add(color(Hue.YellowRed_5, 12, 7));
colors.add(color(Hue.PurpleBlue_2_5, 6, 8));
colors.add(color(Hue.Yellow_5, 4, 7));
colors.add(color(Hue.GreenYellow_5, 2, 5));
colors.add(color(Hue.Green_2_5, 10, 6));
colors.add(color(Hue.RedPurple_5, 10, 7));
colors.add(color(Hue.PurpleBlue_2_5, 8, 4));
colors.add(color(Hue.Red_7_5, 8, 7));
colors.add(color(Hue.PurpleBlue_2_5, 10, 4));
colors.add(color(Hue.YellowRed_7_5, 12, 7));
colors.add(color(Hue.RedPurple_7_5, 12, 4));
colors.add(color(Hue.Yellow_10, 10, 8));
colors.add(color(Hue.YellowRed_2_5, 8, 3));
colors.add(color(Hue.GreenYellow_5, 10, 7));
colors.add(color(Hue.Red_10, 14, 5));
colors.add(color(Hue.GreenYellow_5, 4, 2));
colors.add(allGreys()[2]);
return colors;
}
@Nullable
static Color color(Hue hue, int chroma, int value) {
Collection options = colorMap.get(hue);
for (StandardColor standardColor : options) {
if (standardColor.chroma() == chroma &&
standardColor.value() == value) {
return standardColor.asColor();
}
}
return null;
}
}