I have a small HTML-to-PDF which uses MigraDoc to produce PDF files. There seems to be a bug with adding formatted text to a paragraph. The problem is that underline formatting gets lost for all text on first page in a multipage PDF. Bold and Italic formatting stays preserved on all pages, but underline only shows starting from second page. Is it a known Migradoc bug?
Just to avoid further questions here is my code:
var textFormat = this.BuildTextFormat(isBold, isItalic, isUnderline);
var formattedText = paragraph.AddFormattedText(textFormat);
formattedText.Add(new Text(text));
private TextFormat BuildTextFormat(bool isBold, bool isItalic, bool isUnderline)
{
var textFormat = TextFormat.NoUnderline;
if (isUnderline)
{
textFormat = TextFormat.Underline;
}
if (isBold)
{
textFormat |= TextFormat.Bold;
}
if (isItalic)
{
textFormat |= TextFormat.Italic;
}
return textFormat;
}
UPDATE:
Just to let PdfSharp devs know, that although I solved the issue but I still cannot understand whether it was an implementation or library bug, or both. The problem was solved by changing definition of styles, and more precisely, font colours.
For the normal style we added a code similar to the following:
var style = document.Styles["Normal"];
style.Font.Color = Color.Parse("0x222222");
Then, other styles inherited from the normal style also could have fonts with different colours, also parsed from a Hexadecimal code.
The final fix was tiny, just making change to each parsed colour like this:
style.Font.Color = Color.Parse("0xFF222222");
Another way to solve the bug was to create a CMYK colour. As a separate issue, when doing that I also noticed that colour parsed with the above line and the CMYK-generated colour are slightly different, so the colour parser also seems to be buggy. Here I assume that the HEX colour 0x222222 should be same as CMYK(0,0,0,86.7).
The question is why the described fix solved the underline issue bug, and why the bug appeared only before page brake? Also, interestingly, when debugging this issue then I initially started to remove some pdf content and there was also a scenario when bug would disappear when certain tables were removed from the PDF document, which makes no sense to me.
In any case, thank you for letting me know how to create an mdddl file. It was helpful as it allowed me to test few things.
I cannot replicate a problem with MigraDoc.
Here's the code I added to the MigraDoc Hello World sample:
paragraph2 = section.AddParagraph();
var textFormat0 = BuildTextFormat(false, false, false);
var textFormat1 = BuildTextFormat(false, false, true);
var textFormat2 = BuildTextFormat(false, true, false);
var textFormat3 = BuildTextFormat(false, true, true);
var textFormat4 = BuildTextFormat(true, false, false);
var textFormat5 = BuildTextFormat(true, false, true);
var textFormat6 = BuildTextFormat(true, true, false);
var textFormat7 = BuildTextFormat(true, true, true);
var formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
paragraph2 = section.AddParagraph();
formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
section.AddPageBreak();
paragraph2 = section.AddParagraph();
formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
paragraph2 = section.AddParagraph();
formattedText = paragraph2.AddFormattedText(textFormat0);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat1);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat2);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat3);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat4);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat5);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat6);
formattedText.Add(new Text("Hello, World! "));
formattedText = paragraph2.AddFormattedText(textFormat7);
formattedText.Add(new Text("Hello, World! "));
This results in a PDF file with two pages and underlined text shows correctly on both pages.
Not a general problem - I should have waited for the SSCCE.
Related
What I'm trying to do is, created 2 markers (they are draggable), there will be grid between them, like http://prntscr.com/4nx9f3.
When I change one of the marker, grid should be changed. I am trying to draw with polylines. By the way i can not get latitude or longitute with marker1.getPosition().lat().
all my code:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var map;
var marker1;
var marker2;
function initialize() {
var mapOptions = {
zoom: 10,
center: new google.maps.LatLng(50.3, 44.3)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
marker1 = new google.maps.Marker({
position: new google.maps.LatLng(50.1, 44.1),
map: map,
draggable: true,
title: 'marker1 '
});
marker2 = new google.maps.Marker({
position: new google.maps.LatLng(50.5, 44.5),
map: map,
draggable: true,
title: 'marker2'
});
var flightPlanCoordinates = [
marker1.getPosition(),
marker2.getPosition(),
];
// code below is not working
/*
google.maps.event.addListener(marker1, 'dragend', function () {
polyline.LatLngBounds(new google.maps.LatLng(marker1.getPosition(), marker2.getPosition()));
});
google.maps.event.addListener(marker2, 'dragend', function () {
polyline.LatLngBounds(new google.maps.LatLng(marker1.getPosition(), marker2.getPosition()));
*/
var polyline = new google.maps.Polyline(
{ path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
var lat1 = marker1.getPosition().lat();
var lng1 = marker1.getPosition().lng();
var lat2 = marker2.getPosition().lat();
var lng2 = marker2.getPosition().lng();
// I tried to get distance between 2 markers but it did not work either
/* function distance(
lat1,
lng1,
lat2,
lng2
) {
var R = 6371;
var a =
0.5 - Math.cos((lat2 - lat1) * Math.PI / 180) / 2 +
Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
(1 - Math.cos((lon2 - lon1) * Math.PI / 180)) / 2;
return R * 2 * Math.asin(Math.sqrt(a));
}
*/
polyline.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
I think this is what you are trying to do. Changed your rectangleLng array to a two dimensional array and changed the excLat/excLng variables to not be rounded (they were backwards as well extLat wants to be up/down, excLng should be side to side).
proof of concept fiddle
code snippet:
var map;
var marker1;
var marker2;
var rectangle;
var infowindow = new google.maps.InfoWindow();
function initialize() {
var mapOptions = {
zoom: 11,
center: new google.maps.LatLng(38.4, 26.7)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
marker1 = new google.maps.Marker({
position: new google.maps.LatLng(38.3, 26.6),
map: map,
draggable: true,
title: 'marker1'
});
google.maps.event.addListener(marker1, 'click', function(evt) {
infowindow.setContent(marker1.getPosition().toUrlValue(6));
infowindow.open(map, this);
});
marker2 = new google.maps.Marker({
position: new google.maps.LatLng(38.5, 26.8),
map: map,
draggable: true,
title: 'marker2'
});
google.maps.event.addListener(marker2, 'click', function(evt) {
infowindow.setContent(marker1.getPosition().toUrlValue(6));
infowindow.open(map, this);
});
rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: new google.maps.LatLngBounds(
marker1.getPosition(),
marker2.getPosition())
});
var leftSideDist = Math.round((marker2.getPosition().lng() - marker1.getPosition().lng()) * 10000) / 100;
var belowSideDist = Math.round((marker2.getPosition().lat() - marker1.getPosition().lat()) * 10000) / 100;
google.maps.event.addListener(marker1, 'dragend', function() {
rectangle.setBounds(new google.maps.LatLngBounds(marker1.getPosition(), marker2.getPosition()));
leftSideDist = Math.round((marker2.getPosition().lng() - marker1.getPosition().lng()) * 10000) / 100;
makeGrid();
});
google.maps.event.addListener(marker2, 'dragend', function() {
rectangle.setBounds(new google.maps.LatLngBounds(marker1.getPosition(), marker2.getPosition()));
belowSideDist = Math.round((marker2.getPosition().lat() - marker1.getPosition().lat()) * 10000) / 100;
makeGrid();
});
makeGrid();
}
var rectangleLat = [];
var rectangleLng = [];
function makeGrid() {
for (x in rectangleLng) {
for (y in rectangleLng[x]) {
if (rectangleLng[x][y].setMap) {
rectangleLng[x][y].setMap(null)
rectangleLng[x][y] = null;
}
}
}
var leftSideDist = marker2.getPosition().lng() - marker1.getPosition().lng();
var belowSideDist = marker2.getPosition().lat() - marker1.getPosition().lat();
var dividerLat = 5;
var dividerLng = 5; //ilerde kullanıcıdan alınacak
var excLat = belowSideDist / dividerLat;
var excLng = leftSideDist / dividerLng;
var m1Lat = marker1.getPosition().lat();
var m1Lng = marker1.getPosition().lng();
var m2Lat = marker2.getPosition().lat();
var m2Lng = marker2.getPosition().lng();
document.getElementById('info').innerHTML += "dividerLat=" + dividerLat + ", excLat=" + excLat + "<br>";
document.getElementById('info').innerHTML += "dividerLng=" + dividerLat + ", excLng=" + excLng + "<br>";
document.getElementById('info').innerHTML += "m1=" + marker1.getPosition().toUrlValue(6) + "<br>";
document.getElementById('info').innerHTML += "m2=" + marker2.getPosition().toUrlValue(6) + "<br>";
for (var i = 0; i < dividerLat; i++) {
if (!rectangleLng[i]) rectangleLng[i] = [];
for (var j = 0; j < dividerLng; j++) {
if (!rectangleLng[i][j]) rectangleLng[i][j] = {};
rectangleLng[i][j] = new google.maps.Rectangle({
strokeColor: '#FFFFFF',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.1,
map: map,
bounds: new google.maps.LatLngBounds(
new google.maps.LatLng(m1Lat + (excLat * i), m1Lng + (excLng * j)),
new google.maps.LatLng(m1Lat + (excLat * (i + 1)), m1Lng + (excLng * (j + 1))))
});
document.getElementById('info').innerHTML += "[i=" + i + ",j=" + j + "]:" + rectangleLng[i][j].getBounds() + "<br>";
} //for j Lng
} //for i Lat
document.getElementById('left').value = leftSideDist;
document.getElementById('blw').value = belowSideDist;
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
/* border: 1px solid #999;*/
}
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
<div id="map-canvas"></div>
<div id="panel" style="margin-left:-320px">leftSideDist:
<input type="text" readonly id="left">belowSideDist:
<input type="text" readonly id="blw">
</div>
<div id="info"></div>
To get the coordinates of the marker after it's been dragged, change:
google.maps.event.addListener(marker1, 'dragend', function() {
polyline.LatLngBounds(new google.maps.LatLng(marker1.getPosition(), marker2.getPosition()));
});
to:
google.maps.event.addListener(marker1, 'dragend', function(event) {
polyline.LatLngBounds(event.latLng);
});
However, there is no LatLngBounds function on the polyline object.
As far as i done:
<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?
sensor=false&v=3&libraries=geometry"></script>
<script>
var map;
var marker1;
var marker2;
var rectangle;
function initialize() {
var mapOptions = {
zoom: 11,
center: new google.maps.LatLng(38.4, 26.7)
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
marker1 = new google.maps.Marker({
position: new google.maps.LatLng(38.3, 26.6),
map: map,
draggable: true,
title: 'marker1'
});
marker2 = new google.maps.Marker({
position: new google.maps.LatLng(38.5, 26.8),
map: map,
draggable: true,
title: 'marker2'
});
rectangle = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: new google.maps.LatLngBounds(
marker1.getPosition(),
marker2.getPosition())
});
var leftSideDist = Math.round((marker2.getPosition().lng() - marker1.getPosition().lng()) * 10000) / 100;
var belowSideDist = Math.round((marker2.getPosition().lat() - marker1.getPosition().lat()) * 10000) / 100;
google.maps.event.addListener(marker1, 'dragend', function () {
rectangle.setBounds(new google.maps.LatLngBounds(marker1.getPosition(), marker2.getPosition()));
leftSideDist = Math.round((marker2.getPosition().lng() - marker1.getPosition().lng()) * 10000) / 100;
});
google.maps.event.addListener(marker2, 'dragend', function () {
rectangle.setBounds(new google.maps.LatLngBounds(marker1.getPosition(), marker2.getPosition()));
belowSideDist = Math.round((marker2.getPosition().lat() - marker1.getPosition().lat()) * 10000) / 100;
});
var leftSideDist = Math.round((marker2.getPosition().lng() - marker1.getPosition().lng()) * 10000) / 100;
var belowSideDist = Math.round((marker2.getPosition().lat() - marker1.getPosition().lat()) * 10000) / 100;
var dividerLat = 5;
var dividerLng = 5; //ilerde kullanıcıdan alınacak
var excLat = leftSideDist / dividerLat;
var excLng = belowSideDist / dividerLng;
var rectangleLat[];
var rectangleLng[];
var m1Lat = marker1.getPosition().lat();
var m1Lng = marker1.getPosition().lng();
var m2Lat = marker2.getPosition().lat();
var m2Lng = marker2.getPosition().lng();
for (var i = 0; i < dividerLat; i++) {
for (var j = 0; j < dividerLng; j++) {
rectangleLng[i*5+j] = new google.maps.Rectangle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35,
map: map,
bounds: new google.maps.LatLngBounds(
( m1Lat , (excLng*(j+1) ) ),
( m1Lat+excLat, m2Lng+(excLng*(j+1) ) ) )
});
}//for j Lng
}//for i Lat
document.getElementById('left').value = leftSideDist;
document.getElementById('blw').value = belowSideDist;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
<div id="panel" style="margin-left:-320px">
leftSideDist: <input type="text" readonly id="left">
belowSideDist: <input type="text" readonly id="blw">
</div>
</body>
</html>
When zooming in, all features disappear. The features are on either side of the antimeridian. In order to be able to use modify interaction, the geographical lengths of some features exceed the value of 180 degrees.
Any help is welcome!
var coords = [
[32100000, -7900000],
[28900000, -9700000],
[26300000, -10000000],
[23800000, -9300000],
[20400000, -6500000]
];
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var featuresLayer = new ol.layer.Vector({
source: new ol.source.Vector()
});
var map = new ol.Map({
layers: [osmLayer, featuresLayer],
target: document.getElementById("map")
});
var s = featuresLayer.getSource();
for (var i = 0; i < coords.length; i++) {
s.addFeature(new ol.Feature({
geometry: new ol.geom.Point(coords[i])
}));
}
map.setView(new ol.View({
center: coords[parseInt(coords.length / 2)],
zoom: 3,
maxZoom: 18,
minZoom: 3
}));
html,
body,
.map {
width: 100%;
height: 100%;
overflow: hidden;
}
<link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/css/ol.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/build/ol.js"></script>
<div id="map" class="map"></div>
Per #Mike's comment, use new ol.source.Vector({wrapX: false}) if your coordinates exceed the normal world
var featuresLayer = new ol.layer.Vector({
source: new ol.source.Vector({wrapX: false})
});
updated code snippet:
var coords = [
[32100000, -7900000],
[28900000, -9700000],
[26300000, -10000000],
[23800000, -9300000],
[20400000, -6500000]
];
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var featuresLayer = new ol.layer.Vector({
source: new ol.source.Vector({wrapX: false})
});
var map = new ol.Map({
layers: [osmLayer, featuresLayer],
target: document.getElementById("map")
});
var s = featuresLayer.getSource();
for (var i = 0; i < coords.length; i++) {
s.addFeature(new ol.Feature({
geometry: new ol.geom.Point(coords[i])
}));
}
map.setView(new ol.View({
center: coords[parseInt(coords.length / 2)],
zoom: 3,
maxZoom: 18,
minZoom: 3
}));
html,
body,
.map {
width: 100%;
height: 100%;
overflow: hidden;
}
<link href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/css/ol.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/build/ol.js"></script>
<div id="map" class="map"></div>
I am using webamp to show the map created in ArcGIS (Javascript API in PHP website). In the map, a popup also appears when clicking on the layer's points. Recently I have updated the version 4.14 from 4.13. After updating it, the popup is not working properly. I have a custom popup template. After research in the documentation, I came to know there required a return function to show the custom div on the popup. The below code I have added to show my custom popups.
var template = { content: function(){ var div = document.createElement("div"); div.className = "myClass"; div.innerHTML = "<span>My custom content!</span>"; return div; } }
layers[layerIndex].popupTemplate = template;
Now the popup appears fine. But I have to show the field values on the popup. I have used the required field attributes in double brackets eg: {Name}. But in the latest version, the field values are not appearing when I used the same.
The code I have used in version 4.13 and it was working,
popupTemplate = {
title: "{Name}",
content: '<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>' };
layers[layerIndex].popupTemplate = popupTemplate;
Please help me to fix this issue.
Thanks.
The complete code for the Webmap and custom popup
map.js
// The map classes and includ1a65d527bfd04cc180c87edf0908907bes
require([
"esri/views/MapView",
"esri/WebMap",
"esri/widgets/Search",
"esri/widgets/Zoom",
"esri/widgets/Locate"
], function(MapView, WebMap, Search, Zoom, Locate) {
var webmap = new WebMap({
portalItem: {
id: "d1ca798d8c7d4afab8983d911df8326b"
}
});
var view = new MapView({
map: webmap,
container: "map",
center: [-95.9406, 41.26],
zoom: 16,
maxZoom: 21,
minZoom: 13,
basemap: "topo",
ui: {
components: ["attribution"]
}
});
webmap
.load()
.then(function() {
return webmap.basemap.load();
})
.then(function() {
let allLayers = webmap.allLayers;
console.log(allLayers);
var promises = allLayers.map(function(layer) {
return layer.load();
});
return Promise.all(promises.toArray());
})
.then(function(layers) {
// Position of the popup in relation to the selected feature.
view.popup.alignment = "top-center";
// To disable the collapse functionality
view.popup.collapseEnabled = false;
// A spinner appear at the pointer
view.popup.spinnerEnabled = false;
// To disable the dock (The popup will be appear in bottom or any corner of the window)
view.popup.dockEnabled = false;
// Disable the pagination
view.popup.featureNavigationEnabled = false;
// Popup template details, Keep only name and address in the popup and avoid all other details
view.popup.viewModel.actions.getItemAt(0).visible = false;
// view.on("click", function(event) {
// keep a delay to align the popup and the pointer together positioned to the map center
// Add animation only if the browser not IE
// });
layers.forEach(function(popupLayers, layerIndex) {
console.log(popupLayers);
var template = {
title: "{Name}",
content: function() {
var div = document.createElement("div");
div.className = "myClass";
div.innerHTML = "<span>{Address}</span>";
return div;
}
};
layers[layerIndex].popupTemplate = template;
// popupTemplate = {
// title: "{Name}",
// content:
// '<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>'
// };
// layers[layerIndex].popupTemplate = popupTemplate;
});
// To close the popup when hit on esc button
document.onkeyup = function(evt) {
var key = evt.keyCode;
if (key == 27) {
view.popup.close();
}
};
})
.catch(function(error) {
// console.log(error);
});
});
Index.php
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Load a basic WebMap - 4.14</title>
<style>
html,
body,
#map {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.14/"></script>
<script src="map.js"></script>
</head>
<body>
<div id="map"></div>
</body>
</html>
I have modified the code,
for (let i = 2; i < layers.length; i++) {
var template = {
title: "{Name}",
content: function() {
var div = document.createElement("div");
div.innerHTML =
'<div id="popup_address">{Address}</div><div class="right"><div href="#" id="popupRight" class="toggle"><p onClick="openPopupDetails({FACILITYID})">+</p></div></div>';
return div;
}
};
layers[i].popupTemplate = template;
console.log(layer[i]);
}
When I apply custom div, the {Address} part is not rendering. It appears like {Address} itself.
I think you are a bit confuse, you still can use a string, or you can use a function for the content of the popup template. So if you want to use a function, you can use something like this,
popupTemplate = {
title: "{Name}",
content: popupContentChange
}
layers[layerIndex].popupTemplate = template;
function popupContentChange(feature) {
let div = document.createElement("div");
div.className = "myClass";
div.innerHTML = "<span>"+feature.graphic.attributes.Address+"</span>";
return div;
}
There are several examples in the API documentation, take a look there. Just to reference one, ArcGIS JavaScript API Examples - Intro to Popups
Here an example I made for you taking your code as base adding some fixes to display what you want.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Sketch Feature Coords</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.14/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.14/"></script>
<style>
html,
body,
#map {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
require([
"esri/views/MapView",
"esri/WebMap",
"esri/widgets/Search",
"esri/widgets/Zoom",
"esri/widgets/Locate"
], function(MapView, WebMap, Search, Zoom, Locate) {
var webmap = new WebMap({
portalItem: {
id: "d1ca798d8c7d4afab8983d911df8326b"
}
});
var view = new MapView({
map: webmap,
container: "map",
center: [-95.9406, 41.26],
zoom: 16,
maxZoom: 21,
minZoom: 13,
basemap: "topo",
ui: {
components: ["attribution"]
}
});
webmap
.load()
.then(function() {
return webmap.basemap.load();
})
.then(function() {
let allLayers = webmap.allLayers;
console.log(allLayers);
var promises = allLayers.map(function(layer) {
return layer.load();
});
return Promise.all(promises.toArray());
})
.then(function(layers) {
// Position of the popup in relation to the selected feature.
view.popup.alignment = "top-center";
// To disable the collapse functionality
view.popup.collapseEnabled = false;
// A spinner appear at the pointer
view.popup.spinnerEnabled = false;
// To disable the dock (The popup will be appear in bottom or any corner of the window)
view.popup.dockEnabled = false;
// Disable the pagination
view.popup.featureNavigationEnabled = false;
// Popup template details, Keep only name and address in the popup and avoid all other details
view.popup.viewModel.actions.getItemAt(0).visible = false;
// it is only going to work on the last two layers
// those are the one that have fields: Name and Address
for (let i = 2; i < layers.length; i++) {
var template = {
title: "{Name}",
content: "<span>Address: {Address}</span>"
};
layers[i].popupTemplate = template;
console.log(layer[i]);
}
// To close the popup when hit on esc button
document.onkeyup = function(evt) {
var key = evt.keyCode;
if (key == 27) {
view.popup.close();
}
};
})
.catch(function(error) {
console.log(error);
});
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
If you want to use a function as content, you have to set the outFields parameter to include the fields you want to use in the function. The selected feature is pass as a parameter to the function, and inside you use feature.graphic.attributes to access the attributes. This should work,
var template = {
title: "{Name}",
// content: "<span>Address: {Address}</span>"
content: function(feature) {
console.log(feature);
var div = document.createElement("div");
div.className = "myClass";
div.innerHTML = "<span>Address:"+feature.graphic.attributes.Address+"</span>";
return div;
},
outFields: ["Name", "Address"]
};
featureNavigationEnabled is deprecated as of version 4.15. Use Popup.visibleElements.featureNavigation instead.
https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#featureNavigationEnabled
I’ve created a graph with echarts and want to include it to a pdf by using jspdf. I found that one way to do so might be to use canvas, transfer the graph to an image and finally include the image to the pdf. However, I fail to transfer the graph to an image. Here comes the code:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Balken</title>
<script src="echarts.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.4/jspdf.debug.js"></script>
<div id="body">
<div id="chart"></div>
</div>
<!-- prepare a DOM container with width and height -->
<div id="main" style="width: 750px; height: 500px"></div>
<script type="text/javascript">
// based on prepared DOM, initialize echarts instance
var myChart = echarts.init(document.getElementById('main'));
// specify chart configuration item and data
var option = {
color: ['#3398DB'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Salami',
type: 'bar',
barWidth: '60%',
data: [10, 52, 200, 334, 390, 330, 220]
}
]
};
// use configuration item and data specified to show chart
myChart.setOption(option);
var canvas = document.getElementById('main');
var dataURL = canvas.toDataURL();
//console.log(dataURL);
$('#exportButton').click(function () {
var pdf = new jsPDF();
pdf.addImage(dataURL, 'JPEG', 0, 0);
pdf.save('download.pdf');
});
</script>
<button id="exportButton" type="button">Export as PDF</button>
</body>
</html>
Any suggestions?
I needed this as well for a commercial product, so I did not give up until I found the solution.
You cannot use the ID of the chart to get the URL for the image, instead you need to search for the canvas.
($('canvas')[0]).toDataURL("image/png");
Notice the "[0]" means it will give your the first canvas, if you have more charts just do:
($('canvas')[0]).toDataURL("image/png");
($('canvas')[1]).toDataURL("image/png");
($('canvas')[2]).toDataURL("image/png");
3 Hours of searching and testing well spent :)
Enjoy!
I would use the toolbox, save as image:
.....
toolbox: {
feature: {
saveAsImage : {show: true}
}
}
.....
This option, among all the existing ones, will show you an icon to save the graphic as an image.
Quedaria así:
enter image description here
For more options with toolbox: http://echarts.baidu.com/echarts2/doc/option-en.html#title~toolbox
I hope it helps you.
You have to import "html2canvas" in order to make this work.
Html2canvas library will get the snapshot and that image should be written to the pdf with jspdf.
I have created a pen for this.
$("#exportButton").click(function(){
html2canvas($("#main"), {
onrendered: function(canvas) {
var dataURL=canvas.toDataURL('image/jpeg');
var pdf = new jsPDF();
pdf.addImage(dataURL, 'JPEG', 0, 0);
pdf.save("download.pdf");
}
});
});
Echart code:
<ReactEcharts
ref={(e) => {
this.echarts_react = e;
}}
option={option}
notMerge
lazyUpdate
/>
Function:
saveAsImage = (uri, name = 'undefine.jpeg') => {
var link = document.createElement('a');
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
};
saveAsPDF = (uri, name = 'undefine.pdf') => {
let height = echartsInstance.getHeight();
let width = echartsInstance.getWidth();
var doc = '';
if (width > height) {
doc = new jsPDF('l', 'mm', [width, height]);
} else {
doc = new jsPDF('p', 'mm', [height, width]);
}
doc.addImage(echartsInstance.getDataURL({ backgroundColor: '#fff' }), 'JPEG', 10, 10);
doc.save(name);
};
function call:
<li className="nav-item inline dropdown">
<span className="nav-link" data-toggle="dropdown">
<i className="fa fa-download" />
</span>
<div className="dropdown-menu dropdown-menu-scale pull-right">
<span
className="dropdown-item"
onClick={() =>
this.saveAsImage(this.echarts_react.getEchartsInstance().getDataURL({ backgroundColor: '#fff' }))
}>
Save as Image
</span>
<span
className="dropdown-item"
onClick={() =>
this.saveAsPDF(this.echarts_react.getEchartsInstance().getDataURL({ backgroundColor: '#fff' }))
}>
Save as PDF
</span>
</div>
</li>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.2.61/jspdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-beta1/html2canvas.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-beta1/html2canvas.svg.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/amstockchart/3.13.0/exporting/rgbcolor.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/canvg/1.5/canvg.min.js"></script>
<script type="text/javascript">
// $("#list1").on("click",function(){
$("#list1").click(function(){
$("#row").html(option);
var imgData;
var svgElements = $("#row").find('svg');
//replace all svgs with a temp canvas
svgElements.each(function() {
var canvas, xml;
// canvg doesn't cope very well with em font sizes so find the calculated size in pixels and replace it in the element.
$.each($(this).find('[style*=em]'), function(index, el) {
$(this).css('font-size', getStyle(el, 'font-size'));
});
canvas = document.createElement("canvas");
canvas.className = "screenShotTempCanvas";
//convert SVG into a XML string
xml = (new XMLSerializer()).serializeToString(this);
// Removing the name space as IE throws an error
xml = xml.replace(/xmlns=\"http:\/\/www\.w3\.org\/2000\/svg\"/, '');
//draw the SVG onto a canvas
canvg(canvas, xml);
$(canvas).insertAfter(this);
//hide the SVG element
////this.className = "tempHide";
$(this).attr('class', 'tempHide');
$(this).hide();
});
/* html2canvas($("#row"), {
onrendered: function(canvas) {
var imgData = canvas.toDataURL(
'image/png');
var doc = new jsPDF('p', 'mm');
doc.addImage(imgData, 'PNG', 10, 10);
doc.save('sample-file.pdf');
}
});*/
var imgData;
html2canvas($("#row"), {
useCORS: true,
'allowTaint': true,
onrendered: function (canvas) {
imgData = canvas.toDataURL(
'image/jpeg', 1.0);
canvaswidth1=canvas.width/2;
canvasheight1=canvas.height/4;
currentHeight = $("#row").height();
currentHeight2=currentHeight/2;
var imgWidth = 200;
var pageHeight = 260;
var imgHeight = canvas.height * imgWidth / canvas.width;
var heightLeft = imgHeight;
var doc = new jsPDF('p', 'm`enter code here`m','a4');
var position = 35;
doc.setFillColor(52,73,94);
doc.rect(5, 5, 200, 25, "F");
doc.setFontSize(40);
doc.setTextColor(255, 255, 255);
doc.text(80, 23, "Fitview");
doc.addImage(imgData, 'JPEG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
while (heightLeft >= 0) {
position = heightLeft - imgHeight;
doc.addPage();
doc.addImage(imgData, 'JPEG', 5, position, imgWidth, imgHeight);
heightLeft -= pageHeight;
}
doc.save('healthcheck_Rapportage.pdf');
location.reload();
}
});
$("#row").find('.screenShotTempCanvas').remove();
$("#row").find('.tempHide').show().removeClass('tempHide');
});
</script>
Can you please take a look at this JSFiddle and let me know why I am not able to add the Market into the Map? I am getting this error
Uncaught TypeError: Cannot read property 'add' of null
Here is the ode I have
var map;
var graphicsArray = [];
require(["esri/map",
"esri/geometry/Geometry",
"esri/geometry/Point",
"esri/geometry/Polyline",
"esri/geometry/Polygon",
"esri/graphic",
"esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/Color",
"esri/InfoTemplate",
"dojo/domReady!",
"esri/geometry"], function (Map,
Geometry,
Point,
Polyline,
Polygon,
Graphic,
SimpleMarkerSymbol,
SimpleLineSymbol,
SimpleFillSymbol,
Color,
InfoTemplate) {
map = new Map("map", {
basemap: "topo",
center: [-106.61, 35.1107],
zoom: 13
});
var point = new Point(-106.61, 35.1107);
var pointSymbol = new SimpleMarkerSymbol();
var pointAttributes = { city: "Albuquerque", state: "New Mexico" };
var pointInfoTemplate = new InfoTemplate("Albuquerque");
var pointGraphic = new Graphic(point, pointSymbol, pointAttributes).setInfoTemplate(pointInfoTemplate);
graphicsArray.push(pointGraphic);
for (i = 0; i < graphicsArray.length; ++i) {
map.graphics.add(graphicsArray[i]);
}
});
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family:"Trebuchet MS";
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">
<script src="http://js.arcgis.com/3.14/"></script>
<div id="map"></div>
You are trying to add this point when the map isn't fully loaded.
So just wait for the map to be fully loaded and then add the point, by wrapping your loop inside this function:
map.on('load', function() {
console.log('load event called');
for (i = 0; i < graphicsArray.length; ++i) {
map.graphics.add(graphicsArray[i]);
}
});
ESRI has a small documentation on how to work with events here