How to highlight cell in Anychart table when I click on that cell - anychart

Is there any way to highlight a cell in an Anychart table when I click on the cell?
I tried the following code, but it doesn't work.
table.listen("click",function(e){e.cellBorder(" #ff0000")});

Unfortunately, the current version of AnyChart 8.2.1 tables does not support events. But you can implement this functionality with some extra code. For details, please, check the sample below.
anychart.onDocumentReady(function () {
// set stage
var stage = anychart.graphics.create("container");
// create table
var table = anychart.standalones.table();
// set table content
table.contents([
[
null,
"2003 Sales",
"2004 Sales"
],[
"January",
"$10000",
"$12000"
],[
"February",
"$12000",
"$15000"
],[
"March",
"$18000",
"$16000"
],[
"April",
"$11000",
"$15000"
],
[
"May",
"$9000",
"$14000"
]
]);
var contents = table.contents();
// Set rows height.
table.rowsHeight(70);
table.getRow(0).fontWeight(900);
table.getCol(0).width(70).fontWeight(900); // Set first column width 70 px and bold the text
table.getCol(1).width(300);
table.getCol(2).width(300);
table.cellFill("#E1E1E1"); // Set table background color
// adjust table border and position text in each cell into center
table.cellBorder("#B8B8B8").vAlign("middle").hAlign("center");
// set table container and initiate draw
table.container(stage).draw();
var colsCount = table.colsCount();
var widths = [];
for(var i = 0; i<colsCount;i++) {
var width = table.getCol(i).width();
widths.push(width);
}
var rowHeight = table.rowsHeight();
// buffer cell
var buffer = 0;
var cont = document.getElementById('container');
cont.addEventListener('click', function(e) {
var x = e.clientX;
var y = e.clientY;
var indX = null;
var indY = null;
if(x < widths[0]) {
indX = 0;
}
if(x> widths[0] && x<widths[0] + widths[1]) {
indX = 1;
}
if(x > widths[0] + widths[1]) {
indX = 2;
}
indY = Math.floor(y / rowHeight);
// color selected cell
if (contents[indY]) {
table.getCell(indY,indX).fill("#0000ff", 0.2);
}
// color back
if (buffer !=0) {
buffer.fill("#e1e1e1")
}
// save selected cell to buffer
if (contents[indY]) {
buffer = table.getCell(indY,indX);
}
});
});
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<link href="https://cdn.anychart.com/releases/8.2.1/css/anychart-ui.min.css" rel="stylesheet"/>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-table.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-ui.min.js"></script>
<div id="container"></div>

Related

Contour line data to DEM data

