MapBox Heatmap hide outside boundaries - heatmap

I'm creating a heatmap of the United States and the designers want to "stop" the color from bleeding outside the US borders. So under Texas, the colors would reach the edge of the state and just stop.
Is this possible?
I tried creating another layer that included Mexico, Canada, and the Pacific/Atlantic Oceans, but heatmaps render after and I can't find out how to set a render priority, either.
edit: Here is an image that shows the desired effect:
And here is my code, minus some irrelevant data:
mapboxgl.accessToken = 'accessTokenString';
var map = new mapboxgl.Map({
container: 'map-heatmap',
style: 'mapbox://uri/for/styles',
center: [-95.922211, 37.881266],
zoom: 3.15,
minZoom: 3.15,
maxZoom: 3.15,
maxPitch: 0,
dragPan: false,
dragRotate: false
});
map.on('load', function() {
map.addSource('states', {
'type': 'geojson',
'data': '/path/to/us-states-contiguous.geojson'
});
map.addLayer({
'id': 'state-fills',
'type': 'fill',
'source': 'states',
'layout': {},
'paint': {
'fill-color': '#F2F2F2'
}
});
map.addSource('mexico', {
'type': 'geojson',
'data': '/path/to/mexico.geojson'
});
map.addLayer({
'id': 'mexico',
'type': 'fill',
'source': 'mexico',
'layout': {},
'paint': {
'fill-color': '#fff'
}
});
map.addSource('heatmapCoordinates', {
'type': 'geojson',
data: {
"type": "FeatureCollection",
"features": {/* JSON coordinates */}
}
});
map.addLayer({
'id': 'myHeatmap',
'type': 'heatmap',
'source': 'heatmapCoordinates',
'layout': {},
'paint': {
'heatmap-weight': 1,
'heatmap-color': [
'interpolate',
['linear'],
['heatmap-density'],
0,
'rgba(0, 0, 0, 0)',
1,
'rgba(0, 183, 79, 1)',
],
'heatmap-radius': 100,
'heatmap-opacity': .5
}
}, 'mexico');
map.addLayer({
'id': 'state-borders',
'type': 'line',
'source': 'states',
'layout': {},
'paint': {
'line-color': 'rgba(43, 43, 43, .5)',
'line-width': .25
}
});
});
For some reason, the borders that I draw over the heatmap appear "on top" of it. But when I try a layer to "fill", (like with Mexico above), it won't appear over the heatmap gradients, always underneath.
So how would I be able to "clip" the heatmap's shading outside of the US borders to achieve the above image's desired effect?

Your heatmap renders above the clip polygons because you're adding it to the map afterwards.
You just need to change the order of the two addLayer() calls.

Related

JSON QuickChart.io Change the Chart Size

I am creating a QuickChart.io using Chart.JS within a PowerApps canvas and am having some issues with formatting. Everything works on the visualization (filtering, rendering, etc.) but I am trying to remove the gridlines and resize the display area but the formatting options are not showing up. Any idea what's causing this?
"https://quickchart.io/chart?c="&EncodeUrl("{
'type': 'bar',
'data': {
'labels': ["&Concat(Filter(Table2,Scenario=_code),"'"&'X-Axis'&"',")&"],
'datasets': [
{
'label': 'Dataset 2',
'backgroundColor': 'rgba(54, 162, 235, 0.5)',
'borderColor': 'rgb(54, 162, 235)',
'borderWidth': 1,
'data': ["&Concat(Filter(Table2,Scenario=_code),"'"&DataSet1&"',")&"]
}
]
},
'options':
{
'elements': {
'rectangle': {
'borderWidth': 2
}
},
'responsive': true,
'maintainAspectRatio': false,
'legend': {
'display': false
},
'grid': {
display: false
},
'title': {
'display': true,
'text': 'Revenue'
}
}
}")
Your config is invalid, there is no grid option in the root of the options.
Depending on if quick chart is using chartjs V2 or v3 you need to configure it in the scales section
V2: options.scales.xAxes[0].gridLines.display
V3: options.scales.x.grid.display
And then you replace x by y to remove the y grid

Barchart reducing space between bars

