Java: 如何可视化/绘制时间间隔

huangapple go评论83阅读模式
英文:

Java : How to visualize/plot time intervals

问题

我有一个具有以下结构的表格:

[时间间隔名称,开始时间,结束时间]

我想在一个带有时间轴的图表上可视化这些时间间隔,类似于这样的东西,但显然要漂亮得多。
有没有任何免费的Java库可以做到这一点?有关如何自己进行可视化的任何想法吗?

非常感谢大家的帮助 Java: 如何可视化/绘制时间间隔

英文:

I have a table with the following structure:

[interval_name, start_time, end_time]

I would like to visualize those time intervals over a plot with a time axis, Some thing like this but obviously much prettier.
Is there any free java library to do so? any ideas on how to visualize it by my own?

much appreciation to all Java: 如何可视化/绘制时间间隔

答案1

得分: 1

以下是你提供的代码的中文翻译部分:

我认为用Java Swing从头开始创建一个时间轴图会很有趣

这是我设计的图形界面你可能需要右键点击图像然后选择在新标签页中打开链接以清楚地看到细节

[![Timeline Plot][1]][1]

我首先创建了一个`Event`我使用`LocalDateTime`字段来保存事件的开始和结束时间

我在`Event`类的构造函数中添加了一个`Color`字段以便可以使用不同的颜色绘制图中的事件在上面的示例中我使用蓝色表示个人时间黑色表示工作时间

接下来我创建了一个`TimeLine`类来保存事件列表

然后我在主要的`TimeLinePlot`类的构造函数中创建了一个时间轴

最后我创建了一个`JFrame`和一个绘图的`JPanel`。我在绘图的`JPanel`上绘制了时间轴图

这段代码不是一个完整的解决方案这段代码旨在向提问者和其他人展示如何创建一个时间轴图

