面试题答案
一键面试使用Gosu实现实时图表
-
安装依赖: 确保安装了
gosu
库,可以通过gem install gosu
进行安装。 -
Ruby代码实现:
require 'gosu'
class RealTimeChart < Gosu::Window
def initialize
super(800, 600, false)
self.caption = 'Real - Time Chart'
@data = []
@font = Gosu::Font.new(self, Gosu::default_font_name, 20)
@last_update_time = 0
end
def update
new_data = load_data
@data.concat(new_data) if new_data.any?
@data = @data[-100..-1] if @data.length > 100
end
def draw
draw_background
draw_axis
draw_chart
end
private
def load_data
new_data = []
if File.exist?('data.txt')
File.foreach('data.txt') do |line|
new_data << line.chomp.to_f
end
File.write('data.txt', '')
end
new_data
end
def draw_background
Gosu.draw_rect(0, 0, width, height, Gosu::Color::WHITE)
end
def draw_axis
Gosu.draw_line(50, height - 50, 50, 50, Gosu::Color::BLACK)
Gosu.draw_line(50, height - 50, width - 50, height - 50, Gosu::Color::BLACK)
@font.draw('X', width - 40, height - 40, 1, 1, 1, Gosu::Color::BLACK)
@font.draw('Y', 40, 40, 1, 1, 1, Gosu::Color::BLACK)
end
def draw_chart
return if @data.empty?
max_value = @data.max
min_value = @data.min
data_points = @data.map.with_index do |value, index|
x = 50 + (index * (width - 100) / (@data.length - 1))
y = height - 50 - ((value - min_value) * (height - 100) / (max_value - min_value))
[x, y]
end
(0...data_points.length - 1).each do |i|
Gosu.draw_line(data_points[i][0], data_points[i][1], data_points[i + 1][0], data_points[i + 1][1], Gosu::Color::BLUE)
end
end
end
window = RealTimeChart.new
window.show
使用Chartkick实现实时图表
-
安装依赖: 确保安装了
chartkick
和sinatra
库,可以通过gem install chartkick sinatra
进行安装。 -
Ruby代码实现:
require'sinatra'
require 'chartkick'
require 'json'
enable :sessions
get '/' do
erb :index
end
post '/update' do
new_data = []
if File.exist?('data.txt')
File.foreach('data.txt') do |line|
new_data << line.chomp.to_f
end
File.write('data.txt', '')
end
session[:data] ||= []
session[:data].concat(new_data)
session[:data] = session[:data][-100..-1] if session[:data].length > 100
content_type :json
{ data: session[:data] }.to_json
end
- HTML和JavaScript实现(
views/index.erb
):
<!DOCTYPE html>
<html>
<head>
<title>Real - Time Chart</title>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Index');
data.addColumn('number', 'Value');
var options = {
title: 'Real - Time Chart',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
function updateChart() {
$.post('/update', function (result) {
data.removeRows(0, data.getNumberOfRows());
result.data.forEach(function (value, index) {
data.addRow([index, value]);
});
chart.draw(data, options);
});
}
setInterval(updateChart, 1000);
updateChart();
}
</script>
</head>
<body>
<div id="chart_div" style="width: 800px; height: 600px;"></div>
</body>
</html>
上述代码中,Gosu实现通过直接绘制图形来展示实时图表;Chartkick结合Sinatra实现了一个Web应用,通过AJAX请求更新图表数据。在实际运行时,确保有一个不断写入数字到data.txt
的进程。