This is my first question on here so please go easy :)
I am trying to implement some line graphs with rickshaw graphs, d3 and jquery UI.
I have some vertical tabs and have successfully gotten the charts to load from external html files.
There was a bit of documentation on Rickshaw but I couldn't find what I was specifically after so I will ask this kind community a few questions if that is ok?
Firstly when loading Tabs in jquery UI from external html files where should I put all of the javascript and css into the page that is embedded (see below historic.html) or into the parent page? I have tried both and they seem to work I was just wanting to know best practice.
<ul>
<li><div id="live-icon"></div>LIVE GRAPHS</li>
<li><div id="historic-icon"></div>HISTORIC DATA</li>
Secondly, I the x-axis on the graph is in milliseconds. I would like to append "ms" to the end of each of the x-axis "ticks". so the x-axis would read 50ms, 100ms, 150ms etc... Can this be done?
And lastly in Rickshaw they have that fan-dangled example (http://code.shutterstock.com/rickshaw/examples/extensions.html) that has all of the bells and whistles. It has two properties that I cannot find any information on.
perserve: true ? and another example has tickFormat and tickTreatment? Could someone please explain what these do.
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 900,
height: 500,
renderer: 'area',
stroke: true,
preserve: true,
Thankyou very much for your help.
Probably no longer relevant for the OP, but since it's still unanswered, I can answer the Rickshaw questions:
To append ms to the end of your ticks, you need to use the tickFormat option. In their tutorial, they set up the axis as follows:
var y_axis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
Here, they're setting up the tickFormat to be a default they've built in, but in reality, it can take anything that conforms to what d3's axis' tickFormat takes. tickFormat should be a function that accepts a number and outputs a string. You probably want something along the lines of
var y_axis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: function (d) { return d + ' ms'; },
element: document.getElementById('y_axis'),
} );
This will make the ticks simple be the number followed by ms.
This also happens to answer one part of the three part question that follows. The other two parts concern tickTreatment and preserve.
The short answer is that tickTreatment gets added as a class to the ticks. The reason that this is useful is for CSS styling, which Rickshaw takes advantage of. They have some presets you can use for this. The one they're using in that example is called glow, which adds a white glow around the text to make it readable on top of the graph.
preserve is an option that affects whether or not the data you provide is copied before it's used. The relevant section from Rickshaw's source is here:
var preserve = this.preserve;
if (!preserve) {
this.series.forEach( function(series) {
if (series.scale) {
// data must be preserved when a scale is used
preserve = true;
}
} );
}
data = preserve ? Rickshaw.clone(data) : data;
Basically, if you set preserve to true (it defaults to false), it'll make a copy of the data first.
Related
There are many examples of doing this in axml, but I would like to have a complete binding using code behind. To be honest, I would like to have NO axml, but seems like creating all the controls programmatically is a nightmare.
I first tried the suggestions at:
MvxListView create binding for template layout from code
I have my list binding from code-behind, and I get six rows (so source binding is working); but the cells itself does not bind.
Then at the following url:
Odd issue with MvvmCross, MvxListViewItem on Android
Stuart has the following comment: Have looked through. In this case, I don't think you want to use DelayBind. DelayBind is used to delay the binding action until next time the DataContext is set. In Android's MvxAdapter/MvxListItemView case, the DataContext is passed in the ctor - so DataContext isn't set again until the cell is reused. (This is different to iOS MvxTableDataSource).
So in essence, the only example I see shows DelayBind, which shouldn't work.
Can someone please show me some examples... thanks in advance.
Added reply to Comments:
Cheesebaron, first of all, a huge thank you and respect for all your contributions;
Now, why not use axml? Well, as programmers, we all have our own preferences and way of doing stuff - I guess I am old school where we didn't have any gui designer (not really true).
Real reasons:
Common Style: I have a setup where Core has all the style details, including what all the colors would be. My idea is, each platform would get the style details from core and update accordingly. It's easy for me to create controls with the correct style this way.
Copy-Paste across platform (which then I can even have as linked files if I wanted). For example, I have a login screen with web-like verification, where a red error text appears under a control; overall on that screen I have around 10 items that needs binding. I have already got iOS version working - so starting on Droid, I copied the whole binding section from ios, and it worked perfectly. So, the whole binding, I can make it same across all platform... Any possible error in my way will stop at building, which I think is a major advantage over axml binding. Even the control creation is extremely similar, where I have helpers with same method name.
Ofcourse I understand all the additional layout that has to be handled; to be honest, it's not that bad if one really think it through; I have created a StackPanel for Droid which is based on WP - that internally handles all the layouts for child views; so for LinearLayout, all I do is setup some custom parameters, and let my panel deal with it. Relative is a different story; so far, I have only one screen that's relative, and I can even make it Linear to reduce my additional layout code.
So, from my humble point of view, for my style, code-behind creation allows me to completely copy all my bindings (I do have some custom binding factories to allow that), copy all my control create lines; then only adding those controls to the view is the only part that is different (then again, droid and WP are almost identical). So there is no way I can miss something on one platform and all are forced to be the same. It also allows me to change all the styles for every platform just by changing the core. Finally, any binding error is detected during compile - and I love that.
My original question wasn't about NOT using axml... it was on how to use MvxListView where all the binding is done in code-behind; as I have explained, I got the list binding, but not the item/cell binding working.
Thanks again in advance.
Here is part of my LoginScreen from droid; I think it's acceptable amount of code for being without axml file.
//======================================================================================================
// create and add all controls
//======================================================================================================
var usernameEntry = ControlHelper.GetUITextFieldCustom(this, "Username.", maxLength: 20);
var usernameError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Username);
var passwordEntry = ControlHelper.GetUITextFieldCustom(this, "Password.", maxLength: 40, secureTextEntry: true);
var passwordError = AddErrorLabel<UserAuthorization, string>(vm => ViewModel.Authorization.Password);
var loginButton = ControlHelper.GetUIButtonMain(this);
var rememberMe = new UISwitch(this);
var joinLink = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var copyRightText = ControlHelper.GetUILabel(this, textAlignment: UITextAlignment.Center);
var copyRightSite = ControlHelper.GetUIButtonHyperLink(this, textAlignment: UITextAlignment.Center);
var layout = new StackPanel(this, Orientation.Vertical)
{
Spacing = 15,
SubViews = new View[]
{
ControlHelper.GetUIImageView(this, Resource.Drawable.logo),
usernameEntry,
usernameError,
passwordEntry,
passwordError,
loginButton,
rememberMe,
joinLink,
ControlHelper.GetSpacer(this, ViewGroup.LayoutParams.MatchParent, weight: 2),
copyRightText,
copyRightSite
}
};
I just came across a similar situation myself using Mvx4.
The first link you mentioned had it almost correct AND when you combine it from Staurts comment in the second link and just remove the surrounding DelayBind call, everything should work out ok -
public class CustomListItemView
: MvxListItemView
{
public MvxListItemView(Context context,
IMvxLayoutInflater layoutInflater,
object dataContext,
int templateId)
: base(context, layoutInflater, dataContext, templateId)
{
var control = this.FindViewById<TextView>(Resource.Id.list_complex_title);
var set = this.CreateBindingSet<CustomListViewItem, YourThing>();
set.Bind(control).To(vm => vm.Title);
set.Apply();
}
}
p.s. I have asked for an Edit to the original link to help others.
I am looking for some guidance on how to create SVG image composed of paths based on contour line data coming from (geo/topo)JSON and render it with d3.js.
This is an image of what I'd like to create essentially:
Ultimately, I'd like the image to be able to scale responsively, animate (draw in lines, change color interactively) the paths, and be able to swap out different data files to render other images.
I have looked through several guides, tutorials etc, but it seems I am missing some steps or implementing the wrong procedure thus far, so I thought I'd ask here. Thanks for any help.
I'm trying to clarify the best way to do this and figure out what I'm misinterpreting in terms of the capabilities/procedures in d3.js.
I'm creating contour lines from DEM (Digital Elevation Model) data by extracting contours in QGIS. To get the JSON from these I have tried saving as GeoJSON in QGIS, and converting Shapefiles (ESRI .shp) to GeoJSON in OGR2OGR. I have also tried using Node's Topojson (https://www.npmjs.org/package/topojson). For the most part, I've been able to get JSON files, although there might be something wrong with the way I'm converting them, or the original contour data coming from QGIS that makes it incompatible with what I've tried in d3.
The results that I have gotten when the JSON gets rendered basically look like black boxes (looks like improperly rendered polygons gone wild inside the svg container). If I change the fill color to none I see crazy lines all over. I read somewhere that TopoJSON has to be polygons not lines or polylines since it uses arcs, but I got the same results with GeoJSON.
I'm wondering if this is a problem with the way I've exported the contour lines from QGIS and converted to JSON, perhaps the projections are not lining up? There also might be some errors in the lines that were created automatically when converting, but I'm not sure how to fix these. As you can see in the example image, some of my contours are not closed loops because they extend beyond the boundaries of the area I have data for/want to show. Does it make sense that these are supposed to be rendered as polylines or paths?
Also a note, I am not particularly interested in the "geospaciality" of these lines in terms of their lat-long or geographic location in this project. Basically just using contour lines from real geographic data to display the line patterns.
Here is my code:
<script type="text/javascript">
var width = 500,
height = 500;
var svg = d3.select("#section-1-svg").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("contour.json", function(error, contour) {
console.log(contour);
});
var path = d3.geo.path()
.projection(d3.geo.mercator());
d3.json("contour.json", function(error, json) {
svg.selectAll("path")
.data(json.features)
.enter()
.append("path")
.attr("d", path);
});
</script>
So other than just getting this to render on a basic level, other questions are:
Will I be able to select individual lines to animate with for example stroke-dashoffset?
Does this source JSON still contain elevation data so I can color lines based on elevation?
Thanks for your help in getting me on track with this! I would appreciate anyone clarifying this for me and informing me on the best way to render this.
EDIT: Using the code from user1614080's example, I'm rendering the lines thus:
svg.selectAll("path")
.data(topo).enter()
.append("path")
.style("fill", "none")
.style("stroke", function(d, i) {
return interp(cScale(d.properties.ELEV));
})
.attr("d", path)
.each(function(d) {
d.totalLength = this.getTotalLength();
console.log(d.totalLength);
})
.attr("stroke-dasharray", function(d) { return d.totalLength + " " + d.totalLength;})
.attr("stroke-dashoffset", function(d) { return d.totalLength; })
.transition()
.delay(function(d, i) { return i * 200; })
.duration(4000)
.ease("linear")
.attr("stroke-dashoffset", "0");
});
But I can't get the effect I need (lines drawing in). They seem to fade in from small dashes instead of drawing the entire dash. I can see in browser that the stroke-dasharray and offset is being assigned correctly, just can't figure out why the transition is not respected.
Following on from what Lar's mentioned I can't really see anything wrong with what you've got there (except that you're two identical d3.json calls but this shouldn't be causing you problems).
The workflow you describe is more or less identical to what I've done before. The only thing that I can think of that might be causing you trouble (although not in the code you've presented) is that topojson's default does not preserve feature properties and you have to use the -p switch.
Anyway, I've been meaning t do a contour example for a while and this seemed like a good opportunity so I created one which you can see here. There's a fair bit of explanation in the code and readme so I hope this helps you along the way.
Once you get your vis working you will be able to create all sorts of interactions etc. For instance in my example you could highlight contours on mouseover events, using the something like the following:
.on("mouseover", highlight)
.on("mouseout", unhighlight(this, d)
function highlight(x) {
var s = d3.select(this);
s.style("stroke", "red");
}
function unhighlight(x,y) {
var old = y.properties.ELEV;
var u = d3.select(x);
u.style("stroke", function(d, i) {
return interp(cScale(old));
})
}
Hope this gets you going
I am currently in the process of turning a sudoku solving program into a GUI with scala.swing and running into some trouble with the use of different functions. That is to say, I have a function for completely solving the puzzle, another for offering a hint entry, and another that will reset the grid. The interface consists of 81 individual ComboBox'es (see: http://i.imgur.com/45vzpei.png) and three buttons that perform said functions. My problem is that, while the separate reactions/cases involved reference specifically which buttons/functions to listen to, any button will incite all of the functions. My code for each of the listeners/buttons looks something like the following
listenTo(solve,comb11,comb12,comb13,comb14,comb15,comb16,comb17,comb18,comb19,comb21,comb22,comb23,comb24,comb25,comb26,comb27,comb28,comb29,comb31,comb32,comb33,comb34,comb35,comb36,comb37,comb38,comb39,comb41,comb42,comb43,comb44,comb45,comb46,comb47,comb48,comb49,comb51,comb52,comb53,comb54,comb55,comb56,comb57,comb58,comb59,comb61,comb62,comb63,comb64,comb65,comb66,comb67,comb68,comb69,comb71,comb72,comb73,comb74,comb75,comb76,comb77,comb78,comb79,comb81,comb82,comb83,comb84,comb85,comb86,comb87,comb88,comb89,comb91,comb92,comb93,comb94,comb95,comb96,comb97,comb98,comb99)
reactions += {
case ButtonClicked(solve) =>
...[working code for solve function]...
}
(The 'comb##'s are the exhaustive 81 ComboBoxes and the 'solve' is the button that solves the whole puzzle.) If I get rid of all but one of the listener/reaction blocks of code, clicking the remaining button works perfectly. If I try to include two or all of the listener/reaction code blocks, then every button causes ALL functions to be performed, which is clearly confusing and undesirable.
Not sure I understand your problem. But if you use lower case names in pattern matching extraction, these are fresh variables, and have nothing to do with values of the same name defined elsewhere. So to react to the solve button, you need to match against the value solve which you can do by putting it in back ticks:
listenTo(allMyButtons: _*)
reactions += {
case ButtonClicked(`solve`) => // note the back ticks!
...[working code for solve function]...
}
Otherwise, why don't you just keep each reaction with each combo box?
val combos = Vector.tabulate(81) { i =>
new ComboBox(1 to 9) {
listenTo(this)
reactions += {
case ButtonClicked(_) =>
... // not important to check the button - we only listen to one!
}
}
}
There is also a shorter way of defining the reaction to a pressed button.
import swing.{MainFrame, FlowPanel, Button}
val frame = new MainFrame {
contents = new FlowPanel {
contents += Button("solve")(println("solve"))
}
visible = true
}
I'm trying to create a fairly straightforward interface with Raphael, whereby if you click on a given path you'll get a corresponding div to appear. Since I'm likely going to be using irregular shapes I'll be creating the shapes in Illustrator and then converting to paths using readysetraphael.com, but if there's a better way to do it I'm open to that too.
I'm basically looking to capture the functionality you see here, but with raphael objects as the buttons.
http://jsfiddle.net/4xV7b/
Here's my current fiddle -- what I don't understand is what needs to happen during the mouseclick event to show/hide the corresponding divs.
el.click(function() {
//mysterious voodoo magic goes here
});
If you were using Raphael 2, you could use the data method to store arbitrary information with your elements -- as in this example.
Essentially, when you're creating each path, you simply call
el.data( 'div_id', 'greenthing' );
Then, when that element is clicked, you can retrieve the indicated div from the element using
el.click( function()
{
var div_id = this.data( 'div_id' );
// Display the div here. Josemando's approach is perfectly cool and will work universally.
} );
If you wanted to make sure that only one div at a time is displayed, you could do this (primitive but effective):
el.click( function()
{
rsr.forEach( function( subEl )
{
var divId = subEl.data('div_id' );
if ( divId && document.getElementById( divId ) )
document.getElementById( divId ).style.display = 'none';
} );
} );
There are, of course, other ways to skin that cat.
You may also find that your path construction code would be more manageable if you put all of the shape-specific data into a structured object and then render each path in a loop. The fiddle I've provided above demonstrates such a technique, which will pay off quickly once you have more than a handful of shapes.
You can use pure javascript to show a div:
document.getElementById("redthing").style.display = "block";
If you want animations, you can try using jQuery, or even manually creating them with css
i am using slideshow2 by Aeron Glemann in a website.Does in generate the thumbnails or do i have to provide them?the images iam showing are coming from a cloud, and are passed to the slideshow in an array.the thumbs exist in the cloud. how can i pass them in the array if the show cannot create them?
i have used the replace parameter with regex but it shows as thumbnails the full image and nothing happens when i alter the css properties for the thumbnails. the images are displayed.
here is the line for the show creation:
var myShow = new Slideshow('show', eval(res.value), { controller: true, height: 350,overlap: false, resize: false, hu: '',replace:[/^\S+.(gif|jpg|jpeg|png)$/,'t$1'],thumbnails: true, width: 600});
the value object contains the images from the cloud in format shown below:
['xx.jpg','yy.png',....]
thank you very much for your time.
I'd say your regular expression is broken. To add a 't' to the end of the filename? Try:
replace:[/^(\S+)\.(gif|jpg|jpeg|png)$/,'$1t.$2']
Best to play with the regular expression using an online tester to get it right.