```java
// 这里是你提供的代码的Java翻译部分,包括类和方法的定义。
// 由于篇幅较长,我将其省略,仅提供中文翻译。

请注意,这只是代码的翻译部分,其他内容都被省略了。如果你有任何关于代码的问题,可以继续提问。
<details>
<summary>英文:</summary>
I thought it would be interesting to create a timeline plot from scratch using Java Swing.
Here&#39;s the GUI I came up with.  You may have to right-click on the image and choose &quot;Open link in new tab&quot; to see the details clearly.
[![Timeline Plot][1]][1]
The first thing I did was to create an `Event` class.  I used `LocalDateTime` fields to hold the event start and event end.
I added a `Color` field to the `Event` class constructor so that the events on the plot can be drawn in different colors. In the example above, I used blue for personal time and black for work time.
Next, I created a `TimeLine` class to hold a `List` of events.
Then I created a timeline in the constructor of the main `TimeLinePlot` class.
Finally, I created a `JFrame` and a drawing `JPanel`.  I drew the timeline plot on the drawing `JPanel`.
This code is not meant to be a complete solution.  This code is meant to show the OP and others how to create a timeline plot.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TimeLinePlot implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new TimeLinePlot());
}
private final int plotWidth;
private final int plotHeight;
private final int margin;
private int increment;
private final String[] xAxis;
private final TimeLine timeLine;
public TimeLinePlot() {
this.plotWidth = 1000;
this.plotHeight = 500;
this.margin = 50;
this.timeLine = generateTimeLine();
this.xAxis = createXAxis();
}
private TimeLine generateTimeLine() {
TimeLine timeLine = new TimeLine();
Event event = new Event(&quot;Breakfast&quot;, Color.BLUE,
&quot;5/29/2020 7:00AM&quot;, &quot;5/29/2020 8:00AM&quot;);
timeLine.addEvent(event);
event = new Event(&quot;Shower&quot;, Color.BLUE,
&quot;5/29/2020 8:00AM&quot;, &quot;5/29/2020 8:30AM&quot;);
timeLine.addEvent(event);
event = new Event(&quot;Stack Overflow&quot;, Color.BLACK,
&quot;5/29/2020 8:30AM&quot;, &quot;5/29/2020 11:45AM&quot;);
timeLine.addEvent(event);
event = new Event(&quot;Lunch&quot;, Color.BLUE,
&quot;5/29/2020 11:30AM&quot;, &quot;5/29/2020 12:30PM&quot;);
timeLine.addEvent(event);
event = new Event(&quot;Stack Overflow&quot;, Color.BLACK,
&quot;5/29/2020 12:00PM&quot;, &quot;5/29/2020 4:30PM&quot;);
timeLine.addEvent(event);
return timeLine;
}
private String[] createXAxis() {
LocalDateTime startDateTime =
timeLine.getEarliestStartDate();
LocalDateTime endDateTime =
timeLine.getLatestEndDate();
Duration duration = Duration.between(
startDateTime, endDateTime);
//		System.out.println(duration);
if (duration.toDays() &gt; 0L) {
// TODO Figure out a multi-day timeline
return new String[0];
} else {
long minutes = duration.toMinutes();
int hours = (int) Math.ceil(minutes / 60D);
//			System.out.println(hours);
increment = 1;
if (hours &gt; 12) {
increment = 2;
hours /= 2;
}
String[] axis = new String[hours + 1];
LocalDateTime dateTime = startDateTime;
for (int i = 0; i &lt;= hours; i += increment) {
axis[i] = createTimeLabel(dateTime);
dateTime = dateTime.plusHours(increment);
}
//			System.out.println(Arrays.asList(axis));
return axis;
}
}
private String createTimeLabel(LocalDateTime dateTime) {
return dateTime.format(
DateTimeFormatter.ofPattern(&quot;h:mm a&quot;));
}
@Override
public void run() {
JFrame frame = new JFrame(&quot;Time Line Plot&quot;);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TimeLinePanel timeLinePanel = new TimeLinePanel(
plotWidth, plotHeight, margin, timeLine,
increment, xAxis);
frame.add(timeLinePanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class TimeLinePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final int plotWidth;
private final int plotHeight;
private final int margin;
private final int tickLength;
private final int increment;
private final String[] xAxis;
private final TimeLine timeLine;
public TimeLinePanel(int plotWidth, int plotHeight,
int margin, TimeLine timeLine, int increment,
String[] xAxis) {
this.plotWidth = plotWidth;
this.plotHeight = plotHeight;
this.margin = margin;
this.tickLength = 20;
this.increment = increment;
this.timeLine = timeLine;
this.xAxis = xAxis;
this.setPreferredSize(new Dimension(
plotWidth, plotHeight));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setFont(getFont().deriveFont(14f)
.deriveFont(Font.BOLD));
createXAxis(g2d);
createTimeLines(g2d);
}
private void createXAxis(Graphics2D g2d) {
int height = plotHeight - margin;
int width = plotWidth - margin * 4;
int pixelGap = width / (xAxis.length - 1);
int x = margin + margin;
int x1 = x;
int y = height - tickLength - 10;
g2d.setColor(Color.BLACK);
g2d.setStroke(new BasicStroke(3f));
FontMetrics metrics = g2d.getFontMetrics(getFont());
for (int i = 0; i &lt; xAxis.length; i++) {
g2d.drawLine(x, y, x, y + tickLength);
int a = x - metrics.stringWidth(xAxis[i]) / 2;
int b = y + tickLength + metrics.getHeight() / 2 +
metrics.getAscent();
g2d.drawString(xAxis[i], a, b);
x += pixelGap;
}
g2d.drawLine(x1, y, x - pixelGap, y);
}
private void createTimeLines(Graphics2D g2d) {
LocalDateTime earliestStartTime =
timeLine.getEarliestStartDate();
List&lt;Event&gt; events = timeLine.getEvents();
int height = plotHeight - margin;
int width = plotWidth - margin * 4;
int pixelGapH = height / events.size();
int pixelGapW = width / (xAxis.length - 1);
int x = margin + margin;
int y = height - tickLength - 30;
g2d.setStroke(new BasicStroke(9f));
FontMetrics metrics = g2d.getFontMetrics(getFont());
for (int i = events.size() - 1; i &gt;= 0; i--) {
Event event = events.get(i);
LocalDateTime startTime = event.getStartTime();
LocalDateTime endTime = event.getEndTime();
Duration duration1 = Duration.between(
earliestStartTime, startTime);
Duration duration2 = Duration.between(
earliestStartTime, endTime);
long minutes1 = duration1.toMinutes();
long minutes2 = duration2.toMinutes();
String text = event.getName();
int a1 = x + (int) (Math.round((double) minutes1 *
pixelGapW * increment / 60D));
int a2 = x + (int) (Math.round((double) minutes2 *
pixelGapW * increment / 60D));
int a = a1 + ((a2 - a1) / 2) -
(metrics.stringWidth(text) / 2) - 4;
int b = y - 8;
g2d.setColor(event.getColor());
g2d.drawLine(a1, y, a2, y);
g2d.drawString(text, a, b);
y -= pixelGapH;
}
}
}
public class TimeLine {
private List&lt;Event&gt; events;
public TimeLine() {
this.events = new ArrayList&lt;&gt;();
}
public void addEvent(Event event) {
this.events.add(event);
}
public List&lt;Event&gt; getEvents() {
return events;
}
public LocalDateTime getEarliestStartDate() {
LocalDateTime minimumStartDateTime = null;
for (Event event : events) {
if (minimumStartDateTime == null ||
event.getStartTime().compareTo(
minimumStartDateTime) &lt; 0) {
minimumStartDateTime = event.getStartTime();
}
}
return minimumStartDateTime;
}
public LocalDateTime getLatestEndDate() {
LocalDateTime maximumEndDateTime = null;
for (Event event : events) {
if (maximumEndDateTime == null ||
event.getEndTime().compareTo(
maximumEndDateTime) &gt; 0) {
maximumEndDateTime = event.getEndTime();
}
}
return maximumEndDateTime;
}
}
public class Event {
private final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern(&quot;M/d/yyyy h:mma&quot;);
private Color color;
private final String name;
private final LocalDateTime startTime;
private final LocalDateTime endTime;
public Event(String name, Color color, String startTimeString,
String endTimeString) {
this.name = name;
this.color = color;
this.startTime = LocalDateTime.parse(startTimeString,
formatter);
this.endTime = LocalDateTime.parse(endTimeString,
formatter);
}
public String getName() {
return name;
}
public Color getColor() {
return color;
}
public LocalDateTime getStartTime() {
return startTime;
}
public LocalDateTime getEndTime() {
return endTime;
}
}
}
[1]: https://i.stack.imgur.com/eogZ2.png
</details>

huangapple
  • 本文由 发表于 2020年5月29日 22:49:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/62088677.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定