Как отмечают другие ответы, использование списка в списке является наиболее естественным способом сделать это в Haskell.
Если вы изучаете Haskell и хотите работать над разработкой интуиций о типах классов, таких как Monad
, однако, это забавное упражнение, чтобы понять, почему это немного более короткое определение эквивалентно:
import Control.Monad (liftM2)
cartProd :: [a] -> [b] -> [(a, b)]
cartProd = liftM2 (,)
Вы, вероятно, никогда не захотели бы писать это в реальном коде, но основная идея - это то, что вы «В Haskell мы все время видим: мы используем liftM2
, чтобы поднять немонодическую функцию (,)
в монаду - в данном случае именно монаду списка.
Если это не сделать какой-либо смысл или не полезно, забудьте об этом - это просто еще один способ взглянуть на проблему.
Ни один из существующих ChartFactory
не использует XYSplineRenderer
, и я не был уверен в ваших существующих наборах данных. Я начал с этого примера и выбрал нормальное распределение, например , это , чтобы получить оригинальный пример, показанный здесь . Возможно, вам придется настроить precision
в соответствии с вашими данными. При необходимости вы можете изменить метки оси домена, используя любой из методов, предложенных в . Как я могу изменить tickLabel
на NumberAxis
…? .
Мой набор данных использует
blockquote>int String String
Чтение более близко, первый
String
- это ключ серии, который я обозначил"Frequency"
; второй представляется числовым диапазоном. Этот новый пример иллюстрирует использование более высокой точности иSymbolAxis
, который должен работать лучше для ваших дюжин или около того диапазонов.Обновленный пример:
import java.awt.Dimension; import java.awt.EventQueue; import javax.swing.JFrame; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.SymbolAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYSplineRenderer; import org.jfree.data.xy.XYDataset; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; /** * @see https://stackoverflow.com/a/55418498/230513 * @see https://stackoverflow.com/a/14790187/230513 * @see https://stackoverflow.com/a/40167139/230513 */ public class SplineTest { public static final String Title = "Spline Test"; public static void main(String[] args) { EventQueue.invokeLater(new SplineTest()::display); } private void display() { XYSeries series = new XYSeries("Frequency"); series.add(0, 1); series.add(1, 1); series.add(2, 3); series.add(3, 7); series.add(4, 11); series.add(5, 21); series.add(6, 28); series.add(7, 16); series.add(8, 22); series.add(9, 7); series.add(10, 1); series.add(11, 2); XYDataset dataset = new XYSeriesCollection(series); String[] labels = new String[series.getItemCount()]; labels[0] = "<46"; labels[1] = "46-55"; labels[2] = "56-65"; labels[3] = "66-75"; labels[4] = "76-85"; labels[5] = "86-95"; labels[6] = "96-105"; labels[7] = "106-115"; labels[8] = "116-125"; labels[9] = "126-135"; labels[10] = "136-145"; labels[11] = ">146"; NumberAxis domain = new SymbolAxis("X", labels); NumberAxis range = new NumberAxis("Y"); XYSplineRenderer r = new XYSplineRenderer(8); XYPlot xyplot = new XYPlot(dataset, domain, range, r); JFreeChart chart = new JFreeChart(xyplot); ChartPanel chartPanel = new ChartPanel(chart) { @Override public Dimension getPreferredSize() { return new Dimension(640, 480); } }; JFrame frame = new JFrame(Title); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(chartPanel); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }