Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement panel of type map #12

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ live view process:
- [chartjs](https://www.chartjs.org/) for rendering plots
- [tabulator](https://tabulator.info/) for rendering tabular data
- [flatpickr](https://flatpickr.js.org/) for time range selection
- [highcharts](https://www.highcharts.com/) for maps (licensing cost)

## Features

Expand All @@ -34,6 +35,7 @@ live view process:
- Stat panels (show single or multiple stats)
- Table panels
- Summary statistics in charts
- Map with areas and pins

## Installation

Expand All @@ -53,12 +55,13 @@ In order to be able to use the provided components, the library's
In `assets/js/app.js`:

```javascript
import { ChartJSHook, TableHook, TimeRangeHook } from "luminous"
import { ChartJSHook, TableHook, TimeRangeHook, MapHook } from "luminous"

let Hooks = {
TimeRangeHook: new TimeRangeHook(),
ChartJSHook: new ChartJSHook(),
TableHook: new TableHook()
TableHook: new TableHook(),
MapHook: new MapHook()
}

...
Expand Down
4 changes: 3 additions & 1 deletion assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { LiveSocket } from "phoenix_live_view"
import ChartJSHook from "./components/chartjs_hook"
import TimeRangeHook from "./components/time_range_hook"
import TableHook from "./components/table_hook"
import MapHook from "./components/map_hook"

let Hooks = {
ChartJSHook: new ChartJSHook(),
TimeRangeHook: new TimeRangeHook(),
TableHook: new TableHook()
TableHook: new TableHook(),
MapHook: new MapHook()
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
Expand Down
72 changes: 72 additions & 0 deletions assets/js/components/map_hook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import HighCharts from 'highcharts';
import MapChart from 'highcharts/modules/map.js';

function MapHook() {
this.mounted = function () {
// the `dataset` property carries all `data-*` attributes of the corresponding html element
const element_data = this.el.dataset
// initialize the library
MapChart(HighCharts);
// Create the chart
this.map = HighCharts.mapChart(element_data.mapId, {
chart: {
map: JSON.parse(this.el.dataset.json),
backgroundColor: 'rgba(0,0,0,0)', // transparent background
height: '100%'
},

title: { text: '' },
credits: { enabled: false },

mapNavigation: {
enabled: true,
},

colorAxis: { min: 0 },

series: [{
name: this.el.dataset.country,
borderColor: '#A0A0A0',
nullColor: 'rgba(200, 200, 200, 0.3)',
states: {
hover: {
color: '#BADA55'
}
},
tooltip: {
headerFormat: '',
pointFormat: '{point.description}',
},
dataLabels: {
enabled: false,
}
}, {
type: 'mappoint',
tooltip: {
headerFormat: '',
pointFormat: '{point.description}',
},
events: {
click: function (e) {
const url = e.target.point.url;
window.open(url);
}
},
color: "#030303"
}]
});

// setup the event handler
this.handleEvent("panel-" + element_data.componentId + "::refresh-data", this.setMapData())
};

this.setMapData = function () {
return (payload) => {
this.map.series[0].setData(payload.Areas)
this.map.series[1].setData(payload.Pins)
}
};

};

export default MapHook;
3 changes: 2 additions & 1 deletion assets/js/luminous.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import ChartJSHook from "./components/chartjs_hook"
import TableHook from "./components/table_hook"
import TimeRangeHook from "./components/time_range_hook"
import MapHook from "./components/map_hook"

export { ChartJSHook, TableHook, TimeRangeHook }
export { ChartJSHook, TableHook, TimeRangeHook, MapHook }
13 changes: 13 additions & 0 deletions assets/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"chartjs-adapter-luxon": "^1.2.0",
"chartjs-plugin-zoom": "^1.2.1",
"flatpickr": "^4.6.9",
"highcharts": "^11.1.0",
"luxon": "^3.0.3",
"tabulator-tables": "^5.4.3"
}
}
}
1 change: 1 addition & 0 deletions assets/topojson/europe.topo.json

Large diffs are not rendered by default.

58 changes: 58 additions & 0 deletions dev/demo_dashboard_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ defmodule Luminous.Dashboards.DemoDashboardLive do
unit: "μCKR",
ylabel: "Description"
),
Panel.define(
:europe_map,
"Europe Map",
:map,
[Query.define(:europe_map, Queries)],
description: "This is a panel with the map of Europe",
map: File.read!(Path.expand("../assets/topojson/europe.topo.json", __DIR__))
),
Panel.define(
:multiple_time_series_with_stacking,
"Multiple Time Series with Stacking",
Expand Down Expand Up @@ -288,6 +296,56 @@ defmodule Luminous.Dashboards.DemoDashboardLive do
}
)
end

def query(:europe_map, _t, _variables) do
data = %{
Areas: [
%{
"hc-key": "gr",
value: 10.64,
description: "● Greece<br/><b>10.64 million citizens</b>"
},
%{
"hc-key": "de",
value: 83.2,
description: "● Germany<br/><b>83.2 million citizens</b>"
},
%{
"hc-key": "it",
value: 59.11,
description: "● Italy<br/><b>59.11 million citizens</b>"
}
],
Pins: [
%{
lat: 37.9838,
lon: 23.7275,
description: "<b>Athens </b><br>The capital of Greece",
marker: %{symbol: "triangle", width: 16, height: 16},
url: "https://en.wikipedia.org/wiki/Athens"
},
%{
lat: 52.5200,
lon: 13.4050,
description: "<b>Berlin </b><br>The capital of Germany",
marker: %{symbol: "circle", width: 16, height: 16},
url: "https://en.wikipedia.org/wiki/Berlin"
},
%{
lat: 44.4268,
lon: 26.1025,
description: "<b>Bucharest </b><br>The capital of Romania",
marker: %{symbol: "url(https://upload.wikimedia.org/wikipedia/commons/thumb/7/73/Flag_of_Romania.svg/1200px-Flag_of_Romania.svg.png)", width: 28, height: 20},
url: "https://en.wikipedia.org/wiki/Bucharest"
}
]
}

Query.Result.new(
data,
attrs: %{}
)
end
end

@doc false
Expand Down
11 changes: 11 additions & 0 deletions dev/test_dashboard_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ defmodule Luminous.Dashboards.TestDashboardLive do
"Panel 11 (nil stat)",
:stat,
[Query.define(:q11, Queries)]
),
Panel.define(
:p12,
"Panel 12 (map)",
:map,
[Query.define(:q12, Queries)],
map: "foo"
)
],
variables: [
Expand Down Expand Up @@ -197,6 +204,10 @@ defmodule Luminous.Dashboards.TestDashboardLive do
def query(:q11, _time_range, _variables) do
Query.Result.new([{"foo", nil}])
end

def query(:q12, _time_range, _variables) do
Query.Result.new(%{Areas: [%{hc_key: "foo", value: 5, description: "bar"}], Pins: [%{lat: 5, lon: 6}]})
end
end

def render(assigns) do
Expand Down
Loading