I was just wondering if there was a way to use the free ordnance survey contour line data and generate DEM data using it. I’ve seen plenty of people converting DEM data to contour line data but not the other way around, could anyone help me out here?
I would also add more relevant tags to this question, though I do not have the reputation, nor do the tags exist
OS Terrain 50 is available as ASCII grid as well as contours. This OpenLayers example reads the unzipped ASCII files directly to produce a single zoom level EPSG:27700 tiled DEM (using the Mapbox RGB encoding method), but you could use similar logic in VB to create and save a PNG tile grid.
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/css/ol.css" type="text/css">
<style>
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.map {
width: 100%;
height: calc(100% - 20px);
}
</style>
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v6.5.0/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.0/proj4.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<div>
<label>
Elevation
<span id="info">0.0</span> meters
</label>
</div>
<script type="text/javascript">
proj4.defs('EPSG:27700', '+proj=tmerc +lat_0=49 +lon_0=-2 +k=0.9996012717 +x_0=400000 +y_0=-100000 +ellps=airy +datum=OSGB36 +units=m +no_defs ');
ol.proj.proj4.register(proj4);
var canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
var ctx = canvas.getContext('2d');
var imgData = ctx.createImageData(200, 200);
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
projection: 'EPSG:27700',
tileGrid: new ol.tilegrid.TileGrid({
tileSize: 200,
resolutions: [50],
extent: [0, 0, 700000, 1300000],
origin: [0, 0]
}),
crossOrigin: '',
imageSmoothing: false,
tileUrlFunction: function (tileCoord, pixelRatio, projection) {
var bounds = this.getTileGrid().getTileCoordExtent(tileCoord);
var x = (Math.round(bounds[0]/10)/10) + 10000;
var y = (Math.round(bounds[1]/10)/10) + 5000;
var a1y = (4 - (Math.floor(y/5000)%5))*5;
var a2y = (4 - (Math.floor(y/1000)%5))*5;
var y1 = Math.floor(y/100)%10;
a1y += (Math.floor(x/5000)%5);
a2y += (Math.floor(x/1000)%5);
var x1 = Math.floor(x/100)%10;
var tile500km = String.fromCharCode(a1y + Math.floor((a1y+17)/25) + "A".charCodeAt(0));
var tile100km = tile500km + String.fromCharCode(a2y + Math.floor((a2y+17)/25) + "A".charCodeAt(0));
var tile10km = tile100km + x1 + y1;
return 'https://mikenunn.net/data/terr50/grid/' + tile100km.toLowerCase() + '/' + tile10km + '.asc';
},
tileLoadFunction: function(tile, src) {
var xhr = new XMLHttpRequest();
xhr.addEventListener('loadend', function (evt) {
var data = this.response;
if (data !== undefined) {
var rows = data.split('\n');
if (rows.length >= 205) {
for (var j = 0; j < 200; j++) {
var values = rows[j + 5].split(' ');
for (var i = 0; i < 200; i++) {
var pixel = (parseFloat(values[i]) * 10) + 100000;
var index = (j * 200 + i) * 4;
imgData.data[index] = (pixel >> 16) & 0xFF;
imgData.data[index+1] = (pixel >> 8) & 0xFF;
imgData.data[index+2] = (pixel >> 0) & 0xFF;
imgData.data[index+3] = 0xFF;
}
}
ctx.putImageData(imgData, 0, 0);
tile.getImage().src = canvas.toDataURL();
}
} else {
tile.setState(3);
}
});
xhr.addEventListener('error', function () {
tile.setState(3);
});
xhr.open('GET', src);
xhr.send();
}
})
});
var map = new ol.Map({
target: 'map',
layers: [layer],
view: new ol.View({
projection: 'EPSG:27700',
center: ol.proj.fromLonLat([0, 51.5], 'EPSG:27700'),
zoom: 14
})
});
var showElevations = function(evt) {
if (evt.dragging) {
return;
}
map.forEachLayerAtPixel(
evt.pixel,
function(layer, pixel) {
var height = -10000 + (pixel[0] * 256 * 256 + pixel[1] * 256 + pixel[2]) * 0.1;
info.innerHTML = height.toFixed(1);
},
{
layerFilter: function(candidate) {
return layer === candidate;
}
}
);
};
map.on('pointermove', showElevations);
</script>
</body>
</html>

Load from JSON with dynamic patterns, patternSourceCanvas is not defined error return by the serialize JSON data

I am trying to save Fabric.js canvas and reload it using loadFromJson. But I am getting error patternSourceCanvas is not defined. I thought I should make it global so I removed var.
How to set the global variable in Fabric JS and use var patternSourceCanvas?
When I use the code below, then everything is working fine and the JSON is loaded easily.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.util.loadImage(t, function(t) {
var svg_width = i.width;
console.log('svg widh' + i.width + 'svg height' + i.height);
console.log('img width t'+ t.width + ' img height' + t.height);
if(svg_width >= 300){
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill({
source: t, repeat: 'repeat', offsetX:200 , offsetY : -110 // working
}), e.fabric.renderAll();
console.log('in if image 300 up ', t);
} else if (i.paths){
for (var r = 0; r < i.paths.length; r++)
i.paths[r].setPatternFill({
source: t, repeat: 'repeat' , offsetX: -100 , offsetY:-110
}), e.fabric.renderAll();
console.log('in image elseeee 300 up ', t);
}
}
})
But when I fill some other new shape with the new patternSourceCanvas variable then it's not working. Kindly help me with dynamic patterns.
var t = https://image.freepik.com/free-photo/roof-texture_21206171.jpg
fabric.Image.fromURL(t, function (img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: function() {
patternSourceCanvas.setDimensions({
width: img.getScaledWidth() ,
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
return patternSourceCanvas.getElement();
},
repeat: r
});
console.log('pattern', pattern);
//p.set('fill', pattern);
canvas.renderAll();
if (i.isSameColor && i.isSameColor() || !i.paths) {
i.setPatternFill(pattern);
} else if(i.paths) {
for (var r = 0; r < i.paths.length; r++) {
i.paths[r].setPatternFill(pattern);
}
}
e.fabric.renderAll();
});
You need to put patternSourceCanvas to global scope/ scope where loadFromJSON can access patternSourceCanvas. Else you can use cors enabled image directly.
DEMO
var imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/2/22/Wikimapia_logotype.svg';
var canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
width: 200,
height: 200,
strokeWidth: 2,
stroke: '#000'
})
canvas.add(rect);
fabric.Image.fromURL(imageUrl, function(img) {
img.scaleToHeight(200);
var patternSourceCanvas = new fabric.StaticCanvas();
patternSourceCanvas.add(img);
patternSourceCanvas.setDimensions({
width: img.getScaledWidth(),
height: img.getScaledHeight()
});
patternSourceCanvas.renderAll();
var pattern = new fabric.Pattern({
source: patternSourceCanvas.getElement()
},
function(patternObj) {
rect.fill = patternObj;
rect.dirty = true;
canvas.renderAll();
});
}, {
crossOrigin: 'annonymous'
});
function loadfromjson() {
var json = canvas.toJSON();
canvas.clear();
setTimeout(function() {
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
}, 1000)
}
canvas{
border:2px solid #000;
}
<canvas id="canvas" width="300" height="300"></canvas><br>
<button onclick="loadfromjson()">loadfromjson </button>
<script src='https://rawgit.com/kangax/fabric.js/master/dist/fabric.js'></script>

