- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个具有以下结构的表:
[间隔名称、开始时间、结束时间]
我想在带有时间轴的图上可视化这些时间间隔,Some thing like this但显然漂亮得多。有没有免费的java库可以做到这一点?关于如何自己可视化它有什么想法吗?
非常感谢大家:)
最佳答案
我认为使用 Java Swing 从头开始创建时间线图会很有趣。
这是我想出的 GUI。您可能需要右键单击图像并选择“在新选项卡中打开链接”才能清楚地查看详细信息。
我做的第一件事是创建一个 Event
类。我使用 LocalDateTime
字段来保存事件开始和事件结束。
我在 Event
类构造函数中添加了一个 Color
字段,以便可以用不同的颜色绘制绘图上的事件。在上面的示例中,我使用蓝色表示个人时间,使用黑色表示工作时间。
接下来,我创建了一个 TimeLine
类来保存事件的 List
。
然后我在主 TimeLinePlot
类的构造函数中创建了一个时间线。
最后,我创建了一个 JFrame
和一个绘图 JPanel
。我在绘图 JPanel
上绘制了时间线图。
此代码并不意味着是一个完整的解决方案。此代码旨在向 OP 和其他人展示如何创建时间线图。
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("Breakfast", Color.BLUE,
"5/29/2020 7:00AM", "5/29/2020 8:00AM");
timeLine.addEvent(event);
event = new Event("Shower", Color.BLUE,
"5/29/2020 8:00AM", "5/29/2020 8:30AM");
timeLine.addEvent(event);
event = new Event("Stack Overflow", Color.BLACK,
"5/29/2020 8:30AM", "5/29/2020 11:45AM");
timeLine.addEvent(event);
event = new Event("Lunch", Color.BLUE,
"5/29/2020 11:30AM", "5/29/2020 12:30PM");
timeLine.addEvent(event);
event = new Event("Stack Overflow", Color.BLACK,
"5/29/2020 12:00PM", "5/29/2020 4:30PM");
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() > 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 > 12) {
increment = 2;
hours /= 2;
}
String[] axis = new String[hours + 1];
LocalDateTime dateTime = startDateTime;
for (int i = 0; i <= 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("h:mm a"));
}
@Override
public void run() {
JFrame frame = new JFrame("Time Line Plot");
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 < 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<Event> 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 >= 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<Event> events;
public TimeLine() {
this.events = new ArrayList<>();
}
public void addEvent(Event event) {
this.events.add(event);
}
public List<Event> getEvents() {
return events;
}
public LocalDateTime getEarliestStartDate() {
LocalDateTime minimumStartDateTime = null;
for (Event event : events) {
if (minimumStartDateTime == null ||
event.getStartTime().compareTo(
minimumStartDateTime) < 0) {
minimumStartDateTime = event.getStartTime();
}
}
return minimumStartDateTime;
}
public LocalDateTime getLatestEndDate() {
LocalDateTime maximumEndDateTime = null;
for (Event event : events) {
if (maximumEndDateTime == null ||
event.getEndTime().compareTo(
maximumEndDateTime) > 0) {
maximumEndDateTime = event.getEndTime();
}
}
return maximumEndDateTime;
}
}
public class Event {
private final DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("M/d/yyyy h:mma");
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;
}
}
}
关于Java : How to visualize/plot time intervals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62088677/
我想根据我使用的 visual studio 版本编译不同的东西,比如 #if VISUAL_STUDIO_VERSION > 2015 eventH?.Invoke(this, EventArgs.
在 Visual Studio 2010 中调试并将鼠标悬停在变量名称上时,我可以选择使用 3 种不同的内置可视化工具:文本、XML 和 HTML。 这是我所指的示例: 由于我越来越多地使用基于 JS
我将可视化编程语言理解为允许程序员在屏幕上操作图形(而不是文本)对象以构建功能的语言。 我在 C#、VB 等中看到的最接近的东西是 RAD 控件,但这只是组成 UI 和最简单的功能——甚至与语言本身无
我目前正在使用 Visual Studio 2015 来编程 ASP.NET Core 应用程序。我对安装 Visual Studio 2017 有以下疑问: 什么被认为是最佳实践和/或最干净的方法?
尝试从扩展和更新获取 Visual Studio 扩展时,出现以下错误:- 向 visualstudiogallery.msdn.microsoft.com/Services/VStudio/Exte
我已经开发了Windows服务,并且该服务正在我的帐户下在本地计算机上运行。当我尝试通过在Visual Studio 2008中将其作为一个过程附加该服务来调试该服务时,我得到“无法附加到该过程。 V
作为标准安装的一部分,Visual Studio Code 带有一个名为“Monokai Dimmed”的颜色主题。 有没有办法将它移植到 Visual Studio 2015?我检查了社区主题( h
Visual Studio Community Edition是否可以使用Visual Studio Online帐户上的存储库? 我一直为包含在Online帐户中的Visual Studio Onl
我正在使用文本可视化工具在 Visual Studio 中调试字符串变量。然而,似乎字符串中间的大部分不见了。这背后的原因是什么? 最佳答案 Visual Studio 中的 Text Visuali
我正在开始一个涉及使用多个 SDK 的新项目,包括: 英特尔凌动开发者 SDK 文本转语音 SDK(建议?) 某种网络摄像头和增强现实支持(建议?) 我目前有 2008,但我也可以安装 2010。是否
我想知道,如果我发送一个解决方案文件夹(它是用 visual studio C# 编写的),您可以在 visual studio for mac 中打开解决方案吗? 在visual studio 20
有没有办法在 Visual Studio Code 和 Visual Studio 中设置相同的快捷方式(而不必每次都手动更改它们)? 例如,我在 Visual Studio Code 中经常使用 A
我无法启用 实时可视化树 在 Visual Studio 2017 用于 UWP 应用程序 (C#)。这个工具在 VS2015 上工作,但在 VS2017 中从来没有为我工作过。它对我的 WPF 项目
我刚开始了解 Visual Studio Code。我想知道,我可以将 Visual Studio 替换为所有 .NET 开发相关的工作吗? 我可以节省 Visual Studio 许可的成本吗? V
我安装了具有有效许可证(Visual Studio 订阅)的 Visual Studio 2019 企业版(VS 2019 16.1.4),它运行良好。 突然之间,当我尝试打开项目或项目中的任何文件时
Visual Studio 2015 Pro 提供以下 错误 : error BC36716: Visual Basic 9.0 does not support implicit line cont
我正在我的 PC 中使用 .net Framework 2.0 和 Visual C#(Microsoft Visual Studio 2008)开发 Windows 应用程序。 完成我的项目后,我必
有什么方法可以在启动 VS 时禁用 VA X 并仅在需要时将其重新打开?因为它会导致一些滞后。我似乎在 VS 的选项或 VA 的选项中都找不到该选项。 最佳答案 持shift在 Visual Stud
我可以将 Visual Studio 命令提示符 与免费的 Visual C# Express 一起使用吗? Visual Studio 命令提示符 被引用 here : Run 'Visual St
这很容易成为 Visual Studio 历史上最烦人的“功能”之一,我不明白它为什么存在 -- 曾经 . 为什么 CodePlex 项目需要关心我使用的是什么版本的 Visual Studio? 在
我是一名优秀的程序员,十分优秀!