I have a group of pictures that toggle back and forth on 2 different pages so far. Now, I'd like to be able to sort by keywords. I like to be able to bring up a page only with items starting with letter A or bring up only a group with pictures relating to sports only, fruit only etc. If someone could point me in the right direction to get started, I would appreciate it. Thanks
http://readautism.atwebpages.com/
http://readautism.atwebpages.com/index1.html
<!doctype html>
<html>
<head>
<meta charset="ISO-8859-1" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<title>Example of How to Play a Sound on Click or on MouseOver</title>
<script>
var gStorage = {};
function toggle(anImage, anAltSrcArr) {
if (typeof(anImage) === "undefined" || typeof(anAltSrcArr) === "undefined" || anAltSrcArr.length === 0) {
return;
}
var id = anImage.id;
var oldSrc = anImage.src;
if (typeof(gStorage[id]) === "undefined") {
gStorage[id] = {
'id': id,
'origSrc': oldSrc,
'i': 0
};
}
gStorage[id].i += 1;
if (gStorage[id].i > anAltSrcArr.length) {
gStorage[id].i = 0;
}
if (gStorage[id].i === 0) {
anImage.src = gStorage[id].origSrc;
} else {
anImage.src = anAltSrcArr[gStorage[id].i - 1];
}
}
</script>
<script>
var html5_audiotypes={ //define list of audio file extensions and their associated audio types. Add to it if your specified audio file isn't on this list:
"mp3": "audio/mpeg",
"mp4": "audio/mp4",
"ogg": "audio/ogg",
"wav": "audio/wav"
}
function createsoundbite(sound){
var html5audio=document.createElement('audio')
if (html5audio.canPlayType){ //check support for HTML5 audio
for (var i=0; i<arguments.length; i++){
var sourceel=document.createElement('source')
sourceel.setAttribute('src', arguments[i])
if (arguments[i].match(/\.(\w+)$/i))
sourceel.setAttribute('type', html5_audiotypes[RegExp.$1])
html5audio.appendChild(sourceel)
}
html5audio.load()
html5audio.playclip=function(){
html5audio.pause()
html5audio.currentTime=0
html5audio.play()
}
return html5audio
}
else{
return {playclip:function(){throw new Error("Your browser doesn't support HTML5 audio unfortunately")}}
}
}
//Initialize two sound clips with 1 fallback file each:
var mouseoversound=createsoundbite("whistle.ogg", "whistle.mp3")
var clicksound=createsoundbite('http://static.sfdict.com/staticrep/dictaudio/P05/P0501900.mp3', "whistle.ogg")
var uniquevar1=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/B01/B0147400.mp3")
var uniquevar2=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/R01/R0153700.mp3")
var uniquevar3=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/B01/B0130100.mp3")
var uniquevar4=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/C02/C0298100.mp3")
var uniquevar5=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/C08/C0897400.mp3")
var uniquevar6=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/H00/H0020400.mp3")
var uniquevar7=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/H01/H0110100.mp3")
var uniquevar8=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/C05/C0578600.mp3")
var uniquevar9=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/S05/S0555400.mp3")
var uniquevar10=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/R04/R0433000.mp3")
var uniquevar11=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/T01/T0107200.mp3")
var uniquevar12=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/P02/P0230400.mp3")
var uniquevar13=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/N02/N0227500.mp3")
var uniquevar14=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/L00/L0050400.mp3")
var uniquevar15=createsoundbite("http://static.sfdict.com/staticrep/dictaudio/S04/S0462700.mp3")
</script>
</head>
<body
<p><CENTER><FONT SIZE = 4>DIRECTIONS: CLICK A PICTURE TO SEE WORD, THEN CLICK WORD TO SEE PICTURE AGAIN.</FONT>
<img class="with-action" id="image1" name="image1" src="bat.jpg" onclick="uniquevar1.playclip();toggle(this, ['bat1.jpg'])" STYLE="position:absolute; TOP:95px; LEFT:70px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image2" name="image2" src="refrigerator.jpg" onclick="uniquevar2.playclip();toggle(this, ['refrigerator1.jpg'])" STYLE="position:absolute; TOP:95px; LEFT:370px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image3" name="image3" src="baseball.jpg" onclick="uniquevar3.playclip();toggle(this, ['baseball1.jpg'])" STYLE="position:absolute; TOP:95px; LEFT:670px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image4" name="image4" src="chair.jpg" onclick="uniquevar4.playclip();toggle(this, ['chair1.jpg'])" STYLE="position:absolute; TOP:95px; LEFT:970px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image5" name="image5" src="couch.jpg" onclick="uniquevar5.playclip();toggle(this, ['couch1.jpg'])" STYLE="position:absolute; TOP:95px; LEFT:1270px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image6" name="image6" src="hair.jpg" onclick="uniquevar6.playclip();toggle(this, ['hair1.jpg'])" STYLE="position:absolute; TOP:395px; LEFT:70px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image7" name="image7" src="hat.jpg" onclick="uniquevar7.playclip();toggle(this, ['hat1.jpg'])" STYLE="position:absolute; TOP:395px; LEFT:370px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image8" name="image8" src="clown.jpg" onclick="uniquevar8.playclip();toggle(this, ['clown1.jpg'])" STYLE="position:absolute; TOP:395px; LEFT:670px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image9" name="image9" src="sink.jpg" onclick="uniquevar9.playclip();toggle(this, ['sink1.jpg'])" STYLE="position:absolute; TOP:395px; LEFT:970px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image10" name="image10" src="rug.jpg" onclick="uniquevar10.playclip();toggle(this, ['rug1.jpg'])" STYLE="position:absolute; TOP:395px; LEFT:1270px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image11" name="image11" src="teeth.jpg" onclick="uniquevar11.playclip();toggle(this, ['teeth1.jpg'])" STYLE="position:absolute; TOP:695px; LEFT:70px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image12" name="image12" src="pencil.jpg" onclick="uniquevar12.playclip();toggle(this, ['pencil1.jpg'])" STYLE="position:absolute; TOP:695px; LEFT:370px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image13" name="image13" src="nose.jpg" onclick="uniquevar13.playclip();toggle(this, ['nose1.jpg'])" STYLE="position:absolute; TOP:695px; LEFT:670px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image14" name="image14" src="lamp.jpg" onclick="uniquevar14.playclip();toggle(this, ['lamp1.jpg'])" STYLE="position:absolute; TOP:695px; LEFT:970px; WIDTH:175px; HEIGHT:175px"/>
<img class="with-action" id="image15" name="image15" src="shoe.jpg" onclick="uniquevar15.playclip();toggle(this, ['shoe1.jpg'])" STYLE="position:absolute; TOP:695px; LEFT:1270px; WIDTH:175px; HEIGHT:175px"/>
</p></CENTER>
</body>
</html>
Here are three functions:
Select by keyword
Select like first letter
Select similar pictures
Are these functions you looking for?
var pics = [
{id:0, name: 'Pineapple', tags: ["sport", "food"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:1, name: 'Venus', tags: ["sport", "planet"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:2, name: 'Jupiyer', tags: ["water", "food"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:3, name: 'Baseball', tags: ["color", "food"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:4, name: 'Apple', tags: ["car", "planet"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:5, name: 'Cloud', tags: ["plant", "sport"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
{id:6, name: 'Computer', tags: ["tree", "fruit", "stone"], audio:'B01/B0147400.mp3', img:'chair1.jpg'},
];
function select(keyword) {
return pics.filter(function(p){
return (p.tags && p.tags.indexOf(keyword)>-1);
});
}
function selectLike(pic) {
var res = {};
for(var i=0; i<pics.length;i++) {
select(pic.tags[i]).forEach(function(simpic){
res[simpic.id] = true;
});
};
delete res[pic.id];
return Object.keys(res).map(function(key){ return pics[key] });
}
function selectByLetter(letter) {
return pics.filter(function(p){
return (p.name[0].toUpperCase() == letter.toUpperCase());
});
};
function prepareAudioClips() {
pics.forEach(function(p){
p.clip = createsoundbite("http://static.sfdict.com/staticrep/dictaudio/"+p.audio)
});
}
// This is like a sceleton of the function
function generateHTMLforSimilar(arr) {
s = '';
for(var i=0;i<arr.length;i++) {
s += '<img class="with-action" id="'+arr[i].name+'" name="'+arr[i].name+'" src="'+arr[i].img+'" onclick="pics[arr.id].clip.playclip();toggle(this, [\"'+arr[i].img+'\"])" STYLE="position:absolute; float:left; WIDTH:175px; HEIGHT:175px"/>';
}
return s;
}
document.write( "<b>Like keyword:</b> ", JSON.stringify(select("food")) ,'<br/>');
document.write( "<b>Like letter:</b> ", JSON.stringify(selectByLetter("A")) ,'<br/>');
document.write( "<b>Like picture:</b> ", JSON.stringify(selectLike(pics[0])) ,'<br/>');
// prepareAudioClips(); // This wont work at SO without resource files
document.write( "<b>HTML:</b> ", generateHTMLforSimilar(selectLike(pics[0])) ,'<br/>');
Related
I wrote an AJAX Javascript code for my ESP32 datalogger which worked so far using old versions of Chart.js. The website hosted by the ESP32 is not working anylonger if I use a more recent of Chart.js.
The error message I caught is:
Uncaught ReferenceError: Chart is not defined at datalogin.html
The line in the code involved is this one
const myChart = new Chart(ctx, config);
Something in the interpretation seems to occur at a very early stage. But I could not identify what. See code below.
I already tried different Chart.js repository in order to have it working. It had absolutly no influence. I actively looked using different browser regarding this specific problematic and I could not find any way of solving this problem.
Thanks a lot for your support
<!DOCTYPE html>
<html lang="en">
<head>
<title>EFM Meter loggin interface</title>
<link rel="icon" type="image/x-icon" href="lightning.ico">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script type="module" src="https://github.com/cdnjs/cdnjs/blob/master/ajax/libs/Chart.js/4.0.1/chart.js" ></script>
<script type="module" src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns#2.0.1/dist/chartjs-adapter-date-fns.bundle.js"></script>
<style>
.jumbotron {
background-color: #000;
color: #fff;
}
</style>
</head>
<body>
<div class="jumbotron text-center">
<h1>Elektrofeldmeter Data Logging Page</h1>
</div>
<div class="container">
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12 ">
<div class="container-sm">
<canvas id="myChart" style="" height="152"></canvas>
</div>
</div>
</div>
</div>
<div class="row">
<div class="border border-2 m-2">
<div class="col-sm-12">
<h3> Parameters setup</h3>
</div>
</div>
<div class="border border-2 m-2">
<div class="row">
<div class="col-sm-12">
<label for="customRange1" class="form-label" id="labelPWM">PWM of motor: 190</label>
<input type="range" class="form-range" min="0" max="190" step="1" value="190" onchange="rangeValue(this)" id="customRange1">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmin">Y min: -5000</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="-5000" onchange="rangeY()" id="Ymin">
</div>
<div class="col-sm-6">
<label for="customRange2" class="form-label" id="labelYmax">Y max: +5000 0</label>
<input type="range" class="form-range" min="-5000" max="5000" step="1" value="5000" onchange="rangeY()" id="Ymax">
</div>
<div class="col-sm-12">
<button type="button" class="btn btn-primary" onclick="saveAs()">*.CSV</button>
</div>
</div>
</div>
</div>
</div>
<script>
function rangeValue(element) {
console.log(element.value);
var xhr = new XMLHttpRequest();
xhr.open("GET", "/pwm?value="+element.value, true);
xhr.send();
document.getElementById("labelPWM").innerHTML = "PWM of motor: " + element.value;
};
function rangeY() {
myChart.options.scales.y.max = document.getElementById('Ymax').value;
myChart.options.scales.y.min = document.getElementById('Ymin').value;
myChart.update();
};
function clkOrientation(element) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "/clk?value="+element.checked, true);
xhr.send();
}
const animation = { };
const config = {
type: 'line',
data: {
datasets: [{
borderColor: '#fc9905',
borderWidth: 2,
radius: 0,
data: 0
}
]
},
options: {
animation,
interaction: {
intersect: false
},
plugins: {
legend: false
},
scales: {
x: {
type: 'time',
title: {
display: true,
text: 'time',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
},
y: {
type: 'linear',
title: {
display: true,
text: 'Electrical field [V/m] # PWM=190',
color: '#000000',
font: {
size: 20
}
},
ticks :
{
color: '#000000',
font: {
size: 12
}
}
}
},
plugins: {
title: {
display: true,
text: 'Electrical field value [V/m]'
}
}
}
};
Chart.defaults.font.size = 20;
const ctx = document.getElementById('myChart').getContext('2d');
const myChart = new Chart(ctx, config);
function addData(chart, data) {
for (var i = 0 ; i < data.length; i++){
chart.data.datasets[0].data.push({"x":data[i].x,"y":(data[i].y-32.671)/0.48025});
};
chart.update();
};
function getData() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var txt = this.responseText;
var array = JSON.parse(txt); //Ref: https://www.w3schools.com/js/js_json_parse.asp
addData(myChart,array);
}
};
xhttp.open("GET", "readEFM", true); //Handle readADC server on ESP32
xhttp.send();
};
setInterval(function() {
getData();
}, 5000);
txt = '[{"x":1662921606250,"y":35.71},{"x":1662921606450,"y":35.61},{"x":1662921606650,"y":35.70},{"x":1662921606850,"y":35.74},{"x":1662921607050,"y":35.78},{"x":1662921607250,"y":35.45},{"x":1662921607450,"y":35.65},{"x":1662921607650,"y":35.66},{"x":1662921607850,"y":35.78},{"x":1662921608050,"y":35.76}]';
const myArr = JSON.parse(txt);
addData(myChart,myArr);
myChart.update();
function saveAs(){
let csvContent = "data:text/csv;charset=utf-8,";
for (var i = 0 ; i < myChart.data.datasets[0].data.length; i++){
csvContent+=myChart.data.datasets[0].data[i].x + "," + myChart.data.datasets[0].data[i].y + "\n";
}
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "EFM_log.csv");
document.body.appendChild(link);
link.click();
};
</script>
</body>
</html>
Say we have the following crossfilter / dc.js app:
While this is nice, the user loses "reference" the population when brushing. I would like for charts x, y, z, and a to keep the "underlying" bars when other charts are brushed. Perhaps in a different color like so:
I believe this may require updating the dc.renderAll() function, but I am not sure even how to start.
Here is all the code to reproduce this app with the .csv data hosted as a gist.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Data Exploration Tool MVP</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="http://unpkg.com/dc#3/dc.css"/>
<style>
#data-count {
margin-top: 0;
text-align: left;
float: none;
}
table {
table-layout: fixed;
}
td {
width: 1%;
}
</style>
</head>
<body>
<div class="container-fluid" style="margin: 10px;">
<div class="row">
<h2>Data Exploration Tool</h2>
<div class="col-md-3 well well-sm">
<div class="dc-data-count" id="data-count">
<span class="filter-count"></span>
selected out of
<span class="total-count"></span>
points |
Reset All<br>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<!-- First row of charts -->
<div class="row">
<div class="col-md-3">
<div id="chart-11" style="width:100%;">
<div id="chart-11-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-12" style="width:100%;">
<div id="chart-12-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-13" style="width:100%;">
<div id="chart-13-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-14" style="width:100%;">
<div id="chart-14-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
</div>
<!-- Second row of chart -->
<div class="row">
<div class="col-md-3">
<div id="chart-21" style="width:100%;">
<div id="chart-21-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-22" style="width:100%;">
<div id="chart-22-title"></div>
<div class="reset" style="visibility: hidden;">range: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-23"style="width:100%;">
<div id="chart-23-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
<div class="col-md-3">
<div id="chart-24"style="width:100%;">
<div id="chart-24-title"></div>
<div class="reset" style="visibility: hidden;">selected: <span class="filter"></span>
reset
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.1/d3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.js"></script>
<script src="http://unpkg.com/dc#3/dc.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<script type="text/javascript">
'use strict';
dc.config.defaultColors(d3.schemeSet1);
var
chart_11 = dc.barChart("#chart-11"),
chart_12 = dc.barChart("#chart-12"),
chart_13 = dc.barChart("#chart-13"),
chart_21 = dc.barChart("#chart-21"),
chart_22 = dc.barChart("#chart-22"),
chart_23 = dc.barChart("#chart-23"),
data_count = dc.dataCount(".dc-data-count");
d3.csv("https://gist.githubusercontent.com/JasonAizkalns/32ece5c815f9ac5d540c41dc0825bbab/raw/362050300ddcb99f195044c00d9f26b0d7d489ca/data.csv").then(function(data) {
var var_names = ["x", "y", "z", "a", "b", "c"];
$("#chart-11-title").append(["<h5>", var_names[0], "<br>Subtitle</h5>"].join(""));
$("#chart-12-title").append(["<h5>", var_names[1], "<br>Subtitle</h5>"].join(""));
$("#chart-13-title").append(["<h5>", var_names[2], "<br>Subtitle</h5>"].join(""));
$("#chart-21-title").append(["<h5>", var_names[3], "<br>Subtitle</h5>"].join(""));
$("#chart-22-title").append(["<h5>", var_names[4], "<br>Subtitle</h5>"].join(""));
$("#chart-23-title").append(["<h5>", var_names[5], "<br>Subtitle</h5>"].join(""));
var c11_bin = 10,
c12_bin = 10,
c13_bin = 500,
c21_bin = 100,
c22_bin = 20,
c23_bin = 1000;
var ndx = crossfilter(data),
chart_11_dim = ndx.dimension(function(d) { return +d[var_names[0]]; }),
chart_12_dim = ndx.dimension(function(d) { return +d[var_names[1]]; }),
chart_13_dim = ndx.dimension(function(d) { return +d[var_names[2]]; }),
chart_21_dim = ndx.dimension(function(d) { return +d[var_names[3]]; }),
chart_22_dim = ndx.dimension(function(d) { return +d[var_names[4]]; }),
chart_23_dim = ndx.dimension(function(d) { return +d[var_names[5]]; }),
chart_11_grp = chart_11_dim.group(function(d) { return Math.floor(d / c11_bin) * c11_bin }).reduceCount(),
chart_12_grp = chart_12_dim.group(function(d) { return Math.floor(d / c12_bin) * c12_bin }).reduceCount(),
chart_13_grp = chart_13_dim.group(function(d) { return Math.floor(d / c13_bin) * c13_bin }).reduceCount(),
chart_21_grp = chart_21_dim.group(function(d) { return Math.floor(d / c21_bin) * c21_bin }).reduceCount(),
chart_22_grp = chart_22_dim.group(function(d) { return Math.floor(d / c22_bin) * c22_bin }).reduceCount(),
chart_23_grp = chart_23_dim.group(function(d) { return Math.floor(d / c23_bin) * c23_bin }).reduceCount();
var all = ndx.groupAll();
data_count.dimension(ndx)
.group(all);
var chart_11_min = +chart_11_dim.bottom(1)[0][var_names[0]],
chart_11_max = +chart_11_dim.top(1)[0][var_names[0]],
chart_12_min = +chart_12_dim.bottom(1)[0][var_names[1]],
chart_12_max = +chart_12_dim.top(1)[0][var_names[1]],
chart_13_min = +chart_13_dim.bottom(1)[0][var_names[2]],
chart_13_max = +chart_13_dim.top(1)[0][var_names[2]],
chart_21_min = +chart_21_dim.bottom(1)[0][var_names[3]],
chart_21_max = +chart_21_dim.top(1)[0][var_names[3]],
chart_22_min = +chart_22_dim.bottom(1)[0][var_names[4]],
chart_22_max = +chart_22_dim.top(1)[0][var_names[4]],
chart_23_min = +chart_23_dim.bottom(1)[0][var_names[5]],
chart_23_max = +chart_23_dim.top(1)[0][var_names[5]];
var breathing_room = 0.05;
chart_11
.dimension(chart_11_dim)
.group(chart_11_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_11_min - ((chart_11_max - chart_11_min) * breathing_room), chart_11_max + ((chart_11_max - chart_11_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c11_bin; })
.controlsUseVisibility(true);
chart_12
.dimension(chart_12_dim)
.group(chart_12_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_12_min - ((chart_12_max - chart_12_min) * breathing_room), chart_12_max + ((chart_12_max - chart_12_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c12_bin; })
.controlsUseVisibility(true);
chart_13
.dimension(chart_13_dim)
.group(chart_13_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_13_min - ((chart_13_max - chart_13_min) * breathing_room), chart_13_max + ((chart_13_max - chart_13_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c13_bin; })
.controlsUseVisibility(true);
chart_21
.dimension(chart_21_dim)
.group(chart_21_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_21_min - ((chart_21_max - chart_21_min) * breathing_room), chart_21_max + ((chart_21_max - chart_21_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c21_bin; })
.controlsUseVisibility(true);
chart_22
.dimension(chart_22_dim)
.group(chart_22_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_22_min - ((chart_22_max - chart_22_min) * breathing_room), chart_22_max + ((chart_22_max - chart_22_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c22_bin; })
.controlsUseVisibility(true);
chart_23
.dimension(chart_23_dim)
.group(chart_23_grp)
.round(dc.round.floor)
.alwaysUseRounding(true)
.x(d3.scaleLinear().domain([chart_23_min - ((chart_23_max - chart_23_min) * breathing_room), chart_23_max + ((chart_23_max - chart_23_min) * breathing_room)]))
.xUnits(function(start, end, xDomain) { return (end - start) / c23_bin; })
.controlsUseVisibility(true);
dc.renderAll();
});
</script>
</div>
</body>
</html>
So yeah, neither dc.js nor crossfilter directly supports this use case, not that people don't want it.
Crossfilter only supports one active filter and gives you no way to find out what the totals were when no filters were applied.
EDIT: there is now an official example with code cleaned up in response to the follow up code review question. The below discussion still describes the technique well, but the code is less repetitive in the example.
Thanks for the reproducible example to start with. I put your original code in a fiddle.
It's a little tedious, but one way to get the affect you are after is to change each chart into a composite of two bar charts. We'll make the second subchart red and hide it until something is filtered. (More precisely, we'll hide it whenever there is nothing filtered.)
And we'll make the first (blue) subchart always show the initial values, not affected by any filters.
Creating a composite chart looks like this:
var chart_11 = dc.compositeChart("#chart-11"),
chart_12 = dc.compositeChart("#chart-12"),
chart_13 = dc.compositeChart("#chart-13"),
chart_21 = dc.compositeChart("#chart-21"),
chart_22 = dc.compositeChart("#chart-22"),
chart_23 = dc.compositeChart("#chart-23");
chart_11
.compose([
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp_copy)
.controlsUseVisibility(true)
,
dc.barChart(chart_11)
.dimension(chart_11_dim)
.group(chart_11_grp)
.colors('red')
.controlsUseVisibility(true)
.brushOn(false)
]);
(Yes it seems you have to apply controlsUseVisibility to every child chart - looks like a bug.)
The heart of the problem is how to make the underlying blue chart not change. We can use a
fake group for this. The idea is this object acts like a group except it just returns what the group had on page load:
function static_copy_group(group) {
var all = group.all().map(kv => ({key: kv.key, value: kv.value}));
return {
all: function() {
return all;
}
}
}
var chart_11_grp_copy = static_copy_group(chart_11_grp),
chart_12_grp_copy = static_copy_group(chart_12_grp),
chart_13_grp_copy = static_copy_group(chart_13_grp),
chart_21_grp_copy = static_copy_group(chart_21_grp),
chart_22_grp_copy = static_copy_group(chart_22_grp),
chart_23_grp_copy = static_copy_group(chart_23_grp);
Yes, that's a deep copy of group.all() because crossfilter updates everything in place.
Finally, here's the code to hide the second chart when nothing is filtered:
function any_filters() {
return [chart_11, chart_12, chart_13, chart_21, chart_22, chart_23]
.some(chart => chart.filters().length);
}
function hide_second_chart(chart) {
chart.select('.sub._1')
.attr('visibility', any_filters() ? 'visible' : 'hidden')
}
[chart_11, chart_12, chart_13, chart_21, chart_22, chart_23].forEach(function(chart) {
chart.on('pretransition', hide_second_chart)
})
Example fiddle.
I am developing a Jssor gallery in which I change the path of the images dynamically with Ajax. It turns out that everything works fine until I load the new images without refreshing the page. The styles are not loaded well. I have read that it is necessary to re-initialize Jssor after the modifications but I do not get it. Let's see if someone can help me. Thank you very much and sorry for my bad English.
Jssor function:
function ScaleSlider() {
var jssor_1_slider;
jssor_1_slider_init = function() {
var jssor_1_options = {
$AutoPlay: 1,
$SlideshowOptions: {
$Class: $JssorSlideshowRunner$,
$TransitionsOrder: 1
},
$ArrowNavigatorOptions: {
$Class: $JssorArrowNavigator$
},
$ThumbnailNavigatorOptions: {
$Class: $JssorThumbnailNavigator$,
$Rows: 2,
$SpacingX: 14,
$SpacingY: 12,
$Orientation: 2,
$Align: 156
}
};
jssor_1_slider = new $JssorSlider$("jssor_1", jssor_1_options);
var MAX_WIDTH = 960;
var containerElement = jssor_1_slider.$Elmt.parentNode;
var containerWidth = containerElement.clientWidth;
if (containerWidth) {
var expectedWidth = Math.min(MAX_WIDTH || containerWidth, containerWidth);
jssor_1_slider.$ScaleWidth(expectedWidth);
}
else {
window.setTimeout(ScaleSlider, 30);
}
$Jssor$.$AddEvent(window, "load", ScaleSlider);
$Jssor$.$AddEvent(window, "resize", ScaleSlider);
$Jssor$.$AddEvent(window, "orientationchange", ScaleSlider);
}
};
Ajax script:
$(document).ready(function() {
$('#btnchange').on('click', function(){
$.ajax({
type: "POST",
url: "alternative.php",
data: $("#data1").serialize(),
success: function(response) {
$('#jssor_1').html(response);
//At this point is where I try to start it but I do not get it
}
});
});
Helo Jssor, I have solved my code in this way. Thank you so much for all your help.
HTML:
I preload the images in the first category. With the 2 buttons I will call Ajax to modify the folder with the images of the gallery
<div class="gallery">
<input type="hidden" id="data1" name="category" value="cat1">
<button id="btn1" class="btn-gal"><span>Category 1</span></button>
<input type="hidden" id="data2" name="category" value="cat2">
<button id="btn2" class="btn-gal""><span>Category 2</span></button>
</div>
<div id="jssor_1" style="position:relative;margin:0 auto;top:0px;left:0px;width:980px;height:480px;overflow:hidden;visibility:hidden;">
<div data-u="loading" class="jssorl-009-spin" style="position:absolute;top:0px;left:0px;width:100%;height:100%;text-align:center;background-color:rgba(0,0,0,0.7);">
<img style="margin-top:-19px;position:relative;top:50%;width:38px;height:38px;" src="img/spin.svg" />
</div>
<div data-u="slides" style="cursor:default;position:relative;top:0px;left:0px;width:980px;height:380px;overflow:hidden;">
<?php
$directory = 'images/gallery/cat1/';
$dirint = dir($directory);
while (($archivo1 = $dirint->read()) !== false){
if (preg_match("/jpg/i", $archivo1)){
echo '<div>
<a href="'.$directory.$archivo1.'" >
<img data-u="image" src="'.$directory.$archivo1.'"/>
</a>
<img data-u="thumb" src="'.$directory.$archivo1.'"/>
</div>';
}
}
$dirint->close();
?>
</div>
<div data-u="thumbnavigator" class="jssort101" style="position:absolute;left:0px;bottom:0px;width:980px;height:100px;background-color:#000;" data-autocenter="1" data-scale-bottom="0.75">
<div data-u="slides">
<div data-u="prototype" class="p" style="width:190px;height:90px;">
<div data-u="thumbnailtemplate" class="t"></div>
<svg viewbox="0 0 16000 16000" class="cv">
<circle class="a" cx="8000" cy="8000" r="3238.1"></circle>
<line class="a" x1="6190.5" y1="8000" x2="9809.5" y2="8000"></line>
<line class="a" x1="8000" y1="9809.5" x2="8000" y2="6190.5"></line>
</svg>
</div>
</div>
</div>
<!-- Arrow Navigator -->
<div data-u="arrowleft" class="jssora106" style="width:55px;height:55px;top:162px;left:30px;" data-scale="0.75">
<svg viewbox="0 0 16000 16000" style="position:absolute;top:0;left:0;width:100%;height:100%;">
<circle class="c" cx="8000" cy="8000" r="6260.9"></circle>
<polyline class="a" points="7930.4,5495.7 5426.1,8000 7930.4,10504.3 "></polyline>
<line class="a" x1="10573.9" y1="8000" x2="5426.1" y2="8000"></line>
</svg>
</div>
<div data-u="arrowright" class="jssora106" style="width:55px;height:55px;top:162px;right:30px;" data-scale="0.75">
<svg viewbox="0 0 16000 16000" style="position:absolute;top:0;left:0;width:100%;height:100%;">
<circle class="c" cx="8000" cy="8000" r="6260.9"></circle>
<polyline class="a" points="8069.6,5495.7 10573.9,8000 8069.6,10504.3 "></polyline>
<line class="a" x1="5426.1" y1="8000" x2="10573.9" y2="8000"></line>
</svg>
</div>
</div>
<script type="text/javascript">jssor_1_slider_init();</script>
**The image folders in my system are "images/gallery/cat1" and "images/gallery/cat2"
Script:
Here are the functions for the buttons. Below is the gallery code. Each one that configures it with the options that he wants. I think it would be too much text if I write everything.
var jssor_1_slider;
$(document).ready(function() {
$('#btn1').on('click', function(){
$.ajax({
type: "POST",
url: "alternative.php",
data: $("#data1").serialize(),
success: function(response) {
jssor_1_slider.$ReloadSlides(response);
}
});
});
$('#btn2').on('click', function(){
$.ajax({
type: "POST",
url: "alternative.php",
data: $("#data2").serialize(),
success: function(response) {
jssor_1_slider.$ReloadSlides(response);
}
});
});
});
jssor_1_slider_init = function() {
var jssor_1_SlideshowTransitions = [
...
...
...
];
var jssor_1_options = {
...
...
...
};
jssor_1_slider = new $JssorSlider$("jssor_1", jssor_1_options);
var MAX_WIDTH = 980;
function ScaleSlider() {
...
...
...
}
ScaleSlider();
$Jssor$.$AddEvent(window, "load", ScaleSlider);
$Jssor$.$AddEvent(window, "resize", ScaleSlider);
$Jssor$.$AddEvent(window, "orientationchange", ScaleSlider);
};
alternative.php:
I scroll through the selected folder and upload the corresponding images in the gallery. The code selects all the JPG files in the folder.
<?php
$cat = $_POST['category'];
$directory = 'images/gallery/'.$cat.'/';
$dirint = dir($directory);
$response_slide='';
while (($archivo1 = $dirint->read()) !== false){
if (preg_match("/jpg/i", $archivo1)){
$response_slide.='<div><img data-u="image" src="'.$directory.$archivo1.'"/><img data-u="thumb" src="'.$directory.$archivo1.'"/></div>';
}
}
$dirint->close();
echo $response_slide;?>
I hope to help someone with this solution.
Please use the $ReloadSlides api method.
$(document).ready(function() {
$('#btnchange').on('click', function(){
$.ajax({
type: "POST",
url: "alternative.php",
data: $("#data1").serialize(),
success: function(response) {
//remove all slides and reload new slides
var slidesHtml = '<div><img data-u="image" src="url" /></div>';
slidesHtml += '<div><img data-u="image" src="url" /></div>';
jssor_1_slider.$ReloadSlides(slidesHtml);
}
});
});
Reference:
https://www.jssor.com/development/api-methods-properties-events.html
I am testing the solution you gave me and it works, but what I was trying to do is something more complicated.
When adding the new images I wanted to load all the .jpg files in a directory. I have done it with PHP in this way:
<?php
$directory = 'images/gallery/dir1/';
$dirint = dir($directory);
while (($archivo1 = $dirint->read()) !== false){
if (preg_match("/jpg/i", $archivo1)){
echo '<div>
<a href="'.$directory.$archivo1.'" >
<img data-u="image" src="'.$directory.$archivo1.'"/>
</a>
<img data-u="thumb" src="'.$directory.$archivo1.'"/>
</div>';
}
}
$dirint->close();
?>
But I do not know how to combine it with the sentences you told me:
var slidesHtml = '<div><img data-u="image" src="url" /></div>';
slidesHtml += '<div><img data-u="image" src="url" /></div>';
jssor_1_slider.$ReloadSlides(slidesHtml);
Let's see if you can think of something. Thank you.
I want to capture image from webcam and store it to database and file path.but it will not stored in database also in file path.
My view:
<script type="text/javascript" src="<?php echo base_url() ?>assets/dist/js/webcam.min.js"></script>
<div class="form-group">
<div class="col-sm-3 col-md-offset-3 no-print">
<!--<img src="<?php echo base_url(); ?>assets/images/blank.png" >-->
<div class="clearfix" id="my_camera"></div><br>
<button type="button" class="btn btn-info" onClick="take_snapshot()"><i class="fa fa-camera fa-fw"></i>Capture</button>
</div>
<div class="col-md-3 col-md-offset-1 imager" id="results">
<!--<img src="<?php echo base_url(); ?>assets/images/user.png" class="thumbnail" >-->
<h3>Visitors Photo</h3>
</div>
</div>
<script language="JavaScript">
function take_snapshot() {
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="' + data_uri + '"/>';
});
}
</script>
<script language="JavaScript">
Webcam.set({
width: 320,
height: 240,
image_format: 'jpeg',
jpeg_quality: 90
});
Webcam.attach('#my_camera');
</script>
if you use https://github.com/jhuckaby/webcamjs/blob/master/DOCS.md you can
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="' + data_uri + '"/>';
});
must be like
Webcam.snap(function (data_uri) {
document.getElementById('results').innerHTML =
'<h2>Here is your image:</h2>' +
'<img src="' + data_uri + '"/>';
Webcam.upload( data_uri, '<?php echo site_url('controlerfunctiontoupload'); ?>', function(code, text) {
if (code == '200') {
alert ('ok');
} else {
alert('error');
}
} );
});
see in documentation
upload_name "webcam"
in controler / function to upload
$filename='test.jpg';
$filepath=FCPATH.'folderWithRights0777/'.$filename;
$result=move_uploaded_file($_FILES['webcam']['tmp_name'], $filepath));
also for insert in database
$this->db->from('files');
$this->db->set('image', $filename);
$this->db->insert();
I'm trying to create a heatmap map with 2 layers using google maps API and heatmaps.js. I'm able to create my map by hard-coding my lat/lon variables, but ultimately I'd like to have my layers fed from JSON files that can easily be refreshed.
Here is my current HTML, which works great.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href='css/bootstrap.css' rel='stylesheet' type='text/css'></link>
<link href='css/bootstrap-responsive.css' rel='stylesheet' type='text/css'></link>
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.3.js'></script>
<script type='text/javascript' src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=visualization&.js"></script>
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
#media (max-width: 980px) {
/* Enable use of floated navbar text */
.navbar-text.pull-right {
float: none;
padding-left: 5px;
padding-right: 5px;
}
}
</style>
<script>
var map, pointarray, heatmap;
var layer1 = [
{location: new google.maps.LatLng(42.071523,-72.624257), weight:13.747727085},
{location: new google.maps.LatLng(42.37686,-72.46914), weight:6.6332495807},
{location: new google.maps.LatLng(42.40524,-72.528427), weight:5.1961524227},
{location: new google.maps.LatLng(42.383945,-72.511834), weight:1.7320508076},
{location: new google.maps.LatLng(42.433317,-72.114488), weight:5.6568542495}
];
var layer2 = [
{location: new google.maps.LatLng(41.513113,-74.37616), weight:2.4494897428},
{location: new google.maps.LatLng(41.147711,-73.941171), weight:10},
{location: new google.maps.LatLng(41.329376,-74.347207), weight:4.8989794856},
{location: new google.maps.LatLng(41.338977,-73.987248), weight:1.7320508076}
];
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
pointArray1 = new google.maps.MVCArray(layer1);
pointArray2 = new google.maps.MVCArray(layer2);
heatmap1 = new google.maps.visualization.HeatmapLayer({
data: pointArray1
});
heatmap2 = new google.maps.visualization.HeatmapLayer({
data: pointArray2
});
heatmap1.setMap(map);
heatmap2.setMap(map);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
<link href='css/DT_bootstrap.css' rel='stylesheet' type='text/css'></link>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../assets/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="#">Test Page</a>
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
Logged in as ...
</p>
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<body class="container-fluid">
<div class="row">
<div class="span12" style="float: none; margin: 0 auto;">
<body onload="initialize()">
<h3>Test Layers</h3>
<input type='checkbox' name='system_type17' value='1' onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 1</span>
<input type="checkbox" name="system_type3" value="2" onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 2</span>
<br><br/>
<div id="map-canvas" style="height: 575px; width: 1000px;"></div>
</body>
</div>
</div>
</body>
</body>
</html>
What I would like to do is replace var layer1 and layer2 with a single JSON file that I would be able to just query, I'm just unsure how to execute something like this. For example, a JSON file that would look something like this:
{
"datapoints": [
{
"lat": "38.1513366000",
"lon": "-97.4341659000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1513748000",
"lon": "-97.4341125000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1513938000",
"lon": "-97.4341125000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1493263000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"1"
},
{
"lat": "38.1493339000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1493377000",
"lon": "-97.4339447000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1483650000",
"lon": "-97.4358291000",
"weight": "0",
"layer":"2"
},
{
"lat": "38.1484031000",
"lon": "-97.4358062000",
"weight": "0",
"layer":"2"
}
]
}
Updated code per Yehia's suggestions:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<link href='css/bootstrap.css' rel='stylesheet' type='text/css'></link>
<link href='css/bootstrap-responsive.css' rel='stylesheet' type='text/css'></link>
<script type='text/javascript' src='js/jquery-1.8.3.js'></script>
<script type='text/javascript' src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=visualization&.js"></script>
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
#media (max-width: 980px) {
/* Enable use of floated navbar text */
.navbar-text.pull-right {
float: none;
padding-left: 5px;
padding-right: 5px;
}
}
</style>
<script>
var map, pointarray, heatmap;
/*var layer1 = [
{location: new google.maps.LatLng(42.071523,-72.624257), weight:13.747727085},
{location: new google.maps.LatLng(42.37686,-72.46914), weight:6.6332495807},
{location: new google.maps.LatLng(42.40524,-72.528427), weight:5.1961524227},
{location: new google.maps.LatLng(42.383945,-72.511834), weight:1.7320508076},
{location: new google.maps.LatLng(42.433317,-72.114488), weight:5.6568542495}
];
var layer2 = [
{location: new google.maps.LatLng(41.513113,-74.37616), weight:2.4494897428},
{location: new google.maps.LatLng(41.147711,-73.941171), weight:10},
{location: new google.maps.LatLng(41.329376,-74.347207), weight:4.8989794856},
{location: new google.maps.LatLng(41.338977,-73.987248), weight:1.7320508076}
];*/
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
<link href='css/DT_bootstrap.css' rel='stylesheet' type='text/css'></link>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="../assets/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container-fluid">
<button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="brand" href="#">Test Page</a>
<div class="nav-collapse collapse">
<p class="navbar-text pull-right">
Logged in as ...
</p>
<ul class="nav">
<li class="active">Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<body class="container-fluid">
<div class="row">
<div class="span12" style="float: none; margin: 0 auto;">
<body onload="initialize()">
<h3>Test Layers</h3>
<input type='checkbox' name='system_type17' value='1' onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 1</span>
<input type="checkbox" name="system_type3" value="2" onclick="changeMap(this.value);" checked="checked" />
<span style="width:100px;display:inline-block;">Layer 2</span>
<br><br/>
<div id="map-canvas" style="height: 575px; width: 1000px;"></div>
</body>
</div>
</div>
<script type="text/javascript">
$.getJSON("testdata.json").then(function(data) {
$.each(data, function(i,datapoints) {
$.each(datapoints, function(j,datapoint) {
layers.push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
});
});
});
<script>
</body>
</body>
</html>
Alright, almost there I think. Thanks so much for your help so far, I know this is painful. Here is my initialize function, I'm still getting Uncaught ReferenceError: layers is not defined
<script type='text/javascript'>
var map, pointarray, heatmap;
function initialize() {
function loadData() {
var layers = [ ];
$.ajax({
url: 'testdata.json',
async: false,
dataType: 'json',
success: function (data) {
for (var i=0; i<data.datapoints.length; i++) {
var datapoint = data.datapoints[i];
if (layers[datapoint.layer]===undefined) {
layers[datapoint.layer] = [];
}
layers[datapoint.layer].push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lon),
weight: datapoint.weight,
layerID: datapoint.layer
});
}
}
});
return layers;
}
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(38.82, -99.408660),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
pointArray1 = new google.maps.MVCArray(layers[1]);
pointArray2 = new google.maps.MVCArray(layers[2]);
heatmap1 = new google.maps.visualization.HeatmapLayer({
data: pointArray1
});
heatmap2 = new google.maps.visualization.HeatmapLayer({
data: pointArray2
});
heatmap1.setMap(map);
heatmap2.setMap(map);
}
//FUNCTION TO CHANGE LAYERS
function changeMap(layerNum) {
if (layerNum == 1) {
updateMap(heatmap1);
}
if (layerNum == 2) {
updateMap(heatmap2);
}
}
//FUNCTION TO UPDATE LAYERS
function updateMap(layer) {
var layerMap = layer.getMap();
if (layerMap) {
layer.setMap(null);
} else {
layer.setMap(map);
}
}
</script>
You'll need a way of reading that JSON and parsing it into the variable(s) you need. Since you're using jQuery, here's a method that would work with the JSON structure you have.
$.getJSON("layers.json").then(function(data) {
$.each(data, function(i,datapoints) {
$.each(datapoints, function(j,datapoint) {
layers.push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
});
});
});
Adapt as necessary.
In response to davids12's update, here's a function that returns an array of arrays where each composite array has the datapoints from a certain layer. So, running over your example, layers would have 2 arrays in it (layers[1] and layers[2]) which are basically layer1 and layer2 that you describe in your code (with an additional layerID variable; you could remove it if you wish). This allows you to load much more layers and points just by putting them in the JSON using the format you have now.
function loadData() {
var layers = [ ];
$.ajax({
url: 'j.json',
async: false,
dataType: 'json',
success: function (data) {
for (var i=0; i<data.datapoints.length; i++) {
var datapoint = data.datapoints[i];
if (layers[datapoint.layer]===undefined) {
layers[datapoint.layer] = [];
}
layers[datapoint.layer].push({
location: new google.maps.LatLng(datapoint.lat, datapoint.lng),
weight: datapoint.weight,
layerID: datapoint.layer
});
}
}
});
return layers;
}