AngularJS: How to access scope from directive - angularjs-directive

I'm using a directive to draw graphs:
drawGraph.directive "graph", ->
restrict: "E" # Use as element
scope: # Isolate scope
data: "=" # Two-way bind data to local scope
opts: "=?" # '?' means optional
template: "<div></div><div id='{{graph.id}}'></div>" # We need a div to attach graph to
link: (scope, elem, attrs) ->
graph = new Dygraph(elem.children()[0], scope.data, scope.opts)
While
<div id='{{graph.id}}'>
actually works in the partial, it returns
<div id></div>
when I use it in the template of the directive. Can anyone tell me why?
Update:
After the hint of #Marek, my directive now looks like this:
drawGraph.directive "graph", ->
restrict: "E" # Use as element
scope: # Isolate scope
data: "=" # Two-way bind data to local scope
opts: "=?" # '?' means optional
template: "<div></div><div class='legend'></div>" # We need a div to attach graph to
link: (scope, elem, attrs) ->
scope.opts.labelsDiv = elem.children()[0].getElementsByClassName("legend")[0]
scope.graph = new Dygraph(elem.children()[0], scope.data, scope.opts)
Options are added in the controller:
drawGraph.controller "MyCtrl", [ "myService", "$scope", (myService, $scope) ->
myService.async().then (d) ->
rawData = d
group = rawData
i = 0
while i < group.length
j = 0
while j < group[i].data.length
# Convert date
tmp = new Date(group[i].data[j][0])
group[i].data[j][0] = tmp
# Set draw options
group[i].opts =
labels: [ "x", "Your Price", "Market Price" ],
customBars: true,
labelsSeparateLines: "true",
hideOverlayOnMouseOut: false,
legend: "always",
showRangeSelector: true,
xAxisLabelWidth: 80,
++j
++i
$scope.graphs = group

Problem was that an isolated scope can't access the parent scope by default, so "id" needs to be defined in the scope of the directive.
drawGraph.directive "graph", [(graph) ->
restrict: "E"
scope:
data: "="
opts: "=?"
id: "="

You're not actually putting the graph into the scope.
The last line should be:
scope.graph = new Dygraph(elem.children()[0], scope.data, scope.opts)

Related

Graph not showing

I have the following code
# -*- coding: utf-8 -*-
# # Two Pie Charts
import time
import dash
import dash_bootstrap_components as dbc
import plotly.express as px
import pandas as pd
from dash import Input, Output, dcc, html
# Data treatment
df = pd.read_csv('https://raw.githubusercontent.com/JorgeMiguelGomes/LEG2022_MediaMonitor/main/legislativas_2022_media_monitor_29jan2022/data_products/legislativas_2022_final_dataset_percentages.csv')
df_individuals = pd.read_csv('https://raw.githubusercontent.com/JorgeMiguelGomes/LEG2022_MediaMonitor/main/legislativas_2022_media_monitor_29jan2022/data_products/legislativas_2022_all_candidates_filtered.csv')
df_individuals = df_individuals.drop(columns=["Unnamed: 0"])
df_indivuduals = df_individuals.drop(columns=["Post Created Date"])
df_individuals_melt=pd.melt(df_individuals,id_vars=['candidato','Page Name'])
# Styling
pie_color_map = {
"Angry":"#EB9486",
"Love":"#CAE7B9"
}
app = dash.Dash(external_stylesheets=[dbc.themes.BOOTSTRAP],suppress_callback_exceptions=True,
meta_tags=[{"name": "viewport", "content": "width=device-width, initial-scale=1"}],
)
app.layout = dbc.Container(
[
# First Row
dbc.Row(
[
dbc.Col(html.Hr(style={'borderWidth': "2vh", "width": "100%", "borderColor": "#CAE7B9","opacity": "unset"}),width={'size':2}),
dbc.Col(html.Hr(style={'borderWidth': "2vh", "width": "100%", "borderColor": "#F3DE8A","opacity": "unset"}),width={'size':2}),
dbc.Col(html.Hr(style={'borderWidth': "2vh", "width": "100%", "borderColor": "#EB9486","opacity": "unset"}),width={'size':2}),
dbc.Col(html.Hr(style={'borderWidth': "2vh", "width": "100%", "borderColor": "#7E7F9A","opacity": "unset"}),width={'size':2}),
dbc.Col(html.Hr(style={'borderWidth': "2vh", "width": "100%", "borderColor": "#97A7B3","opacity": "unset"}),width={'size':2}),
],className="g-0",
), # end of first row
dbc.Tabs(
[
dbc.Tab(label="About", tab_id="method", label_style={"color": "#CAE7B9"},tab_style={'background-color': '#97A7B3'},active_label_style={"background-color":"#080808"}),
dbc.Tab(label="Metrics by Totals", tab_id="totals", label_style={"color": "#F3DE8A"},tab_style={'background-color': '#7E7F9A'}, active_label_style={"background-color":"#080808"}),
dbc.Tab(label="Stacked Analysis", tab_id="stacked", label_style={"color": "#EB9486"},tab_style={'background-color': '#F3DE8A'}, active_label_style={"background-color":"#080808"}),
dbc.Tab(label="Love vs Angry", tab_id="love_angry", label_style={"color": "#7E7F9A"},tab_style={'background-color': '#EB9486'}, active_label_style={"background-color":"#080808"}),
dbc.Tab(label="Conclusions", tab_id="conclusions", label_style={"color": "#97A7B3"},tab_style={'background-color': '#F3DE8A'}, active_label_style={"background-color":"#080808"}),
],
id="tabs",
active_tab="love_angry", # this is the tab that will be active when the user comes to the website
), # end of tabs
html.Div(id="tab-content", className="p-5"),
]
)
# Callbacks
# Pie Chart for Candidates
# #app.callback(
# Output(component_id='graph_individuals', component_property='figure'),
# [Input(component_id='dropdown_candidates', component_property='value')],
# )
# def build_graph_individuals(column_chosen):
# dff = df
# totals_sentiment = dff.groupby(['candidato'])[['Love','Angry']].sum().reset_index()
# totals_sentiment_melt = pd.melt(totals_sentiment,id_vars="candidato")
# totals_sentiment_melt = totals_sentiment_melt[totals_sentiment_melt['candidato'] == column_chosen]
# fig_individuals = px.pie(totals_sentiment_melt,names="variable",values="value",hole=0.5, color="variable",color_discrete_map=pie_color_map)
# candidato_filter = column_chosen
# return fig_individuals
# Pie Chart for Media Outlets
#app.callback(
Output(component_id='graph_shares_comments', component_property='figure'),
Output(component_id='graph_individuals', component_property='figure'),
Input(component_id='dropdown_media_outlet', component_property='value'),
Input(component_id='dropdown_candidates', component_property='value')
)
def build_graphs(column_chosen, candidato_filter):
# Data Treatment for candidate graph
dff = df
totals_sentiment = dff.groupby(['candidato'])[['Love','Angry']].sum().reset_index()
totals_sentiment_melt = pd.melt(totals_sentiment,id_vars="candidato")
totals_sentiment_melt = totals_sentiment_melt[totals_sentiment_melt['candidato'] == column_chosen]
# Data Treatment for media graph
dff_m = df[df['candidato']== candidato_filter]
print(dff_m)
totals_sentiment_media = dff_m.groupby(['Page Name'])[['Love','Angry']].sum().reset_index()
totals_sentiment_media_melt = pd.melt(totals_sentiment_media,id_vars="Page Name")
totals_sentiment_media_melt = totals_sentiment_media_melt[totals_sentiment_media_melt['Page Name'] == column_chosen]
print("HELLO HELLO")
print(totals_sentiment_media_melt)
# Pice Charts
fig_candidates = px.pie(totals_sentiment_melt,names="variable",values="value",hole=0.5, color="variable",color_discrete_map=pie_color_map)
fig_media = px.pie(totals_sentiment_media_melt,names="variable",values="value",hole=0.6, color="variable",color_discrete_map=pie_color_map)
return fig_candidates, fig_media
# TABS CALLBACKS -------------------------------------
#app.callback(Output("tab-content", "children"),
[Input("tabs", "active_tab")])
def switch_tab(at):
if at == "love_angry":
tab4_content = dbc.Row(
[
dbc.Col(
[
dcc.Dropdown(
id='dropdown_candidates',
options=[{'label': i, 'value': i} for i in df_individuals_melt.candidato.unique()
],
optionHeight=35, #height/space between dropdown options
value='António Costa', #dropdown value selected automatically when page loads
disabled=False, #disable dropdown value selection
multi=False, #allow multiple dropdown values to be selected
searchable=True, #allow user-searching of dropdown values
search_value='', #remembers the value searched in dropdown
placeholder='Please select...', #gray, default text shown when no option is selected
clearable=True, #allow user to removes the selected value
style={'width':"100%"}, #use dictionary to define CSS styles of your dropdown
# className='select_box', #activate separate CSS document in assets folder
# persistence=True, #remembers dropdown value. Used with persistence_type
# persistence_type='memory' #remembers dropdown value selected until...
),
dbc.Col(
dcc.Graph(id='graph_individuals'),
),
],width={'size':6, 'offset':0}
),
dbc.Col(
[
dcc.Dropdown(
id='dropdown_media_outlet',
options=[{'label': i, 'value': i} for i in df['Page Name'].unique()
],
optionHeight=35, #height/space between dropdown options
value='Agência Lusa', #dropdown value selected automatically when page loads
disabled=False, #disable dropdown value selection
multi=False, #allow multiple dropdown values to be selected
searchable=True, #allow user-searching of dropdown values
search_value='', #remembers the value searched in dropdown
placeholder='Please select...', #gray, default text shown when no option is selected
clearable=True, #allow user to removes the selected value
style={'width':"100%"}, #use dictionary to define CSS styles of your dropdown
# className='select_box', #activate separate CSS document in assets folder
# persistence=True, #remembers dropdown value. Used with persistence_type
# persistence_type='memory' #remembers dropdown value selected until...
),
dbc.Col(
dcc.Graph(id='graph_shares_comments'),
),
],width={'size':6, 'offset':0}
),
],
),
return tab4_content
# Error Message
return html.P("FOR SUPPORT PURPOSES ONLY")
if __name__ == "__main__":
app.run_server(debug=True, port=8888)
The code is running without errors but as you can see in the image below, the chart on the left side is not rendering, and I'm totally lost.
I have inserted a print command in the script, and when I change the dropdowns the values change accordingly as they should.
However the pie chart remains empty, like it's not getting any information.
Maybe I've been looking at the same code for more hours than I should, and I'm missing something really simple, but I just can't spot it.
Any help would be really appreciated.
Disclosure This is not a commercial project nor will I use it in any commercial way.
You were filtering with the wrong keyword for totals_sentiment_melt, use this to correct it:
totals_sentiment_melt = totals_sentiment_melt[totals_sentiment_melt['candidato'] == candidato_filter]