I am trying to reduce the space between bars, and I am pretty sure it has to be within this piece of code. I removed the code that displays the legend and yAxes assuming I would not need to edit those parts.
barchart = new Chart(myChart, {
type:'bar',
data:{
labels: {{ data.x_vals | tojson }},
datasets:[{
label:'Liquid Level',
data:{{ data.y_vals }},
backgroundColor: gradient,
borderWidth:1, //Effects plotted line on chart
borderColor:'white',
hoverBorderWidth:1,
hoverBorderColor:'#000',
barPercentage: 1.0,
categoryPercentage: 1.0
}]
},
options:{
// legend is here
},
scales: {
// yAxes is here
xAxes: [{
display: true,
ticks: {
autoSkip: true,
padding: 4,
fontSize: 12
}
}]
},
You can set the category and bar percentages to 1:
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'blue',
categoryPercentage: 1,
barPercentage: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
EDIT:
Make sure you have at least chart.js version 2.9 installed since any version below its not implemented yet

How do I get an element that is nested within a JSON dictionary?

I got a JSON response using the Spotify API and I'm trying to access the element called 'name' (one says '3 Doors Down' and the other starts with 'Bret Michaels') that seems to be inside the 'items' element but I can't seem to find the solution.
This is how I loaded the data:
search_results = requests.get(search_url + 'q=' + query + '&type=artist', headers=granted_headers).json()
Here is my JSON data:
{
'artists': {
'href': 'https://api.spotify.com/v1/search?query=3+doors+down&type=artist&offset=0&limit=20',
'items': [
{
'external_urls': {
'spotify': 'https://open.spotify.com/artist/2RTUTCvo6onsAnheUk3aL9'
},
'followers': {
'href': None,
'total': 2631330
},
'genres': [
'alternative metal',
'nu metal',
'pop rock',
'post-grunge'
],
'href': 'https://api.spotify.com/v1/artists/2RTUTCvo6onsAnheUk3aL9',
'id': '2RTUTCvo6onsAnheUk3aL9',
'images': [
{
'height': 640,
'url': 'https://i.scdn.co/image/ead4e883a59d30d8c157385aa531d3fe8e688fc0',
'width': 640
},
{
'height': 320,
'url': 'https://i.scdn.co/image/611a4fd8aaf2637c5894acf65f12e79d75926329',
'width': 320
},
{
'height': 160,
'url': 'https://i.scdn.co/image/f1a1a2c37f2f6d242b1ab7ae3f4d893bf5822095',
'width': 160
}
],
'name': '3 Doors Down',
'popularity': 72,
'type': 'artist',
'uri': 'spotify:artist:2RTUTCvo6onsAnheUk3aL9'
},
{
'external_urls': {
'spotify': 'https://open.spotify.com/artist/2kPbQDZvnasPcCuXbq6YQx'
},
'followers': {
'href': None,
'total': 156
},
'genres': [
],
'href': 'https://api.spotify.com/v1/artists/2kPbQDZvnasPcCuXbq6YQx',
'id': '2kPbQDZvnasPcCuXbq6YQx',
'images': [
],
'name': 'Bret Michaels (Featuring Brad Arnold of 3 Doors Down, Chris Cagle, Mark Wills)',
'popularity': 4,
'type': 'artist',
'uri': 'spotify:artist:2kPbQDZvnasPcCuXbq6YQx'
}
],
'limit': 20,
'next': None,
'offset': 0,
'previous': None,
'total': 4
}
}
artists = search_results['artists']['items'] # This is a list
for artist in artists: # artist is each object in the list
print(artist['name'])
Output:
> '3 Doors Down'
> 'Bret Michaels (Featuring Brad Arnold of 3 Doors Down, Chris Cagle, Mark Wills)'

highchart activity gauge chart using json data from a file

I am new to using highcharts.js. I want to create an activity gauge chart using data from a json file or url. I have understood how they draw the chart but failed to understand the data format used in json to display the chart.
Here is my code
var options = {
chart: {
type: 'solidgauge',
marginTop: 50
},
title: {
text: 'Activity',
style: {
fontSize: '24px'
}
},
tooltip: {
borderWidth: 0,
backgroundColor: 'none',
shadow: false,
style: {
fontSize: '16px'
},
pointFormat: '{series.name}<br><span style="font-size:2em; color: {point.color}; font-weight: bold">{point.y}%</span>',
positioner: function (labelWidth, labelHeight) {
return {
x: 200 - labelWidth / 2,
y: 180
};
}
},
pane: {
startAngle: 0,
endAngle: 360,
background: [{ // Track for Move
outerRadius: '112%',
innerRadius: '88%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0.3).get(),
borderWidth: 0
}, { // Track for Exercise
outerRadius: '87%',
innerRadius: '63%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[1]).setOpacity(0.3).get(),
borderWidth: 0
}, { // Track for Stand
outerRadius: '62%',
innerRadius: '38%',
backgroundColor: Highcharts.Color(Highcharts.getOptions().colors[2]).setOpacity(0.3).get(),
borderWidth: 0
}]
},
yAxis: {
min: 0,
max: 100,
lineWidth: 0,
tickPositions: []
},
plotOptions: {
solidgauge: {
borderWidth: '34px',
dataLabels: {
enabled: false
},
linecap: 'round',
stickyTracking: false
}
},
series: []
};
var gauge1;
$.getJSON('bryan.json', function(json){
console.log(json)
options.chart.renderTo = 'container';
options.series.data = json
gauge1 = new Highcharts.Chart(options);
});
/**
* In the chart load callback, add icons on top of the circular shapes
*/
function callback()
{
// Move icon
this.renderer.path(['M', -8, 0, 'L', 8, 0, 'M', 0, -8, 'L', 8, 0, 0, 8])
.attr({
'stroke': '#ffffff',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'stroke-width': 2,
'zIndex': 10
})
.translate(190, 26)
.add(this.series[2].group);
// Exercise icon
this.renderer.path(['M', -8, 0, 'L', 8, 0, 'M', 0, -8, 'L', 8, 0, 0, 8, 'M', 8, -8, 'L', 16, 0, 8, 8])
.attr({
'stroke': '#ffffff',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'stroke-width': 2,
'zIndex': 10
})
.translate(190, 61)
.add(this.series[2].group);
// Stand icon
this.renderer.path(['M', 0, 8, 'L', 0, -8, 'M', -8, 0, 'L', 0, -8, 8, 0])
.attr({
'stroke': '#ffffff',
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'stroke-width': 2,
'zIndex': 10
})
.translate(190, 96)
.add(this.series[2].group);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container" style="width: 400px; height: 400px; margin: 0 auto">
</div>
And here is my json data which i thout might be rendered but it didnot.
data.json
First of all, instead of options.series.data = json, you need to create the first series and then populate its data array with your data. Also, set in each point different radius and innerRadius properties. Take a look at the example below.
API Reference:
http://api.highcharts.com/highcharts/series.solidgauge.data.radius
http://api.highcharts.com/highcharts/series.solidgauge.data.innerRadius
Example:
http://jsfiddle.net/x3cne1ng/

Highchart speedometer take input from csv

I am trying to read the data from csv and display it as a input to Speedometer but I am unable to get the chart. Please tell me where i am going wrong.
My code is:
$(document).ready(function() {
var options = {
chart: {
type: 'gauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
plotBorderWidth: 0,
plotShadow: false
},
title: {
text: 'Speedometer'
},
pane: {
startAngle: -150,
endAngle: 150,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF'],
[1, '#333']
]
},
borderWidth: 0,
outerRadius: '109%'
}, {
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#333'],
[1, '#FFF']
]
},
borderWidth: 1,
outerRadius: '107%'
}, {
// default background
}, {
backgroundColor: '#DDD',
borderWidth: 0,
outerRadius: '105%',
innerRadius: '103%'
}]
},
// the value axis
yAxis: {
min: 0,
max: 100,
minorTickInterval: 'auto',
minorTickWidth: 1,
minorTickLength: 10,
minorTickPosition: 'inside',
minorTickColor: '#666',
tickPixelInterval: 30,
tickWidth: 2,
tickPosition: 'inside',
tickLength: 10,
tickColor: '#666',
labels: {
step: 2,
rotation: 'auto'
},
title: {
text: 'km/h'
},
plotBands: [{
from: 0,
to: 120,
color: '#55BF3B' // green
}, {
from: 120,
to: 160,
color: '#DDDF0D' // yellow
}, {
from: 160,
to: 200,
color: '#DF5353' // red
}]
},
series: []
};
$.get('data.csv', function(data) {
var series = {
data: [],
name: 'Speed',
tooltip: {
valueSuffix: ' km/h'
}
};
series.data.push(parseFloat(data));
options.series.push(series);
alert("data "+options.series);
var chart = new Highcharts.Chart(options);
});
});
and the csv file is simple
data.csv has only one value 30.
or incase it is
t1,30
t2,40
t3,60
how do i display 3 corresponding speedometers with respective speed.
Your help is greatly appreciated.
Thanks in advance.
In your case data your data (from ajax) is a single string, but you need to split elements and then choose which should be parsed to integer (parseFloat).