// Matthew Clapp // itsayellow@gmail.com // April 8, 2016 // // hbounds to restrict wave display between // mintick and maxtick (plus unavoidable after maxtick for // non-0.5-divisible phase and/or period) (function () { // hbounds to restrict wave display between // mintick and maxtick (plus unavoidable after maxtick for // non-0.5-divisible phase and/or period) // hbounds: num_data_dropped function num_data_dropped( in_wave, minchar ) { var eq_count = 0; var i=0; // count eq-signs before slice for (i=minchar-1; i >= 0; i-- ) { if (in_wave[i]==="=" || in_wave[i]==="3" || in_wave[i]==="4" || in_wave[i]==="5") { eq_count++; } } // if first char of slice is ., see if prev char to . // is a data char, and if so, eq_count-- if (in_wave[minchar] === ".") { for (i=minchar-1; i >= 0; i-- ) { if (in_wave[i] !== ".") { // first non-. char before . if (in_wave[i]==="=" || in_wave[i]==="3" || in_wave[i]==="4" || in_wave[i]==="5") { eq_count--; } break; } } } return eq_count; } // hbounds: mult_wave_chars function mult_wave_chars( wave_in, mult ) { var wave_out = ""; for ( var i=0; i < wave_in.length; i++ ) { // add mult-1 "." chars after every original char to // expand overall wave wave_out = wave_out + wave_in[i] + Array(mult).join("."); } return wave_out; } // hbounds: process_signal function process_signal(signal_obj, mintick_adj, maxtick_adj) { var remove_data_items; var period; var minchar_data; var maxchar; var phase_orig; var phase_adj; var period_div; if ( "period" in signal_obj ) { period = signal_obj.period; } else { period = 1.0; // default if not present } if ( "phase" in signal_obj ) { phase_orig = signal_obj.phase; } else { phase_orig = 0.0; // default if not present } // check if non-integer maxchar_adj, and attempt to increase wave resolution // to be as close as possible to ending on final tick if( (maxtick_adj + phase_orig) % period !== 0 && period>=1.0 ) { // find biggest integer to divide period by and still be > 0.5 period_div = Math.floor(period/0.5); // add period_div-1 "." after each original wave char //console.log( signal_obj.name + ": period=" + period + " to period=" + period/period_div ); // expand wave chars by factor of period_div signal_obj.wave = mult_wave_chars( signal_obj.wave, period_div ); period = period/period_div; signal_obj.period = period; } // last char to make sure is included maxchar = Math.ceil( (maxtick_adj + phase_orig)/period ); // earliest char shown, that the data can be applied to minchar_data = Math.floor( (mintick_adj + phase_orig)/period ); // how much to shift the phase to remove beginning part phase_adj = mintick_adj; // manage list-based data property if ( "data" in signal_obj ) { // find number of starting data items to remove from beginning of data // if we phase shift =,3,4,5 off screen we need to remove from data list remove_data_items = num_data_dropped( signal_obj.wave, minchar_data ); // DON'T USE SPLICE! CHANGES ORIG ARRAY EVEN IF ARRAY IS VARIABLE REUSED IN OTHER SIGNALS // instead use slice which returns a copy signal_obj.data = signal_obj.data.slice(remove_data_items); } // slice all character-based properties if ( "wave" in signal_obj ) { signal_obj.wave = signal_obj.wave.slice(0, maxchar); } if ( "node" in signal_obj ) { //signal_obj.node = signal_obj.node.slice(0, maxchar); // overwrite unseen node letters with "."s so we don't get arrows // off left as artifacts signal_obj.node = Array(minchar_data+1).join(".")+signal_obj.node.slice(minchar_data, maxchar); } // adjust phase if ( phase_adj !== 0 ) { if ( "phase" in signal_obj ) { signal_obj.phase = signal_obj.phase + phase_adj; } else { signal_obj.phase = phase_adj; } } return signal_obj; } // hbounds: hbounds // specify mintick and maxtick based on tick property of waveform object function hbounds(wave_obj, mintick, maxtick) { var mintick_adj, maxtick_adj; var tickzero_orig; if ( "head" in wave_obj && "tick" in wave_obj.head ) { tickzero_orig = wave_obj.head.tick; } else { tickzero_orig = 0; } mintick_adj = mintick - tickzero_orig; maxtick_adj = maxtick - tickzero_orig; if ( mintick_adj < 0 || maxtick_adj < 0 ) { throw "Error in hbounds: Can't use a mintick value less than tick property of head"; } for (var i=0; i < wave_obj.signal.length; i++) { if ( wave_obj.signal[i] instanceof Array ) { // element 0 is name of group, so start with 1 for (var j=1; j < wave_obj.signal[i].length; j++) { wave_obj.signal[i][j] = process_signal(wave_obj.signal[i][j], mintick_adj, maxtick_adj); } } else { wave_obj.signal[i] = process_signal(wave_obj.signal[i], mintick_adj, maxtick_adj); } } // modify tick settings if they exist if ( "head" in wave_obj ) { if ( "tick" in wave_obj.head ) { wave_obj.head.tick = wave_obj.head.tick + mintick_adj; } if ( "tock" in wave_obj.head ) { wave_obj.head.tock = wave_obj.head.tock + mintick_adj; } } return wave_obj; } // waveform obj var wavedrom_obj = { signal: [ {name: 'signal2.0', wave: '0.=.1.=.0.=.1.=.0.=.1.', data: ["hi","you","guys","are","you"], period: 2.0 }, {name: 'signal1.0', wave: '0...=...1...=...0...=...1...=...0...=...1...', data: ["hi","you","guys","are","you"],}, {name: 'signal0.5', wave: '0.......=.......1.......=.......0.......=.......1.......=.......0.......=.......1.......', period: 0.5, data: ["hi","you","guys","are","you"],}, {name: 'signal0.25',wave: '0...............=...............1...............=...............0...............=...............1...............=...............0...............=...............1...............', period: 0.25, data: ["hi","you","guys","are","you"],}, [ 'testgroup', {name: 'signal2.0', wave: '0.=.1.=.0.=.1.=.0.=.1.', data: ["hi","you","guys","are","you"], period: 2.0 }, {name: 'signal1.0', wave: '0...=...1...=...0...=...1...=...0...=...1...', data: ["hi","you","guys","are","you"],}, {name: 'signal0.5', wave: '0.......=.......1.......=.......0.......=.......1.......=.......0.......=.......1.......', period: 0.5, data: ["hi","you","guys","are","you"],}, ], ], head: { text:"hbounds test Timing", tick:0, }, }; // shift and clip waveform wavedrom_obj = hbounds(wavedrom_obj, 6, 26); // output waveform obj to wavedrom return wavedrom_obj; })() // vim: nowrap