how to provide options in json-diff when running from node js program

I am working on a simple JSON comparison code that compares two JSON files.
I found json-diff npm module that does exactly what I want. I want to use it with the -k option (compare only keys). Here is the documentation: https://www.npmjs.com/package/json-diff
I can do it in the cmd directly using the command:
json-diff a.json b.json -k
But I'm not able to figure out how do I provide the "options" when writing a node js code.
This is what I have tried but it did not work out.
var jsonDiff = require('json-diff')
console.log(jsonDiff.diffString({ foo: 'bar' }, { foo: 'baz' }, '-k'));
You need to pass the options as the last parameter (for .diff there are 3 parameters)
var jsonDiff = require('json-diff')
console.log(jsonDiff.diff({ foo: 'bar' }, { foo: 'baz' }, {keysOnly: true}));
For diffString there are four params (the 3rd being the colorize options, and the 4th the options)
var jsonDiff = require('json-diff')
console.log(jsonDiff.diffString({ foo: 'bar' }, { foo: 'baz' }, undefined, {keysOnly: true}));

Replace and access values in nested hash/json by path in Ruby

Asking for a advice what would be in your opinion best and simple solution to replace and access values in nested hash or json by path ir variable using ruby?
For example imagine I have json or hash with this kind of structure:
{
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}
And I would like to access or change fixed mobile number by path which could be specified in variable like this: "phone_numbers/1/number" (separator does not matter in this case)
This solution is necessary to retrieve values from json/hash and sometimes replace variables by specifying path to it. Found some solutions which can find value by key, but this solution wouldn't work as there is some hashes/json where key name is same in multiple places.
I saw this one: https://github.com/chengguangnan/vine , but it does not work when payload is like this as it is not kinda hash in this case:
[
{
"value":"test1"
},
{
"value":"test2"
}
]
Hope you have some great ideas how to solve this problem.
Thank you!
EDIT:
So I tried code below with this data:
x = JSON.parse('[
{
"value":"test1"
},
{
"value":"test2"
}
]')
y = JSON.parse('{
"name":"John",
"address":{
"street":"street 1",
"country":"country1"
},
"phone_numbers":[
{
"type":"mobile",
"number":"234234"
},
{
"type":"fixed",
"number":"2342323423"
}
]
}')
p x
p y.to_h
p x.get_at_path("0/value")
p y.get_at_path("name")
And got this:
[{"value"=>"test1"}, {"value"=>"test2"}]
{"name"=>"John", "address"=>{"street"=>"street 1", "country"=>"country1"}, "phone_numbers"=>[{"type"=>"mobile", "number"=>"234234"}, {"type"=>"fixed", "number"=>"2342323423"}]}
hash_new.rb:91:in `<main>': undefined method `get_at_path' for [{"value"=>"test1"}, {"value"=>"test2"}]:Array (NoMethodError)
For y.get_at_path("name") got nil
You can make use of Hash.dig to get the sub-values, it'll keep calling dig on the result of each step until it reaches the end, and Array has dig as well, so when you reach that array things will keep working:
# you said the separator wasn't important, so it can be changed up here
SEPERATOR = '/'.freeze
class Hash
def get_at_path(path)
dig(*steps_from(path))
end
def replace_at_path(path, new_value)
*steps, leaf = steps_from path
# steps is empty in the "name" example, in that case, we are operating on
# the root (self) hash, not a subhash
hash = steps.empty? ? self : dig(*steps)
# note that `hash` here doesn't _have_ to be a Hash, but it needs to
# respond to `[]=`
hash[leaf] = new_value
end
private
# the example hash uses symbols as the keys, so we'll convert each step in
# the path to symbols. If a step doesn't contain a non-digit character,
# we'll convert it to an integer to be treated as the index into an array
def steps_from path
path.split(SEPERATOR).map do |step|
if step.match?(/\D/)
step.to_sym
else
step.to_i
end
end
end
end
and then it can be used as such (hash contains your sample input):
p hash.get_at_path("phone_numbers/1/number") # => "2342323423"
p hash.get_at_path("phone_numbers/0/type") # => "mobile"
p hash.get_at_path("name") # => "John"
p hash.get_at_path("address/street") # => "street 1"
hash.replace_at_path("phone_numbers/1/number", "123-123-1234")
hash.replace_at_path("phone_numbers/0/type", "cell phone")
hash.replace_at_path("name", "John Doe")
hash.replace_at_path("address/street", "123 Street 1")
p hash.get_at_path("phone_numbers/1/number") # => "123-123-1234"
p hash.get_at_path("phone_numbers/0/type") # => "cell phone"
p hash.get_at_path("name") # => "John Doe"
p hash.get_at_path("address/street") # => "123 Street 1"
p hash
# => {:name=>"John Doe",
# :address=>{:street=>"123 Street 1", :country=>"country1"},
# :phone_numbers=>[{:type=>"cell phone", :number=>"234234"},
# {:type=>"fixed", :number=>"123-123-1234"}]}

