I followed this Mapbox GL JS example step by step to make our map layers show and hide.
However, in this case, if our visitors forget to close the layers on top, like with "April" on, when they click on "June", the layers of June cannot be seen, cause they are under April layers.
Is there any ways I can switch between layers? Or if I have one button on the others will be turned off automatically?
My code is below.
HTML:
<div id='map'></div>
<nav id="menu"></nav>
JavaScript:
mapboxgl.accessToken = 'pk.eyJ1IjoibWFyY3VzcGciLCJhIjoiY2l2NmdtZjdyMDAwMjJ6bDVhb2JndDlrMiJ9.EopxTk2v-1WrWsgbLmL_XA';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/marcuspg/cj6xc2cb49xpg2sqpuuwbob0u', // stylesheet location
//center:[]
//zoom:13
});
// add a map layer_3d buildings
map.on('load', function() {
map.addLayer({
'id': '3d-buildings',
'source': 'composite',
'source-layer': 'building',
'filter': ['==', 'extrude', 'true'],
'type': 'fill-extrusion',
'minzoom': 15,
'paint': {
'fill-extrusion-color': '#aaa',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'min_height'
},
'fill-extrusion-opacity': .6
}
});
});
// group two layers into one
toggleLayer(['April','April_2'], 'April');
toggleLayer(['June','June_2'], 'June');
toggleLayer(['September', 'September_2'], 'September');
toggleLayer(['December','December_2'], 'December');
function toggleLayer(ids, name) {
var link = document.createElement('a');
link.href = '#';
link.className = 'active';
link.textContent = name;
link.onclick = function (e) {
e.preventDefault();
e.stopPropagation();
for (layers in ids){
var visibility = map.getLayoutProperty(ids[layers], 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(ids[layers], 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(ids[layers], 'visibility', 'visible');
}
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
CSS:
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
#menu {
background: #fff;
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
border-radius: 3px;
width: 120px;
border: 1px solid rgba(0, 0, 0, 0.4);
font-family: 'Open Sans', sans-serif;
}
#menu a {
font-size: 13px;
color: #404040;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #f8f8f8;
color: #404040;
}
#menu a.active {
background-color: #3887be;
color: #ffffff;
}
#menu a.active:hover {
background: #3074a4;
}
Here is a fiddle: https://jsfiddle.net/tianyiy/Ljujba4b/7/
Related
I am trying display two WMS layers,in which I have succeeded.Next is to get information of a particular WMS layer and display it as a pop up.I am using Openlayers3 with Geoserver.
First layer is 'Village Boundary' which is base layer and the second one is 'OSM Grids'.
These grids are numbered from 1 to 87. When I click on each grid , it should display its attribute information like grid number,map number etc. as a pop up.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="http://localhost:8080/geoserver/openlayers3/ol.css" type="text/css">
<script src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<style>
.ol-zoom {
top: 52px;
}
.ol-toggle-options {
z-index: 1000;
background: rgba(255,255,255,0.4);
border-radius: 4px;
padding: 2px;
position: absolute;
left: 8px;
top: 8px;
}
#updateFilterButton, #resetFilterButton {
height: 22px;
width: 22px;
text-align: center;
text-decoration: none !important;
line-height: 22px;
margin: 1px;
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
font-weight: bold !important;
background: rgba(0,60,136,0.5);
color: white !important;
padding: 2px;
}
.ol-toggle-options a {
background: rgba(0,60,136,0.5);
color: white;
display: block;
font-family: 'Lucida Grande',Verdana,Geneva,Lucida,Arial,Helvetica,sans-serif;
font-size: 19px;
font-weight: bold;
height: 22px;
line-height: 11px;
margin: 1px;
padding: 0;
text-align: center;
text-decoration: none;
width: 22px;
border-radius: 2px;
}
.ol-toggle-options a:hover {
color: #fff;
text-decoration: none;
background: rgba(0,60,136,0.7);
}
body {
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size: small;
}
iframe {
width: 100%;
height: 250px;
border: none;
}
/* Toolbar styles */
#toolbar {
position: relative;
padding-bottom: 0.5em;
}
#toolbar ul {
list-style: none;
padding: 0;
margin: 0;
}
#toolbar ul li {
float: left;
padding-right: 1em;
padding-bottom: 0.5em;
}
#toolbar ul li a {
font-weight: bold;
font-size: smaller;
vertical-align: middle;
color: black;
text-decoration: none;
}
#toolbar ul li a:hover {
text-decoration: underline;
}
#toolbar ul li * {
vertical-align: middle;
}
#map {
clear: both;
position: relative;
width: 600px;
height: 800px;
border: 1px solid black;
bottom:802px;
left:450px;
}
img{
position: relative;
width: 444px;
height: 775px;
top:5px;
}
#legend {
position: relative;
width: 444px;
height: 800px;
border: 1px solid black;
top:0px;
}
#wrapper {
width: 444px;
position: relative;
bottom:802px;
left:450px;
}
#location {
bottom:802px;
left:450px;
}
/* Styles used by the default GetFeatureInfo output, added to make IE happy */
table.featureInfo, table.featureInfo td, table.featureInfo th {
border: 1px solid #ddd;
border-collapse: collapse;
margin: 0;
padding: 0;
font-size: 90%;
padding: .2em .1em;
}
table.featureInfo th {
padding: .2em .2em;
font-weight: bold;
background: #eee;
}
table.featureInfo td {
background: #fff;
}
table.featureInfo tr.odd td {
background: #eee;
}
table.featureInfo caption {
text-align: left;
font-size: 100%;
font-weight: bold;
padding: .2em .2em;
}
</style>
<script src="http://localhost:8080/geoserver/openlayers3/ol.js" type="text/javascript"></script>
<title>OpenLayers map preview</title>
</head>
<body>
<div id="legend">
<img src="Legend.PNG.jpg">
</div>
<div id="map">
<input type="checkbox" value="Village Boundary" checked>Village Boundary<br>
<input type="checkbox" value="OSM Grids">OSM Grids<br>
</div>
<div id="wrapper">
<div id="location"></div>
<div id="scale"></div>
</div>
<script type="text/javascript">
var pureCoverage = false;
// if this is just a coverage or a group of them, disable a few items,
// and default to jpeg format
var format = 'image/png';
var bounds = [472440.0520989996, 911801.0984444692,
768802.9061656371, 1424302.9894040015];
if (pureCoverage) {
document.getElementById('antialiasSelector').disabled = true;
document.getElementById('jpeg').selected = true;
format = "image/jpeg";
}
var supportsFiltering = true;
if (!supportsFiltering) {
document.getElementById('filterType').disabled = true;
document.getElementById('filter').disabled = true;
document.getElementById('updateFilterButton').disabled = true;
document.getElementById('resetFilterButton').disabled = true;
}
var mousePositionControl = new ol.control.MousePosition({
className: 'custom-mouse-position',
target: document.getElementById('location'),
coordinateFormat: ol.coordinate.createStringXY(5),
undefinedHTML: ' '
});
var projection = new ol.proj.Projection({
code: 'EPSG:32643',
units: 'm',
axisOrientation: 'neu',
global: false
});
var villageboundary = new ol.layer.Image({
title:'Village Boundary',
type: 'base',
label:'Village Boundary',
source: new ol.source.ImageWMS({
ratio: 1,
url: 'http://localhost:8080/geoserver/geog585/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
"LAYERS": 'geog585:Village_Boundary',
"exceptions": 'application/vnd.ogc.se_inimage',
}
})
});
var osmgrid = new ol.layer.Image({
title:'OSM Grid',
visible: false,
label:'OSM Grid',
source: new ol.source.ImageWMS({
ratio: 1,
url: 'http://localhost:8080/geoserver/geog585/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
"LAYERS": 'geog585:OSM_Grid_25000_include_hazard_line',
"exceptions": 'application/vnd.ogc.se_inimage',
}
})
});
//Tile OSM
var tiledOSM = new ol.layer.Tile({
title:'OSM Grids',
visible: false,
label:'OSM Grids',
source: new ol.source.TileWMS({
url: 'http://localhost:8080/geoserver/geog585/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
tiled: true,
"LAYERS": 'geog585:OSM_Grid_25000_include_hazard_line',
"exceptions": 'application/vnd.ogc.se_inimage',
tilesOrigin: 472849.4548000004 + "," + 912420.9497999996
}
})
});
//Tile OSM
var map = new ol.Map({
controls: ol.control.defaults({
attribution: false
}).extend([mousePositionControl]),
target: 'map',
layers: [
villageboundary,
tiledOSM
],
view: new ol.View({
projection: projection
})
});
map.getView().on('change:resolution', function(evt) {
var resolution = evt.target.get('resolution');
var units = map.getView().getProjection().getUnits();
var dpi = 25.4 / 0.28;
var mpu = ol.proj.METERS_PER_UNIT[units];
var scale = resolution * mpu * 39.37 * dpi;
if (scale >= 9500 && scale <= 950000) {
scale = Math.round(scale / 1000) + "K";
} else if (scale >= 950000) {
scale = Math.round(scale / 1000000) + "M";
} else {
scale = Math.round(scale);
}
document.getElementById('scale').innerHTML = "Scale = 1 : " + scale;
});
map.getView().fit(bounds, map.getSize());
var changeLayer = function changeLayer(ev) {
var val = $(this).val();
var checked = $(this).is(':checked');
map.getLayers().forEach(function (layer) {
if (layer.get('label') === val) {
layer.setVisible(checked);
}
});
};
$('input').each(function (){ $(this).on('change', changeLayer); });
</script>
</body>
</html>
Can anybody help me with this.
The above requirement worked when I added the below given code snippet.
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
map.addOverlay(overlay);
map.on('singleclick', function(evt) {
var view = map.getView();
var viewResolution = /** #type {number} */ (map.getView().getResolution());
var url = tiledOSM.getSource().getGetFeatureInfoUrl(evt.coordinate, view.getResolution(), view.getProjection(), {
'INFO_FORMAT': 'application/json',
'PIXELRADIUS': 5,
'FEATURE_COUNT': 10
});
if (url) {
var parser = new ol.format.GeoJSON();
$.ajax({
url: url,
crossOrigin: true,
dataType: 'json',
jsonpCallback: 'parseResponse'
}).then(function(response) {
var result = parser.readFeatures(response);
if (result.length) {
var info = [];
for (var i = 0, ii = result.length; i < ii; ++i) {
info.push(result[i].get('Map_No'));
}
content.innerHTML =info.join;
}
});
}
overlay.setPosition(evt.coordinate);
});
Hence,I am marking this as answer.
I have set the 'Student Comments' layer as initially hidden using a setLayoutProperty call as seen here
map.on('load', function() {
map.setLayoutProperty('user-data-comments', 'visibility', 'none');
map.setLayoutProperty('user-data-comments-text', 'visibility', 'none');
});
However, when I open the interactive webmap, Mapbox displays the text before hiding it, when it should just appear hidden from the beginning. You can find the webmap here. I'm not sure if this is a bug or I have to re-write my code somehow. You can find the source code here.
Let me know what you think.
Thanks!
Sample taken from [https://www.mapbox.com/mapbox-gl-js/example/toggle-layers/] and modified
mapboxgl.accessToken = 'pk.eyJ1IjoiY2FtaWxhYW5kaW5vIiwiYSI6ImNqMWlhbnlubDAxNHIyd2xtanQwZmZ3NTkifQ.QypsX075VYyKWFYilxAfxA';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
zoom: 15,
center: [-71.97722138410576, -13.517379300798098]
});
map.on('load', function () {
map.addSource('museums', {
type: 'vector',
url: 'mapbox://mapbox.2opop9hr'
});
map.addSource('contours', {
type: 'vector',
url: 'mapbox://mapbox.mapbox-terrain-v2'
});
map.addLayer({
'id': 'contours',
'type': 'line',
'source': 'contours',
'source-layer': 'contour',
'layout': {
'visibility': 'visible',
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#877b59',
'line-width': 1
}
});
});
var toggleableLayerIds = [ 'contours', 'museums' ];
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = i==1 ? '' :'active';
link.textContent = id;
link.loaded = false;
link.onclick = function (e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
if(this.loaded === false){
this.loaded= true;
map.addLayer({
'id': 'museums',
'type': 'circle',
'source': 'museums',
'layout': {
'visibility': 'none'
},
'paint': {
'circle-radius': 8,
'circle-color': 'rgba(55,148,179,1)'
},
'source-layer': 'museum-cusco'
});
}
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
#menu {
background: #fff;
position: absolute;
z-index: 1;
top: 10px;
right: 10px;
border-radius: 3px;
width: 120px;
border: 1px solid rgba(0,0,0,0.4);
font-family: 'Open Sans', sans-serif;
}
#menu a {
font-size: 13px;
color: #404040;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0,0,0,0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #f8f8f8;
color: #404040;
}
#menu a.active {
background-color: #3887be;
color: #ffffff;
}
#menu a.active:hover {
background: #3074a4;
}
<html>
<head>
<meta charset='utf-8' />
<title>Show and hide layers</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<nav id="menu"></nav>
<div id="map"></div>
</body>
</html>
I'm trying to cause my Pie Chart in Charts.js (version 2.5) to highlight the appropriate slice when I hover over the corresponding legend item.
I have the following code which binds to the mouseover/mouseout events and calls my function, but I can not figure out how to highlight the appropriate slice.
// Function to bind mouseover/mouseout events
Chart.helpers.each(document.getElementById('legendID').firstChild.childNodes, function(legendNode, index) {
Chart.helpers.addEvent(legendNode, 'mouseover', function() {
highlightActiveSegment(myChart,index,true);
});
Chart.helpers.addEvent(legendNode, 'mouseleave', function() {
highlightActiveSegment(myChart,index,false);
});
});
// And the corresponding function highlightActiveSegment
function highlightActiveSegment(oChart,segmentIndex,highlight) {
var activeSegment = oChart.data.datasets[0]._meta[1].controller._data[segmentIndex];
window.chartAccidentsByRoadConditions.data.datasets[0]._meta[1].controller.setHoverStyle(activeSegment);
/*
if (highlight) {
oChart.data.datasets[0].controller.setHoverStyle(segmentIndex);
} else {
oChart.data.datasets[0].controller.removeHoverStyle(segmentIndex);
}
*/
}
Can someone show me PLEASE how to trigger the setHoverStyle and removeHoverStyle methods based on the legend item hovered over for ChartsJS 2.5
I have created a JSFiddle showing the problem. As you will see in the example, there are errors in the console when hovering over a legend item due to the showHoverStyle and removeHoverStyle not being defined. It would appear the ChartJS documentation that is currently online is not up-to-date.
Full Example
var chartAccidentsByRoadConditionsClasses = new Array();
chartAccidentsByRoadConditionsClasses[0] = "Dry";
chartAccidentsByRoadConditionsClasses[1] = "Not Available";
chartAccidentsByRoadConditionsClasses[2] = "Wet";
chartAccidentsByRoadConditionsClasses[3] = "Icy";
var chartAccidentsByRoadConditionsLabels = new Array();
chartAccidentsByRoadConditionsLabels[0] = "Dry";
chartAccidentsByRoadConditionsLabels[1] = "Not Available";
chartAccidentsByRoadConditionsLabels[2] = "Wet";
chartAccidentsByRoadConditionsLabels[3] = "Icy";
var chartAccidentsByRoadConditionsData = new Array();
chartAccidentsByRoadConditionsData[0] = 31;
chartAccidentsByRoadConditionsData[1] = 3;
chartAccidentsByRoadConditionsData[2] = 3;
chartAccidentsByRoadConditionsData[3] = 1;
var dataAccidentsByRoadConditions = {
labels: chartAccidentsByRoadConditionsLabels,
datasets: [{
data: chartAccidentsByRoadConditionsData,
backgroundColor: [ "#82a8c3","#b24339","#053454","#77954b" ],
hoverBackgroundColor: [ "#7597AF","#A03C33","#042E4B","#6B8643" ]
}]
};
$(document).ready(function() {
var canvasAccidentsByRoadConditions = document.getElementById("chart-AccidentsByRoadConditions").getContext("2d");
var chartAccidentsByRoadConditions = new Chart(canvasAccidentsByRoadConditions, {
type: 'pie',
data: dataAccidentsByRoadConditions,
options: {
tooltips: {
enabled: false
},
legend: {
display:false
},
legendCallback: function(chart) {
var text = [];
text.push('<ul>');
for (var i=0; i<chart.data.datasets[0].data.length; i++) {
text.push('<li>');
text.push('<div class="legendValue"><span style="background-color:' + chart.data.datasets[0].backgroundColor[i] + '">');
text.push(chart.data.datasets[0].data[i] + '</span></div>');
text.push('<div class="legendLabel">');
if (chart.data.labels[i]) { text.push('<p class="label">' + chart.data.labels[i] + '</p>'); }
if (chart.data.datasets[0].data[i]) {
text.push('<p class="percentage">' + chartValueToPercentage(chart.data.datasets[0].data[i],chartAccidentsByRoadConditions.getDatasetMeta(0).total) + '</p>');
}
text.push('</li>');
}
text.push('</ul>');
return text.join("");
}
}
});
// Create our legend
$('#legend-AccidentsByRoadConditions').prepend(chartAccidentsByRoadConditions.generateLegend());
// Bind our "Break-Out" Chart function
$('#chart-AccidentsByRoadConditions').on('mousemove mouseout',function(e){
var activeSegment = chartAccidentsByRoadConditions.getElementAtEvent(e);
pieChartHoverBreakout(this,activeSegment,e);
});
// Tie the legend to the chart tooltips
Chart.helpers.each(document.getElementById('legend-AccidentsByRoadConditions').firstChild.childNodes, function(legendNode, index) {
Chart.helpers.addEvent(legendNode, 'mouseover', function() {
highlightActiveSegment(chartAccidentsByRoadConditions,index,true);
});
Chart.helpers.addEvent(legendNode, 'mouseleave', function() {
highlightActiveSegment(chartAccidentsByRoadConditions,index,false);
});
});
});
function chartValueToPercentage(value,total) {
return Math.floor(((value/total)*100)+0.5) + '%';
}
// Function breakout the active "legend item" PieCharts
currentBreakoutIndex = null;
function pieChartHoverBreakout(oChart, activeSegment, eventType) {
try {
// First, remove any existing classes with "breakout" from the legend
var legend = ($(oChart).parent('.chartContainer').find('.legend'));
var segmentIndex = (activeSegment.length && (typeof activeSegment[0]._index != 'undefined' && activeSegment[0]._index !== null)) ? activeSegment[0]._index : -1;
var breakout = (eventType.type === 'mousemove') ? true : false;
if (currentBreakoutIndex != segmentIndex) {
$.each(legend.find('li'), function(index,value) {
$(this).removeClass('breakout');
});
// Second, if we have a valid segment index and breakout is true
// we add the breakout class to the corresponding li in the legend
if (breakout && segmentIndex >= 0) {
currentBreakoutIndex = segmentIndex;
var targetSegment = legend.find('li').get(segmentIndex);//
$(targetSegment).addClass('breakout');
} else {
currentBreakoutIndex = null;
}
}
} catch(e) {
// Nothing - just prevent errors in console
console.log(e);
}
}
function highlightActiveSegment(oChart,segmentIndex,highlight) {
var activeSegment = oChart.data.datasets[0]._meta[0].controller._data[segmentIndex];
if (highlight) {
oChart.data.datasets[0].controller.setHoverStyle(activeSegment);
} else {
oChart.data.datasets[0].controller.removeHoverStyle(activeSegment);
}
}
#dashboardWrapper h2 {
display:block;
text-align:left;
margin-bottom:0px;
margin-left: 20px;
margin: 5px 0px 20px 0px;
line-height: 1.2;
}
#dashboardWrapper .chart {
float:left;
width:50%;
vertical-align:middle;
display:inline-block;
width:50% !important;
height:100% !important;
}
#dashboardWrapper .legend {
float:left;
width:50%;
margin-bottom: 25px;
}
#dashboardWrapper .legendInfo {
background-color: #EBEBEB;
display: inline-block;
padding: 0px 10px 5px 10px;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
box-shadow: 0px 0px 5px #888;
}
#dashboardWrapper .legendInfo span {
display: block;
font-size: 12px;
margin-top: 5px;
}
#dashboardWrapper .chart
{
margin-bottom: 25px;
}
#dashboardWrapper .chartContainer { padding: 20px 0px; }
#dashboardWrapper .chartContainer ul {
background:none;
}
#dashboardWrapper .chartContainer li {
background:none;
margin:0;
padding:0;
border:none;
color: #666666;
font-size: 16px;
font-family: 'Source Sans Pro', sans-serif;
font-weight: 400;
list-style-type: none;
}
#dashboardWrapper .chartContainer li span {
background-color: #791b15;
height: 20px;
min-width: 20px;
padding: 2px 3px;
display: inline-block;
vertical-align: middle;
border-radius: 5px;
margin-right: 10px;
color:#FFF;
text-align:center;
font-size: 12px;
line-height: 18px;
text-shadow: 1px 1px 2px #000;
}
#dashboardWrapper div.legendValue { float:left; width:20%; }
#dashboardWrapper div.legendLabel { float:left; width:80%; }
#dashboardWrapper p.label {
display:inline-block;
margin:0;
margin-right:10px;
padding:0;
vertical-align:middle;
}
#dashboardWrapper p.percentage {
display:inline-block;
margin:0;
padding:0;
vertical-align:middle;
}
#dashboardWrapper .dashboardElement
{
display:inline-block;
min-height: 350px;
float: left;
padding: 0px 20px 0px 2%;
margin: 0px;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
}
#dashboardWrapper .chartContainer li
{
background: none;
margin: 0 0 0 0;
padding: 0px 0px 5px 0px;
border: none;
font-family: 'News Cycle', sans-serif;
font-size: 12px;
white-space: nowrap;
cursor:pointer;
float: right;
display: inline;
width: 94%;
}
.chartContainer .legend ul li {
position:relative;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
-o-transform-origin: 0 0;
-ms-transform-origin: 0 0;
-webkit-transition: all 0.3s;
-moz-transition: all 0.3s;
-ms-transition: all 0.3s;
-o-transition: all 0.3s;
transition: all 0.3s;
left:0px;
}
.chartContainer .legend ul li.breakout {
left:-10px;
}
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.5.0/Chart.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dashboardWrapper">
<div class="dashboardElement right">
<h2>Accidents by Road Conditions</h2>
<div class="chartContainer" style="position:relative;">
<canvas id="chart-AccidentsByRoadConditions" class="chart" width="200" height="150"></canvas>
<div id="legend-AccidentsByRoadConditions" class="legend"></div>
</div>
</div>
</div>
It looks like your highlightActiveSegment function and legend event handlers just has a few problems in it. Here is a corrected version with explanation.
Modified Legend Event Handlers
You need to use mousemove instead of mouseover so that the section stays highlighted as the user moves the mouse around.
Chart.helpers.each(document.getElementById('legend-AccidentsByRoadConditions').firstChild.childNodes, function(legendNode, index) {
Chart.helpers.addEvent(legendNode, 'mousemove', function() {
highlightActiveSegment(chartAccidentsByRoadConditions, index, true);
});
Chart.helpers.addEvent(legendNode, 'mouseleave', function() {
highlightActiveSegment(chartAccidentsByRoadConditions, index, false);
});
});
Modified highlightActiveSegment Function
Basically, the key is to make sure you get the actual segment of the graph represented by the moused over legend item, set the hover style accordingly and re-render the chart.
function highlightActiveSegment(oChart,segmentIndex,highlight) {
var activeSegment = oChart.data.datasets[0]._meta[0].data[segmentIndex];
oChart.updateHoverStyle([activeSegment], null, highlight);
oChart.render();
}
Also, here is a codepen showing the working solution.
color: [
{
backgroundColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
borderColor: 'rgba(255, 255, 255, 0)',
hoverBackgroundColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
hoverBorderColor: ['#92d06f', '#73c8b8', '#3bb9ab'],
hoverBorderWidth: 10,
hoverRadius: 0
}
],
on mouse over highlights the active segment in angular 2(ng-2 charts) for doughnut charts
I've been looking at previously posted StackOverflow questions, and still could not find my answer. So, I've been trying to simply delete the entire modal when I click on the close button. I can't get it to work, unfortunately. This is my code, so far.
var jQueryLoaded = 0;
function Modal(title, contents) {
if (jQueryLoaded === 1) {
var modal = document.createElement('div'),
modal_box = document.createElement('div'),
modal_head = document.createElement('div'),
modal_title = document.createElement('div'),
close_btn = document.createElement('div'),
modal_content = document.createElement('div');
modal.className = 'modal';
modal_box.className = 'modal_box';
modal_head.className = 'modal_head';
modal_title.className = 'modal_title';
modal_title.innerHTML = title;
close_btn.className = 'modal_close';
close_btn.innerHTML = '\u00D7';
modal_content.className = 'modal_content';
modal_content.innerHTML = contents;
$("body").append(modal);
$(modal).append(modal_box);
$(modal_box).append(modal_head, modal_content);
$(modal_head).prepend(modal_title);
$(modal_head).append(close_btn);
} else {
console.warn('jQuery, a required library, is not available at moment of function run. Please double check jQuery is loaded properly before running this function again.');
}
}
$(document).ready(function () {
jQueryLoaded = 1;
$("div.modal_close").on('click', function () {
$(this).parent().parent().closest('.modal').remove();
});
Modal('hello','<p>Example</p>');
});
/* Modals based off of W3Schools example! */
div.modal {
display: block;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background: rgba(0, 0, 0, 0.4);
font-family: 'Open Sans', sans-serif;
}
div.modal > div.modal_box {
background: #FFFFFF;
margin: auto;
padding: 5px;
border: 1px solid #000000;
width: 80%;
box-shadow: 3px 5px 3px rgba(0, 0, 0, 0.6);
}
div.modal > div.modal_box > div.modal_head {
width: 100%;
height: auto;
border: none;
border-radius: 0;
border-bottom: 1px solid #000000;
min-height: 10px;
font-weight: 16px;
}
div.modal > div.modal_box > div.modal_head > div.modal_title {
display: inline-block;
color: #000000;
text-align: center;
font-weight: 900;
font-size: 24px;
}
div.modal > div.modal_box > div.modal_head > div.modal_close {
margin: 1px;
font-weight: 900;
color: #000000;
border: 1px solid transparent;
padding: 2px;
border-radius: 5px;
background: transparent;
cursor: pointer;
float: right;
line-height: 10px;
user-select: none;
-webkit-user-select: none;
-o-user-select: none;
-k-user-select: none;
-moz-user-select: none;
}
div.modal > div.modal_box > div.modal_head > div.modal_close:hover,
div.modal > div.modal_box > div.modal_head > div.modal_close:focus {
border: 1px solid #000000;
background: rgba(0, 0, 0, 0.3);
}
div.modal > div.modal_box > div.modal_head > div.modal_close:active {
background: rgba(255, 0, 0, 0.8);
border: 1px solid #000000;
}
div.modal > div.modal_box > div.modal_content {
padding: 4px;
padding-left: 10px;
font-size: 16px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
Mind you, the code to remove the modal was just the last one I tried. I tried many others like $(this).parent().parent().closest('.modal').remove(); and $(this).parent().parent().find('.modal').remove().
You're mixing JS and jQuery, not that it's not good, but you use it in an inappropriate way. jQuery is designed to help you manipulate with DOM and events - make use of it!
If you're building a Modal function to handle modals, the close should be handled from within the script, not by adding extra stuff all around your .js files.
How do you call your Modal?
Here's an example to give you an idea and get you started:
jQuery(function ($) { // DOM is ready and $ alias secured
Modal("opened",{
title : "Opened example",
content : "<p>Immediately opened from JS using <code>.open()</code></p>"
}).open();
Modal("test1", {
title : "This is Title",
content :
`<p>
<b>Lorem Ipsum</b>
Dolor sit amet<br>
Example
</p>`
});
Modal("another", {
title: "Auto-hide in 3sec",
content: "<p>Like it? <b>Show some love</b></p>",
duration: 3000
});
});
/*QuickReset*/ *{margin:0;box-sizing:border-box;} html,body{height:100%;font:14px/1.4 sans-serif;}
[data-modal]{ color:blue; cursor:pointer; }
<h1>Modal Demo</h1>
Click <a data-modal="test1">here</a> to call modal ID test1<br>
or you can click <a data-modal="another">here</a> to call another modal
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
/** Modal - Custom modals example by RokoCB
* #param {String} modalId - A modal name used to reference a modal
* #param {Object} data - {title:"String", content:"HTML", duration:ms}
* #return {Object} - methods: .open() .close()
*/
function Modal(modalId, data) {
// DEFAULT MODAL STYLES
var css = {
area: {
position: "fixed",
visibility: "hidden",
opacity: 0,
left: 0,
top: 0,
right: 0,
bottom: 0,
zIndex: 99999,
background: "rgba(0,0,0,0.4)",
transition: "0.4s",
},
modal: {
position: "absolute",
left: "50%",
top: "50%",
minWidth: 240,
transform: "translate(-50%, -50%)",
background: "#fff",
boxShadow: "0 8px 24px rgba(0,0,0,0.6)",
},
title: {
padding: "8px 32px 8px 16px",
fontSize: 18,
borderBottom:"1px solid rgba(0,0,0,0.15)",
},
content: {
padding: "16px",
},
close: {
position: "absolute",
top: 4,
right: 4,
padding: 8,
cursor: "pointer",
userSelect: "none",
}
}
// ELEMENTS
var $area = $("<div/>", {
class: "modal_area",
appendTo: "body",
css: css.area,
click : closeModal,
});
var $modal = $("<div/>", {
class: "modal",
appendTo: $area,
css: css.modal,
click: function(evt){evt.stopPropagation();}
});
$("<div/>", {
class: "modal_title",
appendTo : $modal,
text : data.title,
css: css.title,
});
$("<div/>", {
class: "modal_content",
appendTo : $modal,
html : data.content,
css: css.content,
});
$("<div/>", {
class: "modal_close",
appendTo : $modal,
text : '\u00d7',
css: css.close,
click : closeModal,
});
// ACTIONS
var closeTimeout = null;
function closeModal() {
$area.removeClass("open").css({visibility:"hidden", opacity:0});
}
function openModal() {
$area.addClass("open").css({visibility:"visible", opacity:1});
if(data.duration) {
clearTimeout(closeTimeout);
closeTimeout = setTimeout(closeModal, data.duration);
}
}
$(document).on("click", "[data-modal='"+modalId+"']", openModal);
// METHODS
return {
open : openModal,
close : closeModal
}
}
</script>
The button will have no event listener attached to it because you're creating it after the attaching of the event listener. There is two solution for this:
EITHER:
Add the event listener just after the button is created inside the Modal class here:
close_btn.onclick = function() {
$(this).closest('.modal').remove();
}
OR:
Use event delegation like this:
$(document).on('click', 'div.modal_close', function () {
$(this).closest('.modal').remove();
});
NOTE: Since, as mentioned in the comments, you are already using jQuery why not using it inside the Modal class too.
I am creating the script to show the preview of uploaded image on client side with the option to remove it.
I have done all of this but the problem with the UI part the position of close icon is not top-right aligned.
Here is the code and the JSfiddle link, to test it on JSfiddle add the image by browse button.
jQuery(function($) {
$('div').on('click', '.closeDiv', function() {
$(this).prev().remove();
$(this).remove();
$('#upload-file').val("");
});
var fileInput = document.getElementById("upload-file");
fileInput.addEventListener("change", function(e) {
var filesVAR = this.files;
showThumbnail(filesVAR);
}, false);
function showThumbnail(files) {
var file = files[0]
var $thumbnail = $('#thumbnail').get(0);
var $image = $("<img>", {
class: "imgThumbnail"
});
var $pDiv = $("<div>", {
class: "divThumbnail",
style: "float: left"
});
var $div = $("<div>", {
class: "closeDiv",
style: "float: right"
}).html('X');
$pDiv.append($image, $div).appendTo($thumbnail);
var reader = new FileReader()
reader.onload = function(e) {
$image[0].src = e.target.result;
}
var ret = reader.readAsDataURL(file);
var canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
$image.on('load', function() {
ctx.drawImage($image[0], 100, 100);
})
}
});
img {
width: 30%;
float: left;
height: 100px;
width: 100px;
}
.closeDiv {
width: 20px;
height: 21px;
background-color: rgb(35, 179, 119);
float: left;
cursor: pointer;
color: white;
box-shadow: 2px 2px 7px rgb(74, 72, 72);
text-align: center;
margin: 5px;
}
.pDiv {
float: left;
width: 100%
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<div id="thumbnail"></div>
<input type="file" id="upload-file" accept="image/*" />
http://jsfiddle.net/r0taz01L/11/
You need to give
.divThumbnail {
position: relative;
}
and closeDiv to this style
.closeDiv {
position: absolute;
width: 20px;
height: 21px;
background-color: rgb(35, 179, 119);
float: right;
cursor: pointer;
color: white;
box-shadow: 2px 2px 7px rgb(74, 72, 72);
text-align: center;
margin: 5px;
right:0px;
}
here is completed solutions
http://jsfiddle.net/r0taz01L/12/