Javascript: Difference between revisions
(Created page with "=== Basics === {| class="wikitable" ! Jquery |}<!-- ================================================================================================================...") |
No edit summary |
||
Line 4: | Line 4: | ||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Bootstrap | |||
|- | |||
| | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Single Page Application | |||
|- | |||
| css: | |||
<pre> | |||
.mdm-scrollable-div | |||
{ | |||
height: 100%; | |||
overflow: auto; | |||
} | |||
</pre> | |||
html: | |||
<pre> | |||
<-- header --> | |||
<div class="frame" id="frame1top"> | |||
<div class="mdm-scrollable-div"> | |||
... | |||
</div> | |||
</div> | |||
<-- footer --> | |||
</pre> | |||
js: | |||
<pre> | |||
// We need to adjust layout on resize, in ready handler, and programmatically as needed. | |||
$(window).resize(adjustLayout).resize(); | |||
$( document ).ready(function() { | |||
// We need to adjust in ready handler, on resize, and programmatically as needed | |||
adjustLayout(); | |||
/* your other page load code here*/ | |||
}); | |||
function adjustLayout(){ | |||
// ---------------------- | |||
// Fundamental dimensions | |||
var hh = $('#theheader').outerHeight(); | |||
var fh = $('#thefooter').outerHeight(); | |||
var workspace_height = $(window).height() - hh - fh; | |||
var workspace_width = $(window).width(); | |||
// ---------------------- | |||
var cols = 1; | |||
var col_gap = 16; | |||
// Margin is based on percent of one column width, so it goes to zero before column width does. :-) | |||
// Width is based on total width minus margins, then split between columns. | |||
var margin = ($(window).width() / cols) * .04; | |||
var w = ($(window).width() - (margin * (cols + 1))) / cols; | |||
var h1 = workspace_height; | |||
$('#frame1top').css({ | |||
display:'block', | |||
position:'absolute', | |||
left: margin * 1 + w * 0, | |||
top: hh, | |||
width: w, | |||
height: h1 | |||
}); | |||
} | |||
</pre> | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Button handlers | |||
|- | |||
| Buttons can be represented with labels; in that case, use a click handler: | |||
<pre> | |||
jQuery('<label id="'+cycle.apsID+'" class="btn">MahButt</label>') | |||
.appendTo('#'+chartid+'-apsbar') | |||
.on('click', function(){ | |||
$(location).attr('href','/v1/parameters/'+this.id+'.html'); | |||
}); | |||
</pre> | |||
You can also get the checked state, and prevent the button from being pressed, among other things: | |||
<pre> | |||
jQuery('<label id="'+cycle.run+'" ... | |||
.on('click', function(e){ | |||
var run = this.id; | |||
// Look for the (label->input) | |||
if (this.firstChild.checked) | |||
... | |||
// To prevent checked/pressed state if desired: | |||
e.stopPropagation(); | |||
} | |||
</pre> | |||
Button bars are represented by labels wrapped around inputs: | |||
<pre> | |||
<div class="btn-group live-buttons" data-toggle="buttons"><div class="btn-group"><label class="btn"><input type="checkbox">text... | |||
</pre> | |||
In that case use a change handler on the input: | |||
<pre> | |||
var label = jQuery('<label class="btn btn-sm btn-'+color+'"></label>').appendTo(action_button_bar); | |||
var input = jQuery('<input class="run-'+cmd+'" type="checkbox" autocomplete="off" value="'+cycle.run+'">').appendTo(label) | |||
.on('change', cycle.owned? function(){ | |||
patchPick(this.value,'{ "action" : "run-hold" }'); | |||
} : function() { | |||
patchPick(this.value,'{ "action" : "run-buy" }'); | |||
}); | |||
var text = jQuery('<span class="glyphicon glyphicon-'+glyph+'"></span> <span class="hidden-xs">'+cmd+'</span>').appendTo(label); | |||
</pre> | |||
If you just need clicks from the button bar, you do NOT NEED input: | |||
<pre> | |||
<div class="btn-group live-buttons" data-toggle="buttons"><div class="btn-group"><label class="btn">text... | |||
</pre> | |||
Then you can put the change handler right on the label: | |||
<pre> | |||
var applybar = jQuery('<div id="applybar-'+cycle.run+'" class="btn-group pull-right" data-toggle="buttons" />'); | |||
var apply_button = jQuery('<label id="apply-'+cycle.run+'" class="btn btn-sm btn-moneygreen"><span class="glyphicon glyphicon-ok"></span><span class="hidden-xs"> Apply</span></input></label>') | |||
.on('click', function(e) { | |||
// Do work | |||
e.stopPropagation(); | |||
}) | |||
.appendTo(applybar) | |||
; | |||
</pre> | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Programmatically pressing a button | |||
|- | |||
| You MUST DO TWO THINGS: | |||
* Set the active class on the button/label | |||
* Set the input to checked | |||
<label class="btn active"> | |||
<input type="checkbox" autocomplete="off" checked> | |||
Click me | |||
</label> | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Handling the UNCHECK event on a pushbutton | |||
|- | |||
| Again you MUST SET BOTH active and checked STATES PROPERLY when creating the button (see above). Do not set either if the button is unpressed; set both if it is pressed. | |||
Then you can use a single change event: | |||
$("input[type='checkbox'][class='run-hold-on-buy' ]").change(function() { patchPick(this.value,'{ "action" : "'+(this.checked?'hold-on-buy-on' :'hold-on-buy-off' )+'"}'); }); | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! Collapsible panel | |||
|- | |||
| | |||
* Use a unique id on content div, data-target to connect panel header to content, mdm-panel-collapser so javascript can find icon, abt-scrollable-panel for margin. | |||
* HTML for each panel (starts collapsed) | |||
<pre> | |||
<div class="panel panel-default abt-scrollable-panel"> | |||
<div class="panel-heading collapsed" data-toggle="collapse" data-target="#my-content-block-one">Software development skills<span class="mdm-panel-collapser text-muted glyphicon glyphicon-chevron-down pull-right"></span></div> | |||
<div class="collapse" id="my-content-block-one"> | |||
<div class="mdm-panel-body"> | |||
<!-- CONTENT, can include another nested panel, just add .mdm-nested-panel to class; example: --> | |||
<div class="panel panel-default mdm-scrollable-panel mdm-nested-panel"> | |||
<div class="panel-heading collapsed mdm-job-panel-heading" data-toggle="collapse" data-target="#toshiba-job"><p><strong>Senior Developer and Offshore Manager</strong><i> - Toshiba Global Commerce Solutions, Inc.</i><span class="mdm-panel-collapser text-muted glyphicon glyphicon-chevron-up pull-right"></span></p><p><small>April 2014 – August 2015</small></p></div> | |||
<div class="collapse in" id="toshiba-job"> | |||
<div class="mdm-panel-body"> | |||
<!-- SUBCONT(IN)ENT im so funny --> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
</pre> | |||
* For an expanded panel, simply change icon from down to up, and add "in" to content div: | |||
<pre> | |||
... glyphicon-chevron-up ... | |||
<div class="collapse in mdm-panel-body" id="collapseOrderItems1"> | |||
</pre> | |||
* Define Javascript collapser once on load | |||
$('.collapse').on('hide.bs.collapse show.bs.collapse', | |||
toggleCollapser | |||
); | |||
* CSS | |||
.mdm-nested-panel { | |||
margin-top: 1em; | |||
margin-left: 1em; | |||
} | |||
collapse.mdm-panel-body collapsing.mdm-panel-body { | |||
margin: 1em; | |||
} | |||
* Common reusable function: | |||
function toggleCollapser(e) { | |||
$(e.target) | |||
.prev('.panel-heading') | |||
.find('.mdm-panel-collapser') | |||
.toggleClass('glyphicon-chevron-down glyphicon-chevron-up'); | |||
// Prevent bubble up to any parent collapsers. | |||
// This allows nested collapsers, whoop. | |||
e.stopPropagation(); | |||
} | |||
|} | |||
|} | |||
<!-- | |||
=========================================================================================================================================================================================================================================================================================== | |||
--> | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! D3 | |||
|- | |||
| | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! ALWAYS initialize incoming data | |||
|- | |||
| Hard-earned data-import lessons: | |||
* tsv() will do complete date formatting, so when you remove it to use JSON directly, you HAVE TO convert JSON timestamps of ANY kind to full Javascript date objects: | |||
var data = [{"date":"2017-04-01T04:00:00.000Z",... | |||
// MDM WE MUST MASSAGE DATA HERE | |||
// JSON VALUES ARE ALWAYS STRINGS, we need to change to Javascript DATE! | |||
// Incoming datasets need a bit of massaging. | |||
// We do that in a function so we can reuse it on incoming dataset updates. | |||
function initializeDataset(dataset) { | |||
// TIME ON X | |||
// Convert date strings to actual date values. | |||
// MDM MAKE SURE this matches the incoming format. | |||
// Adding date so we can run the chart across days without trouble. | |||
// var parseDate = d3.time.format("%H:%M:%S %m-%d-%Y").parse; | |||
// var parseDate = d3.timeParse("%Y %b %d"); | |||
var parseDate = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ"); | |||
dataset.forEach(function(d) { | |||
// there is NO SKIPING THIS STEP, you have to get valid Javascript date objects out of JSON strings | |||
d.date = parseDate(d.date); | |||
// we WOULD have to divide all data by zero, | |||
// but we already grabbed post-data that was already converted | |||
// This WORKS but makes data / 10000 (very small numbers) | |||
//for (var i = 1, n = dataset.columns.length; i < n; ++i) d[dataset.columns[i]] = d[dataset.columns[i]] / 100; | |||
}); | |||
} | |||
initializeDataset(data); | |||
* tsv() will create an ARRAY but it also jams in a columns PROPERY; it takes two steps to duplicate that: | |||
var data = [ | |||
{"date":"2015-06-15T04:00:00.000Z","Google Chrome":0.48090000000000005,...}, | |||
{"date":"2015-06-22T04:00:00.000Z","Google Chrome":0.48979999999999996,...), | |||
]; | |||
data.columns = ["date","Google Chrome","Internet Explorer",... ]; | |||
|} | |||
{| class="mw-collapsible mw-collapsed wikitable" | |||
! ALWAYS set range and domain properly | |||
|- | |||
| You have to know your display size (range) and the min and max of your data (domain), on each axis. From [https://bost.ocks.org/mike/bar/ Mike's docs]: | |||
D3’s scales specify a mapping from data space (domain) to display space (range). | |||
D3’s scales can also be used to interpolate many other | |||
types of display-space values, such as paths, color spaces | |||
and geometric transforms. | |||
var x = d3.scale.linear() | |||
.domain([0, d3.max(data)]) | |||
.range([0, 420]); | |||
Although x here looks like an object, it is also a function | |||
that returns the scaled display value in the range | |||
for a given data value in the domain. | |||
For example, an input value of 4 returns 40, and an input value of 16 | |||
returns 160. To use the new scale, simply replace the | |||
hard-coded multiplication by calling the scale function: | |||
d3.select(".chart") | |||
.selectAll("div") | |||
.data(data) | |||
.enter().append("div") | |||
.style("width", function(d) { return x(d) + "px"; }) | |||
.text(function(d) { return d; }); | |||
Watch out for Mike's examples where he (trickily) doesn't bother to set a domain because his data is in the [0..1] set, and that's the default domain, apparently. | |||
|} | |||
|}<!-- | |||
=========================================================================================================================================================================================================================================================================================== | |||
--> | |||
{| class="wikitable" | {| class="wikitable" | ||
! [[Jquery]] | ! [[Jquery]] |
Revision as of 14:52, 3 March 2018
Basics
Bootstrap | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
D3 | ||||
---|---|---|---|---|
|
Jquery |
---|
Vega-lite |
---|