Check_MK - Custom check params specified in wato not being given to check function

I am working on a check_mk plugin and can't seem to get the WATO specified params passed to the check function when it runs for one check in particular...
The check param rule shows in WATO
It writes correct looking values to rules.mk
Clicking the Analyze check parameters icon from a hosts service discovery shows the rule as active.
The check parameters displayed in service discovery show the title from the WATO file so it seems like it is associating things correctly.
Running cmk -D <hostname> shows the check as always having the default values though.
I have been staring at it for awhile and am out of ideas.
Check_MK version: 1.2.8p21 Raw
Bulk of check file:
factory_settings["elasticsearch_status_default"] = {
"min": (600, 300)
}
def inventory_elasticsearch_status(info):
for line in info:
yield restore_whitespace(line[0]), {}
def check_elasticsearch_status(item, params, info):
for line in info:
name = restore_whitespace(line[0])
message = restore_whitespace(line[2])
if name == item:
return get_status_state(params["min"], name, line[1], message, line[3])
check_info['elasticsearch_status'] = {
"inventory_function" : inventory_elasticsearch_status,
"check_function" : check_elasticsearch_status,
"service_description" : "ElasticSearch Status %s",
"default_levels_variable" : "elasticsearch_status_default",
"group" : "elasticsearch_status",
"has_perfdata" : False
}
Wato File:
group = "checkparams"
#subgroup_applications = _("Applications, Processes & Services")
register_check_parameters(
subgroup_applications,
"elasticsearch_status",
_("Elastic Search Status"),
Dictionary(
elements = [
( "min",
Tuple(
title = _("Minimum required status age"),
elements = [
Age(title = _("Warning if below"), default_value = 600),
Age(title = _("Critical if below"), default_value = 300),
]
))
]
),
None,
match_type = "dict",
)
Entry in rules.mk from WATO rule:
checkgroup_parameters.setdefault('elasticsearch_status', [])
checkgroup_parameters['elasticsearch_status'] = [
( {'min': (3600, 1800)}, [], ALL_HOSTS ),
] + checkgroup_parameters['elasticsearch_status']
Let me know if any other information would be helpful!
EDIT: pls help
Posted question here as well and the mystery got solved.
I was matching the WATO rule to item None (5th positional arg in the WATO file), but since this check had multiple items inventoried under it (none of which had the id None) the rule was applying to the host, but not to any of the specific service checks.
Fix was to replace that param with:
TextAscii( title = _("Status Description"), allow_empty = True),

