Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
buren committed Sep 30, 2015
0 parents commit 63d3416
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
@@ -0,0 +1,5 @@
/_build
/deps
erl_crash.dump
*.ez
/tmp
4 changes: 4 additions & 0 deletions README.md
@@ -0,0 +1,4 @@
Chartkick
=========

** TODO: Add description **
24 changes: 24 additions & 0 deletions config/config.exs
@@ -0,0 +1,24 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config

# This configuration is loaded before any dependency and is restricted
# to this project. If another project depends on this project, this
# file won't be loaded nor affect the parent project. For this reason,
# if you want to provide default values for your application for third-
# party users, it should be done in your mix.exs file.

# Sample configuration:
#
# config :logger, :console,
# level: :info,
# format: "$date $time [$level] $metadata$message\n",
# metadata: [:user_id]

# It is also possible to import configuration files, relative to this
# directory. For example, you can emulate configuration per environment
# by uncommenting the line below and defining dev.exs, test.exs and such.
# Configuration from the imported file will override the ones defined
# here (which is why it is important to import them last).
#
# import_config "#{Mix.env}.exs"
77 changes: 77 additions & 0 deletions lib/chartkick.ex
@@ -0,0 +1,77 @@
defmodule Chartkick do
defmodule ChartOptions do
@derive [Poison.Encoder]
defstruct [:min, :max, :colors, :stacked, :discrete, :xtitle, :ytitle]
end

def line_chart(data_source, options \\ []) do
chartkick_chart("LineChart", data_source, options)
end

def pie_chart(data_source, options \\ []) do
chartkick_chart("PieChart", data_source, options)
end

def column_chart(data_source, options \\ []) do
chartkick_chart("ColumnChart", data_source, options)
end

def bar_chart(data_source, options \\ []) do
chartkick_chart("BarChart", data_source, options)
end

def area_chart(data_source, options \\ []) do
chartkick_chart("AreaChart", data_source, options)
end

def combo_chart(data_source, options \\ []) do
chartkick_chart("ComboChart", data_source, options)
end

def geo_chart(data_source, options \\ []) do
chartkick_chart("GeoChart", data_source, options)
end

def scatter_chart(data_source, options \\ []) do
chartkick_chart("ScatterChart", data_source, options)
end

def timeline(data_source, options \\ []) do
chartkick_chart("Timeline", data_source, options)
end

def chartkick_chart(klass, data_source, options \\ []) do
id = options[:id] || generate_element_id
height = options[:height] || "300px"
only = options[:only]
"""
#{unless only == :script, do: chartkick_tag(id, height)}
#{unless only == :html, do: chartkick_script(klass, id, data_source, options_json(options))}
"""
end

def chartkick_script(klass, id, data_source, options_json) do
"<script type=\"text/javascript\">new Chartkick.#{klass}('#{id}', #{data_source}, #{options_json});</script>"
end

def chartkick_tag(id, height) do
"<div id=\"#{id}\" style=\"height: #{height}; text-align: center; color: #999; line-height: #{height}; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;\">Loading...</div>"
end

defp generate_element_id do
UUID.uuid4()
end

defp options_json(opts) do
Poison.encode!(%ChartOptions{
min: opts[:min],
max: opts[:max],
colors: opts[:colors],
stacked: opts[:stacked],
discrete: opts[:discrete],
xtitle: opts[:xtitle],
ytitle: opts[:ytitle]
})
end

end
33 changes: 33 additions & 0 deletions mix.exs
@@ -0,0 +1,33 @@
defmodule Chartkick.Mixfile do
use Mix.Project

def project do
[app: :chartkick,
version: "0.0.1",
elixir: "~> 1.0",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps]
end

# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: [:logger]]
end

