Beyond code that gets it done: code readability. Any advice?

I think it cleaned up nicely already. Must say: has been very instructive exercise.

defmodule SurveyWeb.Structs.Bins do
  defstruct [:size, :start, :count]

  def index_of(value, bins) when value >= bins.start + bins.size * bins.count do
    bins.count - 1
  end

  def index_of(value, bins) do
    (value - bins.start)/bins.size
    |> trunc()
  end

  def index_to_label(index, bins) when index == bins.count - 1 do
    lower_limit = bins.start + bins.size * index
    "#{lower_limit}+"
  end

  def index_to_label(index, bins) do
    lower_limit = bins.start + bins.size * index
    upper_limit = lower_limit + bins.size - 1
    "#{lower_limit}-#{upper_limit}"
  end
end

defmodule SurveyWeb.Components.Histogram do
  use SurveyWeb, :live_component

  alias SurveyWeb.Components.Helpers
  alias SurveyWeb.Structs.Bins

  defp histogram_frequencies(responses, target_variable, bin_size, start_value, bin_count) do
    bins = %Bins{size: bin_size, start: start_value, count: bin_count}

    responses
    |> Enum.frequencies_by(fn %{^target_variable => value } -> Bins.index_of(value, bins) end)
    |> add_empty_bins(bins)
    |> List.first() # Temp. Getting rid of this line.
    |> Enum.map(fn {index, count} -> {Bins.index_to_label(index, bins), count} end)
  end

  defp add_empty_bins(frequencies, bins) do
    missing_indexes = Enum.to_list(0..bins.count - 1) -- Map.keys(frequencies)
    for index <- missing_indexes do
      Map.put(frequencies, index, 0)
    end
  end

  def render(assigns) do
    ~H"""
    <span class={"#{@class} histogram"}>
      <%= for {category, count} <-
        histogram_frequencies(@responses, @target_variable, @bin_size, @start_value, @bin_count) do %>
        <div class="bar" style={"height: #{count/Enum.count(@responses)*100}%"}>
          <div class="count">
            <%= count %>
            <%= "(#{Helpers.decimal_responses_percentage(@responses, count, 1)})" %>
          </div>
          <div class="category">
            <%= category %>
          </div>
        </div>
      <% end %>
    </span>
    """
  end
end