Change colour of MabBox Draw Polygon - colors

I'm creating polygons in MapBox using Mapbox draw as follows:
polyshapeoutzone = {
id: 'polyOut',
type: 'Feature',
properties: {},
geometry: { type: 'Polygon', coordinates: [mysql2poly(values[1])]}
};
I want to be able to change the polygon line and fill color on the fly (basically I have 2 polygons, I want 1 to be red and the other to be green). Is there a simple way to apply/change the colours on the fly for a given polygon (I don't care about vertex colours or the polygon colour when it's selected, I just want to be able to set each polygon's line and fill colour and change them dynamically).

$(function() {
if (!mapboxgl.supported()) {
alert('Your browser does not support Mapbox GL');
}
var initMap = function(){
mapboxgl.accessToken = 'pk.eyJ1IjoiamFtZXNwYWNrIiwiYSI6ImNqMDI5amtvZzAwNjIzM3QwYTZkbjk5c3MifQ.9jiCjBzXNG1IqvezOddnHA';
var map = new mapboxgl.Map({
container: 'multiple_poly',
style: 'mapbox://styles/mapbox/satellite-v9',
center: [103.32718927498,2.0123503108086],
zoom: 15
});
map.on('load', function () {
map.addSource("polygon_one",
{
"type":"geojson",
"data":{
"type":"FeatureCollection",
"features":[
{"type":"Feature","properties":[],"geometry":{"coordinates":[[[73.045157852226,26.303612426466],[73.045501174966,26.291685547272],[73.051166000414,26.299611287628],[73.045157852226,26.303612426466]]],"type":"Polygon"}},
]
}
});
map.addSource("polygon_two",
{
"type":"geojson",
"data":{
"type":"FeatureCollection",
"features":[
{"type":"Feature","properties":[],"geometry":{"coordinates":[[[73.01923698434584,26.286793889676773],[73.01726287851736,26.274403503526514],[73.02696174635398,26.277635905719848],[73.02972176719453,26.28963931883034],[73.01923698434584,26.286793889676773]]],"type":"Polygon"}},
]
}
});
map.addLayer({
"id": "quota-one",
"type": "line",
"source": "polygon_one",
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-color": "red",
"line-width": 3
},
"filter": ["==", "$type", "Polygon"]
});
map.addLayer({
"id": "quota-two",
"type": "line",
"source": "polygon_two",
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-color": "green",
"line-width": 3
},
"filter": ["==", "$type", "Polygon"]
});
map.flyTo({center:[73.01923698434584,26.286793889676773],zoom: 13});
});
}
initMap();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.css" rel="stylesheet">
<div id="multiple_poly" style="width: 400px;height: 400px"></div>

Related

Tabulator.js 5.2 datetime formatter with luxon.js, how to configure inputFormat for unix timestamps

I have a dataset with unix timestamp and want to display a readable date. Which inputFormat do I have to configure (using tabulator 5.2)?
I am switching from tabulator 4.9 to 5.2, which also changes the library used for the formatter:"datetime" from moment.js to luxon.js. With moment.js the formatterParams below worked.
formatterParams:{
inputFormat:"unix",
outputFormat:"DD/MM/YY HH:mm",
invalidPlaceholder:"(invalid date)"
}
With the luxon.js this doesn't work and I don't know which inputFormat to configure.
EDIT:
Relevant parts of the table
var event_table = new Tabulator("#events-table", {
height: "750",
layout: "fitDataTable",
movableRows: true,
ajaxURL: [],
columns: [
{ rowHandle: true, formatter: "handle", headerSort: false, frozen: true, width: 30, minWidth: 30 },
{
title: "Time", field: "timestamp", headerFilter: "input", formatter: "datetime", formatterParams: {
inputFormat: "unix",
outputFormat: "DD/MM/YY HH:mm",
invalidPlaceholder: "(invalid date)"
}
},
{ title: "Typ", field: "type", headerFilter: "list", headerFilterParams: { values: true } }
]
});
data:
[
{
"timestamp": 1655845814046,
"type": "weight"
},
{
"timestamp": 1655845931252,
"type": "weight"
},
{
"timestamp": 1655877784130,
"type": "amount"
},
{
"timestamp": 1655877828127,
"type": "weight"
}
]
Please note that "unix" is not "officially" supported by Tabulator 4.9, I don't see it mentioned in the DateTime built-in formatters.
It works because tabulator uses var newDatetime = moment(value, inputFormat); to parse cell value. So tabulator uses moment(String, String) that is is very forgiving, in your case it parse correctly the unix timestamp since the "unix" string used as format token contains the x that represents the token for Unix ms timestamp.
Luxon has no counterpart for moment x, you should use DateTime.fromMillis to parse Unix timestamps. There seems to be no way to use DateTime.fromMillis using DateTime formatter of version 5.2 of tabulator (see its code).
You can instead use a custom formatter:
As well as the built-in formatters you can define a formatter using a custom formatter function.
The formatter function accepts two arguments, the CellComponent for the cell being formatted and the formatterParams option from the column definition.
The function must return the contents of the cell, either the text value of the cell, valid HTML or a DOM node.
Example:
var tabledata = [{
"timestamp": 1655845814046,
"type": "weight"
},
{
"timestamp": 1655845931252,
"type": "weight"
},
{
"timestamp": 1655877784130,
"type": "amount"
},
{
"timestamp": 1655877828127,
"type": "weight"
}
];
var event_table = new Tabulator("#events-table", {
data: tabledata,
height: "750",
layout: "fitDataTable",
//movableRows: true,
//ajaxURL: [],
columns: [{
rowHandle: true,
formatter: "handle",
headerSort: false,
frozen: true,
width: 30,
minWidth: 30
},
{
title: "Time",
field: "timestamp",
headerFilter: "input",
formatter: function(cell, formatterParams, onRendered) {
try {
let dt = luxon.DateTime.fromMillis(cell.getValue());
return dt.toFormat(formatterParams.outputFormat);
} catch (error) {
return formatterParams.invalidPlaceholder;
}
},
formatterParams: {
outputFormat: "dd/MM/yy HH:mm",
invalidPlaceholder: "(invalid date)"
}
},
{
title: "Typ",
field: "type",
headerFilter: "list",
headerFilterParams: {
values: true
}
}
]
});
<link href="https://unpkg.com/tabulator-tables#5.2.7/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#5.2.7/dist/js/tabulator.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/luxon#2.4.0/build/global/luxon.min.js"></script>
<div id="events-table"></div>

js grid and autocomplete

I am able to create a custom field with jsGrid and jquery autocomplete. All ajax CRUD calls are working for all other fields. The below code activates autocomplete and shows the available options in the input field as expected.
var tags = ["tag1", "tag2", "tag3"];
MyDescriptionField.prototype = new jsGrid.Field({
insertTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editPicker = $("<input>").autocomplete({source : tags});
},
........... (more code)
So far so good. However to actually capture the value so it can be inserted into the db, I also need to define insertValue and editValue.
The code below is NOT working
insertValue: function(){
return this._insertPicker = $("<input>").val();
},
...........(more code)
this one is not working eiter:
insertValue: function(){
return this._insertPicker.autocomplete({
select: function(event, ui) {
$("<input>").val(ui.item.value);
}
});
},
reference: jsGrid. http://js-grid.com/demos/
autocomplete: https://jqueryui.com/autocomplete/
Try this snippet:
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return value;
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({source : tags});
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({source : tags}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [
{ name: "Name", type: "text" },
{ name: "Tag", type: "myTagField", width: 100, align: "center" },
{ type: "control", editButton: false, modeSwitchButton: false }
],
data: db.users
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [
{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}];
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script><script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="//rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<div id="jsGrid"></div>
or this codepen: https://codepen.io/beaver71/pen/rpaLEo
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry
$(function() {
var myTagField = function(config) {
jsGrid.Field.call(this, config);
};
myTagField.prototype = new jsGrid.Field({
autosearch: true,
sorter: function(tag1, tag2) {
return tag1.localeCompare(tag2);
},
itemTemplate: function(value) {
return '<span class="label label-primary">' + value + '</span>';
},
insertTemplate: function(value) {
return this._insertAuto = $("<input>").autocomplete({
source: tags
});
},
filterTemplate: function(value) {
if (!this.filtering)
return "";
var grid = this._grid,
$result = this._filterAuto = $("<input>").autocomplete({
source: tags
});
if (this.autosearch) {
$result.on("change", function(e) {
grid.search();
});
}
return $result;
},
editTemplate: function(value) {
return this._editAuto = $("<input>").autocomplete({
source: tags
}).val(value);
},
insertValue: function() {
return this._insertAuto.val();
},
filterValue: function() {
return this._filterAuto.val();
},
editValue: function() {
return this._editAuto.val();
}
});
jsGrid.fields.myTagField = myTagField;
$("#jsGrid").jsGrid({
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
fields: [{
name: "Name",
type: "text"
},
{
name: "Tag",
type: "myTagField",
width: 100,
align: "center"
},
{
type: "control",
editButton: false,
modeSwitchButton: false
}
],
data: db.users,
controller: {
loadData: function(filter) {
return $.grep(db.users, function(item) {
return (!filter.Tag || item.Tag.toLowerCase().indexOf(filter.Tag.toLowerCase()) > -1);
});
}
}
});
});
var tags = ["tag1", "tag2", "tag3"];
var db = {};
db.users = [{
"Name": "Carson Kelley",
"Tag": ""
},
{
"Name": "Prescott Griffin",
"Tag": "tag1"
},
{
"Name": "Amir Saunders",
"Tag": "tag3"
},
{
"Name": "Derek Thornton",
"Tag": "tag2"
},
{
"Name": "Fletcher Romero",
"Tag": ""
}
];
<html>
<head>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.css" rel="stylesheet"/>
<link href="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid-theme.css" rel="stylesheet"/>
<link href="//code.jquery.com/ui/1.11.2/themes/cupertino/jquery-ui.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css"/>
</head>
<body>
<h1>Custom Grid DateField filtering with autocomplete</h1>
<div id="jsGrid"></div>
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="https://rawgit.com/tabalinas/jsgrid/master/dist/jsgrid.min.js"></script>
</body>
</html>
Thanks #beaver. Your pen helped my understand custom fields better. I extended it a bit to add filtering with autocomplete. https://codepen.io/obrienje/pen/aQKNry

X-axis multiple colored label for bar chart using chart.js

I need x-axis labels in different colors, I am using "chart.js". I tried below code but it is not working, just showing single color-
scales: {
xAxes: [{
ticks: {
fontColor: [
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(145,151,163,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)'
]
}
}]
}
Output:
Need:
You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text of the same color as the corresponding bar.
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
When drawing your own tick labels, you need to instruct Chart.js not to display the default labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false
}
}],
You also need to define some padding for the bottom of the chart, otherwise you won't see your custom tick labels.
layout: {
padding: {
bottom: 20
}
},
Please take a look at the following sample code that illustrates how to change the labels on the x-axis depending on the values.
new Chart('myChart', {
type: 'bar',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
ctx.save();
ctx.textAlign = 'center';
ctx.font = '12px Arial';
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
ctx.restore();
}
}],
data: {
labels: ["-3", "-2", "-1", "0", "+1", "+2", "+3"],
datasets: [{
label: "My First Dataset",
data: [60, 59, 80, 81, 60, 55, 40],
fill: false,
backgroundColor: ['rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(145,151,163,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)'],
borderWidth: 1
}]
},
options: {
layout: {
padding: {
bottom: 20
}
},
scales: {
xAxes: [{
ticks: {
display: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 300px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Unable to use OpenLayer

I'm very new with web language and I have to integrate a map in a page. I'm using cshtml with Visual Studio 2015
To do this I have take a code using ol.js. The map have to be displayed, and for each value in my table I localize the city/country from IP and I display for each countries, the number of item.
There is my Index.cshtml
<script type="text/javascript">
var map;
var countriesLayer;
var citiesLayer;
function newCountriesLayer(start, end, item, result) {
return new ol.layer.Vector({
minResolution: 2500,
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: '#Url.Action("GetCountries")'
+ '?StartDate=' + start
+ '&EndDate=' + end
+ '&Item=' + item
+ '&Result=' + result
}),
style: function (f, r) {
return [
new ol.style.Style({
text: new ol.style.Text({ text: f.get("title"), fill: new ol.style.Fill({ color: '#673B8F' }), scale: 1.2 }),
image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'white' }) }),
})
];
}
});
}
function newCitiesLayer(start, end, item, result) {
return new ol.layer.Vector({
maxResolution: 2500,
source: new ol.source.GeoJSON({
projection: 'EPSG:3857',
url: '#Url.Action("GetCities")'
+ '?StartDate=' + start
+ '&EndDate=' + end
+ '&Item=' + item
+ '&Result=' + result
}),
style: function (f, r) {
return [
new ol.style.Style({
text: new ol.style.Text({ text: f.get("title"), fill: new ol.style.Fill({ color: '#673B8F' }), scale: 1.2 }),
image: new ol.style.Circle({ radius: 10, fill: new ol.style.Fill({ color: 'white' }) }),
})
];
}
});
}
$(document).ready(function () {
var start = $('#startDate').val();
var end = $('#endDate').val();
var item = $('#item').val();
var result = $('#resultat').val();
countriesLayer = newCountriesLayer(start, end, item, result);
citiesLayer = newCitiesLayer(start, end, item, result);
map = new ol.Map({
target: 'map',
renderer: 'canvas',
layers:
[
new ol.layer.Tile({
//source: new ol.source.TileWMS({
// url: 'http://maps.opengeo.org/geowebcache/service/wms',
// params: { LAYERS: 'openstreetmap', VERSION: '1.1.1' }
//})
source: new ol.source.OSM(),
}),
countriesLayer, citiesLayer
],
view: new ol.View2D({
center: ol.proj.transform([0, 0], 'EPSG:4326', 'EPSG:3857'),
zoom: 1,
})
});
});
</script>
In my Controller.cs I have 2 functions:
public ContentResult GetCities(string StartDate, string EndDate, string Item, string Result){...}
public ContentResult GetCountries(string StartDate, string EndDate, string Item, string Result){...}
both return :
return new ContentResult()
{
Content = geoJson.ToString(),
ContentEncoding = System.Text.Encoding.ASCII,
ContentType = "text/json"
};
Value for geoJson is :
{
"type": "FeatureCollection",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"properties": {
"id":"CN-30-Guangzhou",
"title":"2",
},
"geometry": {
"type": "Point",
"coordinates": [113.25,23.1167]
}
},
{
"type": "Feature",
"properties": {
"id":"CN-23-Shanghai",
"title":"1",
},
"geometry": {
"type": "Point",
"coordinates": [121.3997,31.0456]
}
},
]}
In the project that I took this code, it works. The map contain 2 points in china : a "1" is displayed in Shanghai and a "2" in Guangzhou.
In my project I have an error :
Uncaught TypeError: Cannot read property 'a' of null
at xl (ol.js:266)
at wl (ol.js:265)
at Bl (ol.js:268)
at Al (ol.js:269)
at nr (ol.js:471)
at pr.mr.f (ol.js:470)
at td (ol.js:38)
at N (ol.js:37)
at Xq.q (ol.js:467)
As I said, I'm very new to web and I lost with that error. If try to check ol.js but it is unreadable. Maybe I'm missing a library or a package but I don't know how to know.

