Skip to content

Commit

Permalink
Add enable_time_slider toogle to Map model. Improving visual feedback…
Browse files Browse the repository at this point in the history
…, embedding numbers per year, show all places switch...)
  • Loading branch information
ut committed Jun 13, 2024
1 parent a4af1ec commit 92b1b78
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 55 deletions.
4 changes: 2 additions & 2 deletions app/assets/javascripts/graphics/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ var LargeMarkerIcon = {
}
}),
iconSVG: function(params) {
console.log("PARAMS",params);
// console.log("PARAMS",params);
var svg = `<svg height="${params.marker_size}" width="${params.marker_size}" xmlns="http://www.w3.org/2000/svg">${params.defs_with_gradient}<circle class="cls-1" cx="${params.marker_size/2}" cy="${params.marker_size/2}" r="${params.marker_size/2}" fill="${params.color}" fill-opacity="${params.opacity}" stroke="${params.stroke}" stroke-width="${params.stroke_width}" stroke-opacity="${params.stroke_opacity}" shape-rendering="geometricPrecision"></circle></svg>`;
return encodeURI("data:image/svg+xml," + svg).replace(new RegExp('#', 'g'),'%23');
},
create: function(params) {
var defaultParams = {marker_size: 30, color: "black", opacity: 0.7, stroke: "transparent", stroke_width: 0, stroke_opacity: 0, defs_with_gradient: ""};
params = Object.assign({}, defaultParams, params);
console.log("PARAMS",params);
// console.log("PARAMS",params);
return new this.CustomLargeIcon({iconUrl: this.iconSVG(params)});
}

