Can use costume format? My charts work with $ dates:
jQuery(document).ready(function() {
var downloaded = [28683,62977,94111,146146,177601,200647,205921];
var viewTitle = '{if $currentLocale == 'en_US'}Example{else}Example{/if}';
var downloadTitle = 'Example';
var labelconvert = function(value) {
var val = Math.abs(value); if (val >= 1000) { val = (val / 100) + " K";} return val;};
var options= {
chart:{
toolbar:{show:!1},
height:200,
type:"area",
series:[{name:viewTitle,data:viewed},{name:downloadTitle,data:downloaded},],
yaxis:{show:1,labels:{formatter:labelconvert,},title:{text:xTitile,style:{fontSize:'12px',fontWeight:'bold',fontFamily:'Roboto',color:'#113060'}}},
yaxis: {
labels: {
formatter: function(value) {
var val = Math.abs(value)
if (val >= 1000) {
val = (val / 1000).toFixed(0) + ' K'
}
return val
}
}
}
yAxis: [
{
type: 'value',
position: 'left',
axisLabel: {
formatter: function (value) {
let val: string | number = Math.abs(value);
if (val >= 10 ** 3 && val < 10 ** 6) {
val = (val / 1000).toFixed(0) + ' K'
} else if (val >= 10 ** 6) {
val = (val / 1000000).toFixed(0) + ' M'
} else {
val = val;
}
return val
}
}
}
],
Related
I am using string.Replace to replace substring A
func removeIP(text string) string {
text = strings.Replace(text, "someWord", "**NewWord**", -1)
return text
}
func removeIPUsingRegex(text string) string {
var re = regexp.MustCompile(`\b` + "someWord" + `\b`) // I want to replace whole word only
text = re.ReplaceAllString(text, "**NewWord**")
}
The Issue I am facing here is, I want to replace a whole word only if is not supported by string replace.
As I have to replace for very very huge strings may be in GBs. Regex is very slow compare to string replace.
eg: text: "abcdef defgh /def/ .def/ =def= def xxxy" -> Replace def with DEF
output: "abcdef defgh /DEF/ .DEF/ =DEF= DEF xxxy" //Notice only whole words have been replaced.
Regex bumps the time by almost 100 times (https://medium.com/codezillas/golang-replace-vs-regexp-de4e48482f53). Any Ideas will be much appreciated.
KMP ALGorithm used
// ReplaceWholeWord ...
func ReplaceWholeWord(text string, oldWord string, newWord string) string {
var patternLength = len(oldWord)
var textLength = len(text)
var copyIndex = 0
var textIndex = 0
var patternIndex = 0
var newString strings.Builder
var lps = computeLPSArray(oldWord)
for textIndex < textLength {
if oldWord[patternIndex] == text[textIndex] {
patternIndex++
textIndex++
}
if patternIndex == patternLength {
startIndex := textIndex - patternIndex
endIndex := textIndex - patternIndex + patternLength - 1
if checkIfWholeWord(text, startIndex, endIndex) {
if copyIndex != startIndex {
newString.WriteString(text[copyIndex:startIndex])
}
newString.WriteString(newWord)
copyIndex = endIndex + 1
}
patternIndex = 0
textIndex = endIndex + 1
} else if textIndex < textLength && oldWord[patternIndex] != text[textIndex] {
if patternIndex != 0 {
patternIndex = lps[patternIndex-1]
} else {
textIndex = textIndex + 1
}
}
}
newString.WriteString(text[copyIndex:])
return newString.String()
}
func computeLPSArray(pattern string) []int {
var length = 0
var i = 1
var patternLength = len(pattern)
var lps = make([]int, patternLength)
lps[0] = 0
for i = 1; i < patternLength; {
if pattern[i] == pattern[length] {
length++
lps[i] = length
i++
} else {
if length != 0 {
length = lps[length-1]
} else {
lps[i] = length
i++
}
}
}
return lps
}
func checkIfWholeWord(text string, startIndex int, endIndex int) bool {
startIndex = startIndex - 1
endIndex = endIndex + 1
if (startIndex < 0 && endIndex >= len(text)) ||
(startIndex < 0 && endIndex < len(text) && isNonWord(text[endIndex])) ||
(startIndex >= 0 && endIndex >= len(text) && isNonWord(text[startIndex])) ||
(startIndex >= 0 && endIndex < len(text) && isNonWord(text[startIndex]) && isNonWord(text[endIndex])) {
return true
}
return false
}
func isNonWord(c byte) bool {
return !((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_'))
}
I'm extracting numbers from web page, and i want compare them, if
number is more than [previous one, then show it in iimDispaly(), otherwise if is it lower then skip, i trued here to do but cannot find a solution.
for(var i = 1; i <= 13; i++) {
for(var j = 3; j<=33; j+=3 ) {
iimPlayCode('TAG POS='+j+' TYPE=DIV ATTR=CLASS:"group_row_labeled" EXTRACT=TXT')
var res = iimGetLastExtract();
var result = res.replace(/[а-z]/g, '');
if(j==3) {
var firstRes = result;
}
if(result => firstRes) {
iimDisplay("Highest Number: " + result)
}
}
}
Copy & paste the following code and try to play it:
for(var i = 1; i <= 13; i++) {
for(var j = 3; j<=33; j+=3 ) {
iimPlayCode('TAG POS='+j+' TYPE=DIV ATTR=CLASS:"group_row_labeled" EXTRACT=TXT')
var res = iimGetLastExtract();
var result = parseFloat(res.replace(/[a-z]/g, ''));
if(j==3) {
var firstRes = result;
}
if(result >= firstRes) {
iimDisplay("Highest Number: " + result)
}
}
}
In the process of writing a regex to obtain the browser and version. This is what I have so far. Can anyone advise a better process? The regex will check for IE/Firefox/Safari/Chrome from this I can check the version number.
import flashx.textLayout.formats.BackgroundColor;
var inputField:TextField = new TextField();
var displayField:TextField = new TextField();
// RegExp
var reg:RegExp = /(MSIE|(?!Gecko.+)Firefox|(?!AppleWebKit.+Chrome.+)Safari|(?!AppleWebKit.+)Chrome|AppleWebKit(?!.+Chrome|.+Safari)|Gecko(?!.+Firefox) (SeaMonkey))(?: |\/)([\d]+)/i;
inputField.border = true;
inputField.width = 500;
inputField.height = 50;
inputField.x = 75;
inputField.y = 50;
inputField.type = "input";
inputField.multiline = true;
addChild(inputField);
displayField.border = true;
displayField.width = 500;
displayField.height = 200;
displayField.backgroundColor = 0x666666;
displayField.x = 75;
displayField.y = inputField.y + 50 + inputField.height;
displayField.multiline = true;
addChild(displayField);
inputField.addEventListener(Event.CHANGE, changeListener, false, 0, true);
function changeListener(event:Event):void
{
var strToTest:String = inputField.text;
var textToDisplay:String = "";
if(reg.test(strToTest))
{
var browser:String = strToTest.match(reg)[1];
var version:int = strToTest.match(reg)[2];
var chromeVersion:int = 29;
var firefoxVersion:int = 23;
var ieVersion:int = 7;
var safariVersion:int = 6;
textToDisplay += "BROWSER IS " + browser;
textToDisplay += "\nVersion " + version;
if(browser == "Chrome")
{
if(version <= chromeVersion)
{
textToDisplay += "\nUPDATE CHROME - VERSION BELOW " + chromeVersion;
}
else
{
textToDisplay += "\nVERSION GREATER THAN " + chromeVersion;
}
}
else if(browser == "MSIE")
{
if(version <= ieVersion)
{
textToDisplay += "\nUPDATE CHROME - VERSION BELOW " + ieVersion;
}
else
{
textToDisplay += "\nVERSION GREATER THAN " + ieVersion;
}
}
else if (browser == "Firefox")
{
if(version <= firefoxVersion)
{
textToDisplay += "\nUPDATE CHROME - VERSION BELOW " + firefoxVersion;
}
else
{
textToDisplay += "\nVERSION GREATER THAN " + firefoxVersion;
}
}
else if (browser == "Safari")
{
if(version <= safariVersion)
{
textToDisplay += "\nUPDATE CHROME - VERSION BELOW " + safariVersion;
}
else
{
textToDisplay += "\nVERSION GREATER THAN " + safariVersion;
}
}
}
else
{
textToDisplay = "Browser is NOT IE/FIREFOX/SAFARI/CHROME"
}
displayField.text = textToDisplay;
}
(MSIE(?!.+Opera)|Firefox(?!.+SeaMonkey)|Version(?=.+Safari)(?!.+Chrome)|Chrome)(?: |/)([\d]+)
I Simplified the Regex to follow these checks https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent.
I don't want to use a third party lib as I would like to understand as I may need to make changes. The following code appears to be returning correctly for what I want.
(MSIE(?!.+Opera)|Firefox(?!.+SeaMonkey)|Version(?=.+Safari)(?!.+Chrome)|Chrome)(?: |/)([\d]+)
I'm using ASGALLANT'S Hide/Show method shown here:
http://jsfiddle.net/asgallant/6gz2Q/
Except I have fourth data series called average. When a series is hidden or shown, I recalculate the average... by adjusting the fiddle above:
function showHideSeries () {
var sel = chart.getChart().getSelection();
var view = chart.getView() || {};
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row == null) {
var col = sel[0].column;
if (typeof(columns[col]) == 'number') {
var src = columns[col];
// hide the data series
columns[col] = {
label: datatable.getColumnLabel(src),
type: datatable.getColumnType(src),
sourceColumn: src,
calc: function () {
return null;
}
};
//record as hidden
hiddenSeries[col] = true;
// grey out the legend entry
series[columnsMap[src]].color = '#CCCCCC';
chart.setOption('series', series);
//If Exists a columnLabel called "Average", check if last column (average column is currently shown), recalculate average
if ((datatable.getColumnLabel(datatable.getNumberOfColumns() - 1) == 'Average') && (hiddenSeries[datatable.getNumberOfColumns() - 1] == false)){
for(var r = 0; r < datatable.getNumberOfRows(); ++r) {
sum = 0;
k = 0
for(var c = 1; c < datatable.getNumberOfColumns()-1; ++c) {
if(hiddenSeries[c] == false){
if(datatable.getValue(r, c) > 0){
sum = sum + datatable.getValue(r, c);
k = k + 1;
}
}
}
if (k == 0) k = 1;
datatable.setValue(r, datatable.getNumberOfColumns() - 1, sum/k);
}
}
var tmpColumn = new Array();
// Add each data value to the array with push()
for(var i = 0; i < datatable.getNumberOfRows(); ++i) {
tmpColumn.push(datatable.getValue(i, col));
}
}
else {
var src = columns[col].sourceColumn;
// show the data series
columns[col] = src;
series[columnsMap[src]].color = null;
//record as shown
hiddenSeries[col] = false;
//If Exists a columnLabel called "Average", check if last column (average column is currently shown), recalculate average
if ((datatable.getColumnLabel(datatable.getNumberOfColumns() - 1) == 'Average') && (hiddenSeries[datatable.getNumberOfColumns() - 1] == false)){
for(var r = 0; r < datatable.getNumberOfRows(); ++r) {
sum = 0;
k = 0;
for(var c = 1; c < datatable.getNumberOfColumns() - 1; ++c) {
if(hiddenSeries[c] == false){
if(datatable.getValue(r, c) > 0){
sum = sum + datatable.getValue(r, c);
k = k + 1;
}
}
}
if (k == 0) k = 1;
datatable.setValue(r, datatable.getNumberOfColumns() - 1, sum/k);
}
}
//chart.setOption('series.' + i + '.type', 'bars');
if(datatable.getColumnLabel(src) == 'Average' || datatable.getColumnLabel(src) == 'Peak Demand [kVA]'){
chart.getOptions().series[columnsMap[src]].type = 'line';
if(c.second_axis == true){
chart.getOptions().series[columnsMap[src]].targetAxisIndex = 1;
}
}
}
chart.setDataTable(datatable);
view.columns = columns;
chart.setView(view);
google.visualization.events.addListener(chart, 'ready', function() {
document.getElementById('chartImg').href = chart.getChart().getImageURI();
});
chart.draw();
}
}
}
It works great, except that the Standard tooltip is not being updated on the re-draw of the chart. I would like to avoid using custom tooltips as a solution. I would think that the ToolTip values should automatically update on each draw of the chart... if not, there must be a way to force it?
The issue here is that I was using formatted numbers as shown below:
var formatter = new google.visualization.NumberFormat(
{negativeColor: 'red', negativeParens: true, pattern: '###,###'});
formatter.format(datatable, i);
Therefore, not only did I have to use datatable.setValue(row, column, value) but I also have to use datatable.setFormattedValue(row, column, *String* value).
Having the following map:
function (doc, meta) {
emit(dateToArray(doc.timestamp), doc.user_id);
}
What changes to I need on this reduce to get a count of user_ids that occur more than once?
function(key, values, rereduce) {
var counts = {}, id;
for (var i = 0; i < values.length; i++) {
id = values[i].replace('-', '_');
counts[id] = counts[id] || 0;
counts[id] = counts[id] + 1;
}
var total = 0;
for (id in counts) {
if (counts[id] > 1) total++;
}
return total;
}
I tried it on plain JS passing some array of values, and it works as I expected. Debugging is difficult on Couchbase though (or I don't know how), and I'm not seeing any errors on the error.1 and mapreduce_errors.1 files.
Update: I've been doing some crude debugging, going line by line, and this is what I have so far:
function(key, values, rereduce) {
var counts = {}, total = 0;
for (var i = 0; i < values.length; i++) {
var id = values[i];
if (id.indexOf('id_') != 0) id = 'id_' + values[i].replace(/-/g, '_');
return id;
counts[id] = counts[id] || 0;
counts[id] = counts[id] + 1;
}
for (id in counts) {
if (counts[id] > 1) total++;
}
return total;
}
Notice the return id; line. It returns a modified uuid, prefixed by "id_", just like you'd expect by looking at the code.
But then, if I change that line to return counts; or return total;, the result from Couchbase is "The results of this view is empty." What gives?
It was one painful debugging session, but here's the final solution:
function(key, values, rereduce) {
var counts = {}, total = 0, id;
if (rereduce) {
for (var set in values) {
for (var i in values[set]) {
counts[i] = (counts[i] || 0) + values[set][i];
}
}
for (f in counts) {
if (counts[f] > 1) total++;
}
return total;
} else {
for (var i in values) {
id = 'id_' + values[i].replace(/-/g, '_');
counts[id] = (counts[id] || 0) + 1;
}
return counts;
}
}
An extra lesson learned: Couchbase won't return big objects off of a reduce operation. Gotta learn more about that.