Passing arrays to Flot

At the end of a functioning JS I have three arrays of x- and y-coordinates, return [theta_plot, omega_plot, e_plot];, that I would like to send to Flot for plotting:
function myPlot(theta_plot, omega_plot, e_plot) {
"use strict";
function doPlot(position) {
$.plot("#placeholder", [
{
data: theta_plot,
label: "Angle (rad)",
yaxis: 1,
color: "red"
},
{
data: omega_plot,
label: "Angular Velocity (rad/sec)",
yaxis: 2,
color: "green"
},
{
data: e_plot,
label: "Energy (J)",
yaxis: 3,
color: "blue"
}
],
{
yaxes: [
{
font: { color: "red" }
},
{
font: { color: "green" }
},
{
font: { color: "blue" }
},
{ alignTicksWithAxis: position === "left" ? 1 : null }
],
legend: { position: "nw" }
}
);
}
doPlot("left");
}
The outer function is my latest attempt to pass these arrays to Flot, without success. The inner function is obviously Flot. Placing doPlot in my JS produces the desired result, though JSLint complains that they are not defined, as it should. However, for purposes of organization I would like doPlot in my HTML. Question: How do I make doPlot aware of my arrays?
Just replace
function doPlot(position) {
with
function doPlot(theta_plot, omega_plot, e_plot, position) {
and call the new function directly without using the myPlot() function.

Resources