Google column chart bars width

I've got angular2 and google charts.
My component code is:
playstoreRatingChart(data) {
let dateTitle: any = 'Date';
let ratingTitle: any = 'Rating';
let dataTable = [[dateTitle, ratingTitle, { "role": 'annotation' }, { role: 'style' }]];
data.playstore_rating.forEach(function (obj) {
let newDate = new Date(obj.year, obj.month-1, obj.day)
let rating = obj.rating;
let rowRating = Number(rating.toFixed(2));
let test = parseFloat(rating.toFixed(2));
let row = [newDate, test, test, 'width:22; stroke-color: #871B47; stroke-opacity: 0.6; stroke-width: 12; fill-color: #BC5679; fill-opacity: 0.2'];
dataTable.push(row)
});
this.testPlayStore = {
chartType: 'ColumnChart',
dataTable: dataTable,
bar: { groupWidth: '100%' }
}
}
I don't know, why, but exactly this chart (i have few charts more on this page) have columns with 1px width and I cannot change its width.

Arbitrary Timeline in Cesium?

Cesium has a nice timeline at the bottom of the screen that changes the current astronomical phenomena and changes model positions and animation based on their model. What it doesn't have, and what I really need, is a way to plot events in arbitrary time. I'd like to start at time 00:00:00, and advance from there in real time, and rewind back to 00:00:00. At the moment, I don't care about astronomical activity, including solar and lunar activity. The API is set up to accept Julian Time, not set up for some arbitrary time. Is it possible to get an arbitrary timeline inserted in place of the normal timeline?
Give this a try. Internally it still uses JulianDates from some arbitrary date, but the user only ever sees the time, not the date.
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationInstructionsInitiallyVisible: false,
skyBox: false
});
var clock = viewer.clock;
clock.clockRange = Cesium.ClockRange.LOOP_STOP;
clock.startTime = Cesium.JulianDate.fromIso8601('2016-01-01T00:00:00Z');
clock.stopTime = Cesium.JulianDate.fromIso8601('2016-01-01T23:59:59Z');
clock.currentTime = clock.startTime;
function twoDigits(num) {
return ((num < 10) ? ('0' + num.toString()) : num.toString());
}
var animationViewModel = viewer.animation.viewModel;
animationViewModel.dateFormatter = function() { return ''; };
animationViewModel.timeFormatter = function(date, viewModel) {
var gregorianDate = Cesium.JulianDate.toGregorianDate(date);
var millisecond = Math.round(gregorianDate.millisecond);
return Cesium.sprintf("%02d:%02d:%02d.%03d", gregorianDate.hour,
gregorianDate.minute, gregorianDate.second, millisecond);
};
viewer.timeline.makeLabel = function(time) {
var gregorian = Cesium.JulianDate.toGregorianDate(time);
var millisecond = gregorian.millisecond, millisecondString = '';
if ((millisecond > 0) && (this._timeBarSecondsSpan < 3600)) {
millisecondString = Math.floor(millisecond).toString();
while (millisecondString.length < 3) {
millisecondString = '0' + millisecondString;
}
millisecondString = '.' + millisecondString;
}
return twoDigits(gregorian.hour) + ':' + twoDigits(gregorian.minute) + ':' +
twoDigits(gregorian.second) + millisecondString;
};
viewer.timeline.updateFromClock();
viewer.timeline.zoomTo(clock.startTime, clock.stopTime);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.18/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.18/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>