Expand Down
72 changes: 53 additions & 19 deletions app/assets/javascripts/helpers/timeslider.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ jQuery(function ($) {
if ( $('#selection').data('map-marker-display-mode') !== 'single' ) {
return;
}
if ( $('#selection').data('map-enable-time-slider') !== true ) {
return;
}
// places_by_year is provided by the controller inline in the show view
console.log('places_by_year',places_by_year.length, places_by_year);
console.log('places_by_year',places_by_year[1990].length);
console.log('places_by_year',places_by_year[1991].length);
console.log('places_by_year',places_by_year[1992].length);
console.log('places_by_year',places_by_year[2010].length);
// scrollbuttons
let scrollLeft = document.createElement('div');
scrollLeft.setAttribute('id', 'scroll-left');
Expand All @@ -19,12 +28,19 @@ jQuery(function ($) {
// timeline
let timelineWrapper = document.createElement('div');
timelineWrapper.setAttribute('id', 'timeline-wrapper');

timelineWrapper.appendChild(scrollLeft);
timelineWrapper.appendChild(scrollRight);
let timelineInfoBox = document.createElement('div');
timelineInfoBox.setAttribute('id', 'timeline-infobox');
timelineInfoBox.innerHTML = '<div id="timeline-info-status"></div><div id="timeline-function">(<a href="">Show all places</a>)</div>';

let timelineInnerWrapper = document.createElement('div');
timelineInnerWrapper.setAttribute('id', 'timeline-innerwrapper');
timelineInnerWrapper.appendChild(scrollLeft);
timelineInnerWrapper.appendChild(scrollRight);
let timelineContent = document.createElement('div');
timelineContent.setAttribute('id', 'timeline-content');
timelineWrapper.appendChild(timelineContent);
timelineInnerWrapper.appendChild(timelineContent);
timelineWrapper.appendChild(timelineInfoBox);
timelineWrapper.appendChild(timelineInnerWrapper);
let body = document.querySelector("body");
document.body.insertBefore(timelineWrapper, document.querySelector("footer"));

Expand All @@ -39,23 +55,26 @@ jQuery(function ($) {
for (var i = minYear; i <= maxYear; i += step) {
var div = document.createElement('div');
div.classList.add('year');
div.setAttribute('title', 'Show '+places_by_year[i].length+' places for '+i);
div.setAttribute('id', 'year'+i);
div.setAttribute('data-year', i);
div.setAttribute('data-places', places_by_year[i].length);
div.textContent = i;
timelineContent.appendChild(div);
}

}
});
let current_selected_year = 1900;
function filterMarkers(selectedYear) {
function filterMarkers(selectedYear,places) {

console.log("filterMarkers **************",selectedYear);
console.log(window.markers);
current_selected_year = ( selectedYear > current_selected_year ) ? selectedYear : current_selected_year;

const status = document.getElementById("timeline-info-status");
status.innerHTML = "Show places in "+selectedYear;
status.innerHTML = "Showing <span style='color:#c6c600'>"+places+"</span> places in <span style='color:#c6c600'>"+selectedYear+"</span>";


window.markers.forEach(function(marker) {
if (!marker.data) {
Expand Down Expand Up @@ -97,6 +116,8 @@ function filterMarkers(selectedYear) {
});
}
function resetMarkers() {
const status = document.getElementById("timeline-info-status");
status.innerHTML = "Showing all places";
markers.forEach(function(marker) {
if (!marker.data) {
return;
Expand All @@ -107,13 +128,13 @@ function resetMarkers() {
});
}

function SelectAndFilterByYear(el,yearDivs,year) {
function SelectAndFilterByYear(el,yearDivs,year,places) {
let active = false;
if ( el.classList.contains("active") ) {
active = true;
resetMarkers();
} else {
filterMarkers(year);
filterMarkers(year,places);
}
yearDivs.forEach(function(div) {
div.classList.remove("active");
Expand All @@ -128,6 +149,9 @@ document.addEventListener("DOMContentLoaded", function() {
if ( $('#selection').data('map-marker-display-mode') !== 'single' ) {
return;
}
if ( $('#selection').data('map-enable-time-slider') !== true ) {
return;
}
const timelineContent = document.getElementById("timeline-content");
const scrollLeft = document.getElementById("scroll-left");
const scrollRight = document.getElementById("scroll-right");
Expand All @@ -151,22 +175,32 @@ document.addEventListener("DOMContentLoaded", function() {
yearDiv.addEventListener("click", function() {

var selectedYear = this.getAttribute('data-year');
SelectAndFilterByYear(this,yearDivs,selectedYear);
var selectedYearPlaces = this.getAttribute('data-places');
SelectAndFilterByYear(this,yearDivs,selectedYear,selectedYearPlaces);
});
});
console.log("Prep eventListeners done");

}
});


$(document).on('click', '#timeline-function a', function(event) {
event.preventDefault();
resetMarkers();
const yearDivs = document.querySelectorAll(".year");
yearDivs.forEach(function(div) {
div.classList.remove("active");
});
});

// for a single slider, used in places index
$(document).on('changed.zf.slider', '[data-slider]', function(event) {
var $slider = $(event.currentTarget);
var $numberInput = $slider.children('input');
console.log($numberInput.val())
$('#slider-selection').html($numberInput.val())
// TODO: create list of all places with startyear and endyear data values
// hide all
// show only those existing in the selected year
});
// for a single slider, used in places index
$(document).on('changed.zf.slider', '[data-slider]', function(event) {
var $slider = $(event.currentTarget);
var $numberInput = $slider.children('input');
console.log($numberInput.val())
$('#slider-selection').html($numberInput.val())
// TODO: create list of all places with startyear and endyear data values
// hide all
// show only those existing in the selected year
});
11 changes: 6 additions & 5 deletions app/assets/javascripts/layers.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,14 @@ function ShowPlacesForLayer(map,text_layers,image_layers,marker_meta_layers,curv
);

if ( $('#selection').data('map-marker-display-mode') === 'single' ) {

const yearDivs = document.querySelectorAll(".year");
let startyear = $('#selection').data('map-timeline-minyear');
console.log("Pre-select first year ", startyear, yearDivs.length);
let el = document.getElementById('year'+startyear);
SelectAndFilterByYear(el,yearDivs,startyear);
}
if ( startyear ) {
console.log("Pre-select first year ", startyear, yearDivs.length);
let el = document.getElementById('year'+startyear);
SelectAndFilterByYear(el,yearDivs,startyear,0);
}
}


console.log("Fit to bounds routine");
Expand Down
7 changes: 7 additions & 0 deletions app/assets/stylesheets/4_map.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@
div.leaflet-popup-content-image {
max-height: 450px;
overflow: hidden;

@media screen and (max-height: 49.9375em) {
max-height: 250px;
}
@media screen and (max-height: 39.9375em) {
max-height: 200px;
}
@media screen and (max-width: 39.9375em) {
max-height: 250px;
}
Expand Down
22 changes: 16 additions & 6 deletions app/assets/stylesheets/6_timeline.css.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,38 +35,48 @@ table#timeline-list {
justify-content: center;
z-index: 9000;
border: 1px solid transparent;

}


#timeline-wrapper {
position: absolute;
left: 10px;
right: 50px;
bottom: 60px;
padding: 0 20px;
display: flex;
justify-content: center;
z-index: 996;
border: 1px solid transparent;
@media screen and (max-width: 63.9375em) {
left: 20px;
right: 50px;
}

}
#timeline-infobox {
display: flex;
}
#timeline-function {
margin-left: 10px;
}
#timeline-innerwrapper {
position: relative;
border: 1px solid #444;
padding: 0 20px;
display: flex;
justify-content: center;
}
#timeline-content {
background-color: transparent;
background-color: rgba(0, 0, 0, 0.3);
border-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
margin: 0 10px;
padding: 5px 30px 5px 220px;
padding: 5px 30px 5px 100px;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
justify-content: left;
flex-wrap: nowrap;
overflow: hidden;
align-items: center;

}
#timeline-content div {
font-family: sans-serif;
Expand Down
16 changes: 14 additions & 2 deletions app/controllers/maps_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,21 @@ def show

@places = @map_layers.flat_map(&:places)
@places_with_dates = @places.reject { |place| place.startdate.nil? && place.enddate.nil? }
# timeline calculation, for now on a yearly basis

# timeline calculation, for now on a yearly basis
@minyear = @places.reject { |place| place.startdate.nil? }.min_by { |place| place.startdate.year }&.startdate&.year || Date.today.year
@maxyear = @places.reject { |place| place.enddate.nil? }.max_by { |place| place.enddate.year }&.enddate&.year || Date.today.year

# make a hash, where the key is a single year and it contains all places that are active in that year
@places_by_year = {}
@places_with_dates.each do |place|
startyear = place.startdate.nil? ? @minyear : place.startdate.year
endyear = place.enddate.nil? ? startyear : place.enddate.year
(startyear..endyear).each do |year|
@places_by_year[year] ||= []
@places_by_year[year] << place
end
end
@timespan = @maxyear - @minyear

respond_to do |format|
Expand Down Expand Up @@ -103,6 +115,6 @@ def set_map

# Never trust parameters from the scary internet, only allow the white list through.
def map_params
params.require(:map).permit(:title, :subtitle, :text, :credits, :published, :script, :image, :group_id, :mapcenter_lat, :mapcenter_lon, :zoom, :northeast_corner, :southwest_corner, :iconset_id, :basemap_url, :basemap_attribution, :background_color, :popup_display_mode, :marker_display_mode, :show_annotations_on_map, :preview_url, :enable_privacy_features, :enable_map_to_go, :enable_historical_maps)
params.require(:map).permit(:title, :subtitle, :text, :credits, :published, :script, :image, :group_id, :mapcenter_lat, :mapcenter_lon, :zoom, :northeast_corner, :southwest_corner, :iconset_id, :basemap_url, :basemap_attribution, :background_color, :popup_display_mode, :marker_display_mode, :show_annotations_on_map, :preview_url, :enable_privacy_features, :enable_map_to_go, :enable_historical_maps, :enable_time_slider)
end
end
5 changes: 4 additions & 1 deletion app/views/maps/_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
%p
= f.input :enable_map_to_go, :input_html => { :class => '' }, label: 'Enable the Map to go feature'
%p.hint This option enables that a user can use the Map to go function and the live preview
%p
= f.input :enable_time_slider, :input_html => { :class => '' }, label: 'Enable a Timeslider (NEW)'
%p.hint This option enables a timeslider on the map. Please consider that only places with a date will be displayed on this timeslider!

- else
%i.fi-torsos-all.fi-21
Expand Down Expand Up @@ -94,7 +97,7 @@
%i.fi.fi-info{"data-tooltip"=>true, :title=>"Basemap are made by someone, you should credit them here. Licences of most providers like Openstreetmap require to mention them properly."}
%hr
.grid-x.grid-padding-x
.large-12.medium-12.small-12.cell
.large-12.medium-12.small-12.cell
%label Special: Enable historical maps of Hamburg
%p
= f.input :enable_historical_maps
Expand Down
43 changes: 24 additions & 19 deletions app/views/maps/show.html.haml
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
- content_for(:title) { @map.title }

#timeline-info{:style => "background-color: #fff; padding:10px; margin-bottom: 10px;"}
%h5
Timeline (still in testing)
%i.fi.fi-info{"data-tooltip"=>true, :title=>"This message will only be visible during the test phase :)" }
%p.hint
#{@places.count} places in #{@map_layers.count} layers, #{@places_with_dates.count} #{@places_with_dates.count > 1 ? 'places' : 'place'} with dates
%br
Timerange:
#{@minyear}
\—
#{@maxyear}
(#{@timespan} Years)
%br
- if @map.marker_display_mode == 'single'
Marker display mode is set to single ✓
- else
Marker display mode is set to cluster x (<em>Timeline will work only with single marker display mode enabled</em>)
%h5#timeline-info-status
#selection{:data => { 'url' => "/maps/#{@map.id}.json", 'map_id' => "#{@map.id}", 'map-center-lat' => "#{@map.mapcenter_lat}", 'map-center-lon' => "#{@map.mapcenter_lon}", 'map-zoom' => "#{@map.zoom}", 'map-extent-northeast' => "#{@map.northeast_corner}", 'map-extent-southwest' => "#{@map.southwest_corner}", 'map-basemap-url' => "#{@map.basemap_url}", 'map-basemap-attribution' => "#{@map.basemap_attribution}", 'map-background-color' => "#{@map.background_color}", 'map-popup-display-mode' => "#{@map.popup_display_mode}", 'map-marker_display_mode' => "#{@map.marker_display_mode}", 'map-enable_historical_maps' => "#{@map.enable_historical_maps}", 'map-timeline-minyear' => "#{@minyear}", 'map-timeline-maxyear' => "#{@maxyear}", 'map-timeline-timespan' => "#{@timespan}" }}
- if @map.enable_time_slider
#timeline-info{:style => "background-color: #fff; padding:10px; margin-bottom: 10px;"}
%h5
Timeline (still in testing)
%i.fi.fi-info{"data-tooltip"=>true, :title=>"This message will only be visible during the test phase :)" }
%p.hint
#{@places.count} places in #{@map_layers.count} layers, #{@places_with_dates.count} #{@places_with_dates.count > 1 ? 'places' : 'place'} with dates
%br
Timerange:
#{@minyear}
\—
#{@maxyear}
(#{@timespan} Years)
%br
- if @map.marker_display_mode == 'single'
Marker display mode is set to single ✓
- else
Marker display mode is set to cluster x (<em>Timeline will work only with single marker display mode enabled</em>)
%script{:type => "text/javascript"}
let places_by_year = #{@places_by_year.to_json.html_safe}
console.log('places_by_year',places_by_year.length, places_by_year);


#selection{:data => { 'url' => "/maps/#{@map.id}.json", 'map_id' => "#{@map.id}", 'map-center-lat' => "#{@map.mapcenter_lat}", 'map-center-lon' => "#{@map.mapcenter_lon}", 'map-zoom' => "#{@map.zoom}", 'map-extent-northeast' => "#{@map.northeast_corner}", 'map-extent-southwest' => "#{@map.southwest_corner}", 'map-basemap-url' => "#{@map.basemap_url}", 'map-basemap-attribution' => "#{@map.basemap_attribution}", 'map-background-color' => "#{@map.background_color}", 'map-popup-display-mode' => "#{@map.popup_display_mode}", 'map-marker_display_mode' => "#{@map.marker_display_mode}", 'map-enable_historical_maps' => "#{@map.enable_historical_maps}", 'map-enable_time_slider' => "#{@map.enable_time_slider}", 'map-timeline-minyear' => "#{@minyear}", 'map-timeline-maxyear' => "#{@maxyear}", 'map-timeline-timespan' => "#{@timespan}" }}
- if params[:setbound]
#form-wrapper.small-wrapper
.grid-x
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20240613101034_add_enable_time_slider_to_maps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddEnableTimeSliderToMaps < ActiveRecord::Migration[6.1]
def change
add_column :maps, :enable_time_slider, :boolean, :default => false
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2024_03_13_185111) do
ActiveRecord::Schema.define(version: 2024_06_13_101034) do

create_table "active_storage_attachments", charset: "utf8mb3", collation: "utf8mb3_general_ci", force: :cascade do |t|
t.string "name", null: false
Expand Down Expand Up @@ -190,6 +190,7 @@
t.boolean "enable_privacy_features", default: true
t.string "marker_display_mode", default: "cluster"
t.boolean "enable_historical_maps", default: false
t.boolean "enable_time_slider", default: false
t.index ["group_id"], name: "index_maps_on_group_id"
t.index ["slug"], name: "index_maps_on_slug", unique: true
end
Expand Down

0 comments on commit 92b1b78

Please sign in to comment.