# Dependencies can be Hex packages:
#
# {:mydep, "~> 0.3.0"}
#
# Or git/path repositories:
#
# {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
#
# Type `mix help deps` for more examples and options
defp deps do
[{ :uuid, "~> 1.0" },
{:poison, "~> 1.5"}]
end
end
2 changes: 2 additions & 0 deletions mix.lock
@@ -0,0 +1,2 @@
%{"poison": {:hex, :poison, "1.5.0"},
"uuid": {:hex, :uuid, "1.0.1"}}
120 changes: 120 additions & 0 deletions test/chartkick_test.exs
@@ -0,0 +1,120 @@
defmodule ChartkickTest do
use ExUnit.Case

test "pie_chart" do
script = Chartkick.pie_chart("{}")
expected = "new Chartkick.PieChart("
assert String.contains?(script, expected)
end

test "column_chart" do
script = Chartkick.column_chart("{}")
expected = "new Chartkick.ColumnChart("
assert String.contains?(script, expected)
end

test "bar_chart" do
script = Chartkick.bar_chart("{}")
expected = "new Chartkick.BarChart("
assert String.contains?(script, expected)
end

test "area_chart" do
script = Chartkick.area_chart("{}")
expected = "new Chartkick.AreaChart("
assert String.contains?(script, expected)
end

test "combo_chart" do
script = Chartkick.combo_chart("{}")
expected = "new Chartkick.ComboChart("
assert String.contains?(script, expected)
end

test "geo_chart" do
script = Chartkick.geo_chart("{}")
expected = "new Chartkick.GeoChart("
assert String.contains?(script, expected)
end

test "scatter_chart" do
script = Chartkick.scatter_chart("{}")
expected = "new Chartkick.ScatterChart("
assert String.contains?(script, expected)
end

test "timeline" do
script = Chartkick.timeline("{}")
expected = "new Chartkick.Timeline("
assert String.contains?(script, expected)
end


test "line_chart returns LineChart" do
script = Chartkick.line_chart("{}")
expected = "new Chartkick.LineChart("
assert String.contains?(script, expected)
end

test "chartkick_chart contains HTML-tag styling" do
height = "42px"
script = Chartkick.chartkick_chart("", "{}", height: height)
expected = "style=\"height: #{height}; text-align: center; color: #999; line-height: #{height};"
assert String.contains?(script, expected)
end

test "chartkick_chart returns with default height set" do
script = Chartkick.chartkick_chart("", "{}")
expected = "height: 300px"
assert String.contains?(script, expected)
end

test "chartkick_chart returns with custom height set" do
script = Chartkick.chartkick_chart("", "{}", height: "400px")
expected = "height: 400px"
assert String.contains?(script, expected)
end

test "chartkick_chart with only script option does not render html-tag" do
script = Chartkick.chartkick_chart("", "{}", only: :script)
expected = "</div>"
assert !String.contains?(script, expected)
end

test "chartkick_chart with only html option does not render script-tag" do
html = Chartkick.chartkick_chart("", "{}", only: :html)
expected = "<script type=\"text/javascript\">"
assert !String.contains?(html, expected)
end

test "chartkick_script contains script open tag" do
script = Chartkick.chartkick_script("", "", "{}", "{}")
expected = "<script type=\"text/javascript\">"
assert String.contains?(script, expected)
end

test "chartkick_script ends with closing script tag" do
script = Chartkick.chartkick_script("", "", "{}", "{}")
expected = "</script>"
assert String.ends_with?(script, expected)
end

test "chartkick_script returns script with correct chart class" do
script = Chartkick.chartkick_script("LineChart", "", "{}", "{}")
expected = "new Chartkick.LineChart"
assert String.contains?(script, expected)
end

test "chartkick_script returns script with custom id set" do
id = "my-chart-id"
script = Chartkick.chartkick_script("klass", id, "{}", "{}")
expected = "new Chartkick.klass('#{id}"
assert String.contains?(script, expected)
end

# test "DEBUG" do
# script = Chartkick.chartkick_chart("", "{}", stacked: true)
# expected = "1298312381askjdjaskdjaskdas2098"
# assert script == expected
# end
end
1 change: 1 addition & 0 deletions test/test_helper.exs
@@ -0,0 +1 @@
ExUnit.start

0 comments on commit 63d3416

Please sign in to comment.