getting Cannot read property '0' of undefined when i click google map marker?

I am getting error when i click google map marker how to solve this problem i have enclosed fiddle http://jsfiddle.net/cLADs/135/ .when i click button it should pass id value based on marker click some one help me out to move forward.
var gmarkers1 = [];
var markers1 = [];
var infowindow = new google.maps.InfoWindow({
content: ''
});
// Our markers
markers1 = [
['0', 'Madivala', 12.914494, 77.560381, 'car','as12'],
['1', 'Majestic', 12.961229, 77.559281, 'third','as13'],
['2', 'Ecity', 12.92489905, 77.56070772, 'car','as14'],
['3', 'Jp nagar', 12.91660662, 77.52047465, 'second','as15']
];
/**
* Function to init map
*/
function initialize() {
var center = new google.maps.LatLng(12.9667,77.5667);
var mapOptions = {
zoom: 12,
center: center,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
for (i = 0; i < markers1.length; i++) {
addMarker(markers1[i]);
}
}
/**
* Function to add marker to map
*/
function addMarker(marker) {
var category = marker[4];
var title = marker[1];
var pos = new google.maps.LatLng(marker[2], marker[3]);
var content = marker[1];
var fullContent = marker.slice(1,6).join();
var marker1 = new google.maps.Marker({
title: title,
position: pos,
category: category,
map: map
});
gmarkers1.push(marker1);
// Marker click listener
google.maps.event.addListener(marker1, 'click', (function (marker1, fullContent) {
return function () {
console.log('Gmarker 1 gets pushed');
infowindow.setContent(fullContent);
infowindow.open(map, marker1);
map.panTo(this.getPosition());
map.setZoom(15);
///////
// Set CSS for the control border.
var controlDiv = document.createElement("div");
var controlUI = document.createElement('div');
controlUI.style.backgroundColor = '#fff';
controlUI.style.border = '2px solid #fff';
controlUI.style.borderRadius = '3px';
controlUI.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
controlUI.style.cursor = 'pointer';
controlUI.style.marginBottom = '22px';
controlUI.style.textAlign = 'center';
controlUI.title = 'Click to recenter the map';
controlDiv.appendChild(controlUI);
// Set CSS for the control interior.
var controlText = document.createElement('div');
controlText.style.color = 'rgb(25,25,25)';
controlText.style.fontFamily = 'Roboto,Arial,sans-serif';
controlText.style.fontSize = '16px';
controlText.style.lineHeight = '38px';
controlText.style.paddingLeft = '5px';
controlText.style.paddingRight = '5px';
controlText.innerHTML = 'Center Map';
controlUI.appendChild(controlText);
// Setup the click event listeners: simply set the map to Chicago.
controlUI.addEventListener('click', function() {
//Do Whatever you want here
});
controlDiv.index = 1;
map.controls[google.maps.ControlPosition.TOP_CENTER].push(controlDiv);
///////
}
})(marker1, fullContent));
}
/**
* Function to filter markers by category
*/
filterMarkers = function (category) {
for (i = 0; i < markers1.length; i++) {
marker = gmarkers1[i];
// If is same category or category not picked
if (marker.category == category || category.length === 0) {
marker.setVisible(true);
}
// Categories don't match
else {
marker.setVisible(false);
}
}
}
// Init map
initialize();
#map-canvas {
width: 500px;
height: 500px;
}
<div id="map-canvas"></div>
<select id="type" onchange="filterMarkers(this.value);">
<option value="">Please select category</option>
<option value="second">second</option>
<option value="car">car</option>
<option value="third">third</option>
</select>
if you print our your i in your listener, you will realized it always to be 4. Basically, the listener does not remember the number i, since it is a globe variable.
Look at the Google Example, they called a function and setup the info window inside.(so that it is i independent) You might do the same too.
Another solution is to store the value i as a tag to the marker, so that you can retrieve it from the marker object.

Resources