diff --git a/lib/kino/explorer.ex b/lib/kino/explorer.ex index d7a35c1..85eaddb 100644 --- a/lib/kino/explorer.ex +++ b/lib/kino/explorer.ex @@ -65,18 +65,18 @@ defmodule Kino.Explorer do end @impl true - def export_data(%{df: df}, "CSV") do - data = df |> DataFrame.collect() |> DataFrame.dump_csv!() + def export_data(rows_spec, %{df: df}, "CSV") do + data = df |> df_to_export(rows_spec) |> DataFrame.dump_csv!() {:ok, %{data: data, extension: ".csv", type: "text/csv"}} end - def export_data(%{df: df}, "NDJSON") do - data = df |> DataFrame.collect() |> DataFrame.dump_ndjson!() + def export_data(rows_spec, %{df: df}, "NDJSON") do + data = df |> df_to_export(rows_spec) |> DataFrame.dump_ndjson!() {:ok, %{data: data, extension: ".ndjson", type: "application/x-ndjson"}} end - def export_data(%{df: df}, "Parquet") do - data = df |> DataFrame.collect() |> DataFrame.dump_parquet!() + def export_data(rows_spec, %{df: df}, "Parquet") do + data = df |> df_to_export(rows_spec) |> DataFrame.dump_parquet!() {:ok, %{data: data, extension: ".parquet", type: "application/x-parquet"}} end @@ -215,4 +215,8 @@ defmodule Kino.Explorer do defp build_top(top) when is_list(top) or is_map(top), do: inspect(top) defp build_top(top), do: to_string(top) + + defp df_to_export(df, rows_spec) do + df |> order_by(rows_spec[:order]) |> DataFrame.collect() + end end diff --git a/mix.exs b/mix.exs index 33222d4..00e94fc 100644 --- a/mix.exs +++ b/mix.exs @@ -27,7 +27,7 @@ defmodule KinoExplorer.MixProject do defp deps do [ - {:kino, "~> 0.12.3"}, + {:kino, github: "/livebook-dev/kino"}, {:explorer, "~> 0.8.1"}, {:ex_doc, "~> 0.31.0", only: :dev, runtime: false} ] diff --git a/mix.lock b/mix.lock index 39042a0..e70df2f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,5 +1,16 @@ %{ + "aws_signature": {:hex, :aws_signature, "0.3.2", "adf33bc4af00b2089b7708bf20e3246f09c639a905a619b3689f0a0a22c3ef8f", [:rebar3], [], "hexpm", "b0daf61feb4250a8ab0adea60db3e336af732ff71dd3fb22e45ae3dcbd071e44"}, + "castore": {:hex, :castore, "1.0.7", "b651241514e5f6956028147fe6637f7ac13802537e895a724f90bf3e36ddd1dd", [:mix], [], "hexpm", "da7785a4b0d2a021cd1292a60875a784b6caef71e76bf4917bdee1f390455cf5"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"}, "ex_doc": {:hex, :ex_doc, "0.31.0", "06eb1dfd787445d9cab9a45088405593dd3bb7fe99e097eaa71f37ba80c7a676", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "5350cafa6b7f77bdd107aa2199fe277acf29d739aba5aee7e865fc680c62a110"}, "explorer": {:hex, :explorer, "0.8.1", "0b7300030407a1d9c90096205395f112daa078148f9fc0b5616df30469b4e080", [:mix], [{:adbc, "~> 0.1", [hex: :adbc, repo: "hexpm", optional: true]}, {:aws_signature, "~> 0.3", [hex: :aws_signature, repo: "hexpm", optional: false]}, {:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:fss, "~> 0.1", [hex: :fss, repo: "hexpm", optional: false]}, {:nx, "~> 0.4", [hex: :nx, repo: "hexpm", optional: true]}, {:rustler, "~> 0.31.0", [hex: :rustler, repo: "hexpm", optional: true]}, {:rustler_precompiled, "~> 0.7", [hex: :rustler_precompiled, repo: "hexpm", optional: false]}, {:table, "~> 0.1.2", [hex: :table, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1 or ~> 4.0.0", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "4982756e2d1a1ee52a4acc913800a522b7b14ccb43801ed05d839e531724b798"}, - "kino": {:hex, :kino, "0.12.3", "a5f48a243c60a7ac18ba23869f697b1c775fc7794e8cd55dd248ba33c6fe9445", [:mix], [{:fss, "~> 0.1.0", [hex: :fss, repo: "hexpm", optional: false]}, {:nx, "~> 0.1", [hex: :nx, repo: "hexpm", optional: true]}, {:table, "~> 0.1.2", [hex: :table, repo: "hexpm", optional: false]}], "hexpm", "a6dfa3d54ba0edec9ca6e5940154916b381901001f171c85a2d8c67869dbc2d8"}, + "fss": {:hex, :fss, "0.1.1", "9db2344dbbb5d555ce442ac7c2f82dd975b605b50d169314a20f08ed21e08642", [:mix], [], "hexpm", "78ad5955c7919c3764065b21144913df7515d52e228c09427a004afe9c1a16b0"}, + "kino": {:git, "https://github.com//livebook-dev/kino.git", "b3f67b036ce76e81794e435259f337b364920efb", []}, + "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "rustler_precompiled": {:hex, :rustler_precompiled, "0.7.1", "ecadf02cc59a0eccbaed6c1937303a5827fbcf60010c541595e6d3747d3d0f9f", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:rustler, "~> 0.23", [hex: :rustler, repo: "hexpm", optional: true]}], "hexpm", "b9e4657b99a1483ea31502e1d58c464bedebe9028808eda45c3a429af4550c66"}, + "table": {:hex, :table, "0.1.2", "87ad1125f5b70c5dea0307aa633194083eb5182ec537efc94e96af08937e14a8", [:mix], [], "hexpm", "7e99bc7efef806315c7e65640724bf165c3061cdc5d854060f74468367065029"}, + "table_rex": {:hex, :table_rex, "4.0.0", "3c613a68ebdc6d4d1e731bc973c233500974ec3993c99fcdabb210407b90959b", [:mix], [], "hexpm", "c35c4d5612ca49ebb0344ea10387da4d2afe278387d4019e4d8111e815df8f55"}, } diff --git a/test/kino/explorer_test.exs b/test/kino/explorer_test.exs index 58159e5..c1cdece 100644 --- a/test/kino/explorer_test.exs +++ b/test/kino/explorer_test.exs @@ -464,9 +464,10 @@ defmodule Kino.ExplorerTest do test "export to" do df = Explorer.DataFrame.new(%{n: Enum.to_list(1..25)}) + rows_spec = %{order: nil} for format <- ["CSV", "NDJSON", "Parquet"] do - exported = Kino.Explorer.export_data(%{df: df}, format) + exported = Kino.Explorer.export_data(rows_spec, %{df: df}, format) extension = ".#{String.downcase(format)}" assert {:ok, %{extension: ^extension}} = exported end @@ -474,9 +475,10 @@ defmodule Kino.ExplorerTest do test "export to for lazy data frames" do df = Explorer.DataFrame.new(%{n: Enum.to_list(1..25)}, lazy: true) + rows_spec = %{order: nil} for format <- ["CSV", "NDJSON", "Parquet"] do - exported = Kino.Explorer.export_data(%{df: df}, format) + exported = Kino.Explorer.export_data(rows_spec, %{df: df}, format) extension = ".#{String.downcase(format)}" assert {:ok, %{extension: ^extension}} = exported end @@ -484,6 +486,7 @@ defmodule Kino.ExplorerTest do test "export to for data frames with list-type columns" do df = Explorer.DataFrame.new(%{list: Explorer.Series.from_list([[1, 2], [1]])}) + rows_spec = %{order: nil} widget = Kino.Explorer.new(df) data = connect(widget) @@ -491,7 +494,7 @@ defmodule Kino.ExplorerTest do assert %{export: %{formats: ["NDJSON", "Parquet"]}} = data for format <- ["NDJSON", "Parquet"] do - exported = Kino.Explorer.export_data(%{df: df}, format) + exported = Kino.Explorer.export_data(rows_spec, %{df: df}, format) extension = ".#{String.downcase(format)}" assert {:ok, %{extension: ^extension}} = exported end