I'm very new to SVG (using D3.js to call everything). Recently, I just came into a huge limitation with a project I am working on. I want to be able to make "g" classes for each category of data I am working with. Unfortunately, I am getting my data from an XML file that only connects data in one way (ex: person1 ---> person2, but not person2 ---> person1). What I would like to be able to do is to put each shape generated from my data in the root class AND the class it is connecting with. If I could add this shape to two or more classes (such as g class = person1 and person2), that would be the fastest solution I believe...But is something like this possible? Can I set an SVG shape to two or more classes? Or will it overwrite it as I define new ones.
I really hope someone can understand what I am asking. It is kind of hard to verbalize my problem without giving away every detail of my final project.
Yes, you can set multiple classes. For example,
<g class="person1 person2">
Or, in D3:
g.attr("class", "person1 person2");
One more note: If you're calling a function from within a file:
.attr("class",function(d) { return d.person1+" "+ d.person2;} )
Related
I'm using Code Mirror to create a simple code editor that creates shapes on a canvas based on certain commands. I would like to use Code Mirror's annotations to store a shape ID in the line's metadata. That way when I delete a line on the commands I can easily tell the Canvas which shape to delete.
I've been looking through the code mirror's documentation for a while now and still have no idea how I would go about implementing this.
How can I access the metadata (annotations) in text with CodeMirror?
Any help is much appreciated.
Okay, I figured it out. CodeMirror has a function "markText" which can be used to give a className to the line for specific CSS styling. It can also be used to pass in any other parameters including user-created ones like shapeID.
// Give a line an ID
function giveLineID(lineIndex,id){
editor.markText( {line:lineIndex,ch:0},{line:lineIndex,ch:line.length},{shapeID : id});
}
// Retrieve an ID from a line
function retrieveID(lineIndex){
var line = myCodeMirror.getLine(lineIndex);
var marks = cm.findMarks({line:lineIndex,ch:0},{line:lineIndex,ch:line.length});
marks.forEach(mark => {
if (mark.hasOwnProperty("shapeID")){
return mark["shapeID"];
}
});
}
I'm having trouble wrapping my head around how to represent a class/object as an image or div on the browser screen. The div would have attributes, and methods. Say I'm making a game where enemy spaceships appear randomly, moving around.
So do I JQuery.append a div tag with every instance creation? How do I connect/bind the div to the class?
Or is there a MVC frame that'll be more efficient?
thanks.
First of all, MVC's not necessarily a perfect fit for a game, but understanding it could help you get a better handle on OOP and something similar could make sense.
Assume CSS as appropriate setting background images, making .spaceObject elements absolute and defaulting at 0,0 and making body an actual set width/height box, etc...
JS doesn't have classes. It uses function constructors instead. I do not recommend attempting to emulate classes. There's nothing wrong with constructors and they actually have some nifty advantages when you get deeper into prototypes and the like.
function BuildSpaceDiv(divID){
var $_spaceDiv = $('<div id="'+divID+'" class="spaceObject" />').appendTo('body');
this.move = function(x,y){
$_spaceDiv.animate({ top:x, left:y });
}
}
Without using the new keyword it works just like a function. You use the new keyword to create an object/instance (not class/object, that's diagram and thing built, object and instance are the interchangeable terms).
var deathSun = new BuildSpaceDiv('death_sun');
You can make as many as you want or add new args to set starting coords, etc... I'm fond of using options objects with my JS constructors. Note that it still fires like a function so building an instance can have side effects if you want and that the $_spaceDiv var is unique to every instance and persistent.
I am trying to bind a property of an object to a property that's bound in an ArrayController. I want all of this to occur after the object has already been created and added to the ArrayController.
Here is a fiddle with a simplified example of what I'm trying to achieve.
I am wondering if I'm having problems with scope - I've already tried to bind to the global path (i.e. 'App.objectTwoController.objectOne.param3') to set the binding to. I've also tried to bind directly to the objectOneController (which is not what I want to do, but tried it just to see if it worked) and that still didn't work.
Any ideas on what I'm doing incorrectly? Thanks in advance for taking the time to look at this post.
So in the example below (I simplified it a little bit, but same principles apply)... The method below ends up looking for "objectOne" on "objectTwo" instead of on the "objectTwoController".
var objectTwoController: Em.Object.create({
objectOneBinding: 'App.objectOne',
objectTwoBinding: 'App.objectTwo',
_onSomething: function() {
var objectTwo = this.get('objectTwo');
objectTwo.bind('param2', Em.Binding.from('objectOne.param3'));
}.observes('something')
});
The problem is that you can't bind between two none relative objects. If you look in the "connect" method in ember you will see that it only takes one reference object (this) in which to observe both paths (this is true for 9.8.1 from your example and the ember-pre-1.0 release).
You have few options (that I can think of at least).
First: You can tell the objects about each other and in turn the relative paths will start working. This will actually give "objectTwo" an object to reference when binding paths.
....
objectTwo.set('objectOne', this.get('objectOne');
....
Second: You could add your own observer/computed property that will just keep the two in sync (but it is a little more verbose). You might be able to pull off something really slick but it maybe difficult. Even go so far as writing your own binding (like Transforms) to allow you to bind two non-related objects as long as you have paths to both.
_param3: function(){
this.setPath('objectTwo.param2', this.getPath('objectOne.param3');
}.observes('objectOne.param3')
You can make these dynamically and not need to pre-define them...
Third: Simply make them global paths; "App.objectOneController.content.param3" should work as your binding "_from" path (but not sure how much this helps you in your real application, because with larger applications I personally don't like everything global).
EDIT: When setting the full paths. Make sure you wait until end of the current cycle before fetching the value because bindings don't always update until everything is flushed. Meaning, your alert message needs to be wrapped in Ember.run.next or you will not see the change.
I've got a web page with a US map that has clickable paths that generate a popup, coded with Raphael.js and a paths file containing all the state's paths. I loop through the paths file to create the paths and set the onClick and hover functions for the popups.
I have one path that is not a state, it is a border around the misplaced Alaska and Hawaii. Problem is when I loop through the code, it gets set to fill and onClick functions same as the other paths.
I know I need a conditional in there to change attributes for that one path, but I'm not savvy enough to be able to code it correctly. Maybe access the DOM through node, but I'm not sure how/where.
Map created with this script.
paths set with /js/paths.js
css is /css/default.css
I've searched the archive and gotten close to a solution from info posted there, but I'm banging my head trying to tweak it to work - any help GREATLY appreciated!!!
The border is called "BD" so you can do something like this or even create a different borderAttributes object and assign different attributes when country == "BD"
for (var country in paths) {
var obj = r.path(paths[country].path);
if (country != "BD") {
obj.attr(attributes);
}
arr[obj.id] = country;
I've got this page I'm doing some tests in Javascript and jQuery: JS Tests
I've got a few questions on how to create, not sure if this is right term, but compound controls via Javascript. In something like Flash, you'd create the Object class, have the getters and setters, draw your images, etc. In JS, it seems to be a very different thought process. My main question is How do you create multiple elements with getters and setters to be rendered, filtered, and interacted with in Javascript?
The main code regarding this example sits with:
var html = (function(){
// var FRAG = $(document.createDocumentFragment());
htmlBox = $(document.createElement("div"));
var eTitle = $(document.createElement("h4"));
var ePrice = $(document.createElement("p"));
// set class first
htmlBox.addClass("box")
htmlBox.css({
backgroundColor : color
})
// set text values
eTitle.text(title);
ePrice.text("$" + price);
htmlBox.append(eTitle)
htmlBox.append(ePrice)
return htmlBox;
})();
... inside the Box() class. If someone could take a look at the source and let me know what isn't quite right, that'd be great.
EDIT
Here's the final result for this example. Some logistics to work out, but what I'm after.
http://geerswitch.in/tests/obj/
As for the jQuery creating nodes, the built in JS version works fine for this, and some research on Google shows that the non-jquery way is faster in most cases anyway (and looks worse, imo)
You're doing it almost right. You've created a Box class to represent your higher-order UI element, you're instantiating it for each element, and your main program is manipulating the elements through its interface. The only thing you're missing is the split between the public interface and the private implementation. There's nothing to prevent me from doing myBox.price += 10 right now, even though the Box interface clearly implies that price should be set at construction and never modified.
JavaScript doesn't have visibility modifiers like "private" and "public", but you can create the same effect yourself. Check out Douglas Crockford's explanation for the details. Crockford is an opinionated genius when it comes to JavaScript, and he's the brains behind JSLint and JSON.