Function default arguments and named values

Let's say I have an R function in which the arguments can be a one of a few predefined named values (one of which is the default) or a custom character vector. How should I implement this without relying on magic value names or another flag?
#allow use of predefined subsets or pass their own list
bratPack<-function(members='CORE',...){
if (members=='CORE')
members<-c('Emilio Estevez','Anthony Michael Hall','Rob Lowe','Andrew McCarthy','Demi Moore','Judd Nelson','Molly Ringwald','Ally Sheedy')
else if (members=='ALL')
members<-c('Emilio Estevez','Anthony Michael Hall','Rob Lowe','Andrew McCarthy','Demi Moore','Judd Nelson','Molly Ringwald','Ally Sheedy','James Spader','Robert Downey, Jr.','Jon Cryer', 'John Cusack', 'Kevin Bacon', 'Jami Gertz', 'Mary Stuart Masterson', 'Matthew Broderick', 'Sean Penn', 'Kiefer Sutherland')
...
}
From your example we have the choice of "CORE" and "ALL". If those are the two options, then we specify them in the function definition for the argument 'members'. E.g.:
foo <- function(x, members = c("CORE", "ALL")) {
## do something
}
That function definition sets up the allowed values for argument 'members', with a default of "CORE" as this is the first named option.
The code that one uses within the function body is match.arg(), as #Joris has already mentioned, but because we have set the function up as above, we can simply the usage to just match.arg(members).
So we can write foo as:
foo <- function(x, members = c("CORE", "ALL")) {
## evaluate choices
members <- match.arg(members)
## do something
print(members)
}
Which we use like this:
> foo()
[1] "CORE"
> foo(members = "CORE")
[1] "CORE"
> foo(members = "ALL")
[1] "ALL"
> foo(members = "3rdRate")
Error in match.arg(members) : 'arg' should be one of “CORE”, “ALL”
Notice the behaviour when we supply an string not included in the set of options. We get an intuitive error message, all because we set up the options in the function arguments.
I'd use some constant dataframe somewhere in the package:
.mdata <- data.frame(
CORE= c(TRUE,FALSE,TRUE),
OLD = c(TRUE,TRUE,FALSE),
ALL = c(TRUE,TRUE,TRUE),
row.names=c("John Doe", "Jan Janssen", "Piet Peters")
)
bratPack<-function(members='CORE',...){
m.tmp <- try(
match.arg(members,names(.mdata),several.ok=T),
silent=T)
if(!is(m.tmp,"try-error"))
members <- rownames(.mdata)[.mdata[[members]]]
print(members)
}
> bratPack('CORE')
[1] "John Doe" "Piet Peters"
> bratPack('Jan Janssen')
[1] "Jan Janssen"
> bratPack(c("John Doe","Dick Dickers"))
[1] "John Doe" "Dick Dickers"