Main points
I use smashing.io, to be fast and to avoid install i run it as (in) a container.This solution allow me to avoid ruby install and the specific gems needed for smashing run, and libXXX-devel and libZZZ and so on.
the target
- add a pie chart board widget
- relying on an API JSON
Start it with docker-compose
I will use a docker compose for development :- one for smashing
- one for fake my data server -json server)
version: '2'
services:
dashboard:
image: "rgcamus/alpine_smashing"
ports:
- "8080:3030"
networks:
- localnetwork
jsonserver:
image: "williamyeh/json-server"
volumes:
- /home/franckys/03_DATA/workspace/fakeData:/data
command:
--watch db.json
networks:
- localnetwork
expose:
- "3000"
networks:
localnetwork:
driver: bridge
I don't use image volume for the dashboard. I want to have a "self contain" image. So the dashboard source will be embed in the image and for security I will use git to checkout the board sources.
For dev I use "docker cp src target" to inject modifications in my dashboard container.
First run
with command line a "docker-compose up" does the job. In your favorite browser connect on locahost:8080 and you will see the default dashboard :Build the board
fake a json API
I my case I want to connect my board to a Json api. Here I don't want to show how to connect to the API , but how to fake it.npm json-server
To fake my server I use json server through npm.Just defining a json.db file and start it allow you to access a faked REST API.
In this docker container case, the file should be in the folder mounted as volume. In the previous docker-compose it means in :
/home/franckys/03_DATA/workspace/fakeData
Here this is my file contend (db.json) :
{
"issues": [
{
"id": "FRKY_10",
"epicLink": "FRKY_3",
"summary": "story one",
"storyPoint" : 3
},
{
"id": "FRKY_11",
"epicLink": "FRKY_3",
"summary": "story two",
"storyPoint" : 3
},
{
"id": "FRKY_1",
"epicLink": "FRKY_2",
"summary": "story one",
"storyPoint" : 2
},
{
"id": "FRKY_5",
"epicLink": "FRKY_12",
"summary": "story twelve",
"storyPoint" : 5
}
],
"epic": [
{
"id": "FRKY_3",
"title": "EPIC01"
},
{
"id": "FRKY_2",
"title": "EPIC02"
}
]
}
If you want to see it in action , replace in docker-compose.yaml :
expose:
- "3000"
by
ports:
- "3000:3000"
the previous setup :
- bind the container port 3000 to the on host (3000 port).
- remove the 3000 exposure on the docker network : localnetwork
http://localhost:3000/epic and you should obtain :
[
{
"id": "FRKY_3",
"title": "EPIC01"
},
{
"id": "FRKY_2",
"title": "EPIC02"
}
]
Don't forget to revert this modification.
Using datas
Smashing rely on a scheduled job to get datas. Just have a look in the directory jobs :# identity your container instance id
docker ps
# run a bash
docker exec -it ${YOUR_CONTAINER_ID} bash
# In the container bash
ls jobs
buzzwords.rb convergence.rb sample.rb twitter.rb
As you could see it's in Ruby. So, to use our fake data we have to :- make a http request
- process data to send it to your board
Where is my pie chart
So first I will use this widget :Google Visualizations Pie Chart so first we should install it, use it in the board then provide it the data
Install it
To install this widget we have to be be connected to the smashing container :docker exec -it ${YOUR_CONTAINER_ID} bash
then install the wiget :
smashing install GIST_ID (see here )
Use it
All is explain in the widget documentation (here)you have to :
- modify the layout.erb file in /dashboard
- modify the board. In my case I modify the sample.erb file
- then add a job to access data (see next paragraph)
Provide it data
Providing data consist in writing a Ruby script to access my Json API and process the response in order to be able to send data in this format :send_event('mychart', slices: [
['Task', 'Hours per Day'],
['Work', 11],
['Eat', 2],
['Commute', 2],
['Watch TV', 2],
['Sleep', 7]
])
So for Http Access
uri = URI.parse("http://compose_jsonserver_1:3000/samples")
request = Net::HTTP::Get.new(uri)
begin
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
http.request(request)
end
parsed = JSON.parse(response.body)
# etc....
# send data to the wigdget, data is in arrayToSend
header = Array.new
header.insert(0, "header1")
header.insert(1, "header2")
arrayToSend.insert(0, header)
logger.info("ArrayEnd #{arrayToSend}")
send_event('mychart2', slices: arrayToSend)