How do I dynamically create CartoCSS for a choropleth with CartoDB - cartodb

I am trying to create choropleth map with CartoDB using the JS library.
How can I dynamically create the cartoCSS on a layer?
It seems possible based on column?
For example using the built in wizard the following was generated. I want to somehow dynamically generate this using custom colors and column names on the frontend.
#mytable{
polygon-fill: #FFFFB2;
polygon-opacity: 0.8;
line-color: #FFF;
line-width: 0.5;
line-opacity: 1;
}
#mytable [ col_xyz <= 12505.969707] {
polygon-fill: #B10026;
}
#mytable [ col_xyz <= 3650.909837] {
polygon-fill: #E31A1C;
}
#mytable [ col_xyz <= 1656.60976] {
polygon-fill: #FC4E2A;
}
#mytable [ col_xyz <= 677.226857] {
polygon-fill: #FD8D3C;
}
#mytable [ col_xyz <= 333.140676] {
polygon-fill: #FEB24C;
}
#mytable [ col_xyz <= 170.576913] {
polygon-fill: #FED976;
}
#mytable [ col_xyz <= 51.090065] {
polygon-fill: #FFFFB2;
}
http://docs.cartodb.com/cartodb-platform/cartodb-js.html#sublayersetcartocsscss

Yes - you'll want to use the createLayer method, making each of the polygons its own sublayer...
cartodb.createLayer(map, {
user_name: 'mycartodbuser',
type: 'cartodb',
sublayers: [{
sql: "SELECT * FROM table_name",
cartocss: '#table_name {polygon-fill: #F0F0F0;}'
},
{
sql: "SELECT * FROM table_name",
cartocss: '#table_name {polygon-fill: #FFFFFF;}'
}]
})
.addTo(map)
.done(function(layer) {
//DO STUFF
});
Maybe there are better ways to do this, but it worked for me.
http://docs.cartodb.com/cartodb-platform/cartodb-js.html

Related

node-graphviz does not generate the expected png file

I am new to node-graphviz, which is a Node.js interface to the GraphViz graphing tool.
I want to draw a directed graph and save it into memory using the code:
var graphviz = require('graphviz');
var debug = true;
function draw (hbGraph) {
/** Create the digraph */
var vGraph = graphviz.digraph('Happens-Before-Graph'),
eventNodes = {};
/** Create nodes for digraph */
for (var i = 0; i < hbGraph.eventNodes.length; i++) {
/** Note, eventNodes is a sparse array */
var event = hbGraph.eventNodes[i];
if (event != undefined) {
var node = vGraph.addNode(event.id, {
'color': common.COLOR.GREY,
'style': common.STYLE,
});
eventNodes[node.id] = node;
}
}
/** Create edges for digraph, just ignore for this question */
if (debug) {
// Create digraph G
var g = graphviz.digraph("G");
// Add node (ID: Hello)
var n1 = g.addNode( "Hello", {"color" : "blue"} );
n1.set( "style", "filled" );
// Add node (ID: World)
g.addNode( "World" );
// Add edge between the two nodes
var e = g.addEdge( n1, "World" );
e.set( "color", "red" );
// Print the dot script
console.log( g.to_dot() );
// Set GraphViz path (if not in your path)
g.setGraphVizPath( "/usr/local/bin" );
// Generate a PNG output
g.output( "png", "test01.png" );
}
console.log( vGraph.to_dot() );
vGraph.setGraphVizPath( "/usr/local/bin" );
vGraph.output('png', 'test02.png');
}
After running the code, file test01.png is generated while file test02.png is not without any exception. Both two results of to_dot() methods are successfully printed on the console.
The printout of to_dot() method for test02.png is:
digraph Happens-Before-Graph {
"1" [ color = "grey" ];
"7" [ color = "grey" ];
"8" [ color = "grey" ];
"9" [ color = "grey" ];
"10" [ color = "grey" ];
"11" [ color = "grey" ];
"12" [ color = "grey" ];
"13" [ color = "grey" ];
"14" [ color = "grey" ];
}
I want to why file test02.png is not generated and how it can be generated. Could anyone help me?
In addition, the documenation about this library cannot be generated, so I am unfamiliar with it.
Additional information: link to node-graphviz is node-graphviz
The answer is just to remove the minus sign - in the digraph.
Since the documentation of node-graphviz cannot be built, I just post the right answer here.

SASS mixing and passing a variable string that's a function name

I'm expanding out a SASS mixin for generating background colours.
Here's my mixin:
#mixin color-columns ($count, $baseName, $startcolor) {
$loop_color : $startcolor;
#for $i from 0 through $count {
$loop_color : darken($loop_color, 8%);
.#{$baseName}-#{$i} {
background-color : $loop_color;
}
}
}
And i use it like this:
#include color-columns(5,'col', $blue);
What I want to do is pass in either 'darken' or 'lighten' as a variable so i can control with SASS colour function. Something like this:
#mixin color-columns ($count, $baseName, $startcolor, $change: 'darken') {
$loop_color : $startcolor;
#for $i from 0 through $count {
$loop_color : $change($loop_color, 8%);
.#{$baseName}-#{$i} {
background-color : $loop_color;
}
}
}
When i try that, my CSS for the first column is like this:
background-color: darken darken #005387, 8%, 8%;
I'm missing the connection on passing a variable that swaps the function.
Currently there is no support for defining dynamic function names. It has been requested several years ago and there is even an open pull request for this functionality but it is not yet merged.
However, it is possible to dynamically call a function with the built-in call($function, $args...) function. It allows you to avoid if-else cascades and can be used in your example like this:
$loop_color : call($change, $loop_color, 8%);
I ended up adding an #if to get this to work:
#mixin color-columns ($count, $startcolor, $start : darken) {
$loop_color : $startcolor;
#if $start == 'lighten' {
#for $i from 0 through $count {
$loop_color : lighten($loop_color, 5%);
.conBG-#{$i} {
background-color : $loop_color;
}
}
}
#else {
#for $i from 0 through $count {
$loop_color : darken($loop_color, 5%);
.conBG-#{$i} {
background-color : $loop_color;
}
}
}
}

Ckeditor : stylesSet not working when i set a custom allowedContent

In my Ckeditor config i have a custom allowedContent. I don't use allowedContent:true because i don't want to allow the style attribute in the span tags
So this is my allowedContent
allowedContent : 'span[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
With this configuration, the style attributes are not allowed anymore on the span tags
The problem is with my stylesSets :
stylesSet:
- { name: "style 1", element: ['div', 'p', 'a', 'span'], attributes: { class:"display_only_in_popup" } }
- { name: "style 2", element: ['div', 'p', 'a', 'span'], attributes: { class:"blockquote" } }
- { name: "style 3", element: ['div', 'p', 'a', 'span'], attributes: { class:"note" } }
- { name: "style 4", element: ['p', 'span'], attributes: { class:"highlight" } }
- { name: "style 5", element: 'span', attributes: { class:"visuallyhidden" } }
Before, when i had allowedContent:true, i was able to see and use all of my 5 stylesets, but now, for some reason, i only see the "style 5" in the Styles field
Is it possible to keep my 5 stylesets without using allowedContent:true?
Thanks a lot
It seems that your 5 stylesets all use the class attribute, but your allowedContent rule only allows the class attribute for the span elements.
I suggest changing the allowedContent rule to:
allowedContent : '*[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
or if you want to be more explicit:
allowedContent : 'div[class]; p[class]; a[class]; span[class]; a[!href](*); caption; div; em; h1; h2; h3; h4; h5; h6; hr; i; img; li; ol; p[*]{*}; pre; strong; sub; sup; table; thead; tbody; tfoot; td; th; tr; tt; u; ul; dl; dt; dd; iframe;'
Please refer to the documentation here.
Note: I was not able to test this code, please let me know in the comments if it does the job.

Angular2 and D3.js Gantt chart

I have an angular2 app which i am attempting to implement a Gantt chart from d3.js into. I am trying to use the following example http://bl.ocks.org/dk8996/5538271. obviously this uses javascript rather than typescript. However i have got most of it seeming ok, but i get one issue.
Here is my whole method:
createSchedule() {
var tasks = [{"startDate":new Date("Sun Dec 09 01:36:45 EST 2012"),"endDate":new Date("Sun Dec 09 02:36:45 EST 2012"),"taskName":"E Job","status":"RUNNING"}];
var taskStatus = {
"SUCCEEDED" : "bar",
"FAILED" : "bar-failed",
"RUNNING" : "bar-running",
"KILLED" : "bar-killed"
};
var taskNames = [ "D Job", "P Job", "E Job", "A Job", "N Job" ];
tasks.sort(function(a,b) {
return a.endDate.getTime() - b.endDate.getTime();
});
var maxDate = tasks[tasks.length -1].endDate;
tasks.sort(function(a,b) {
return a.startDate.getTime() - b.startDate.getTime();
});
var minDate = tasks[0].startDate;
var format = "%H:%M";
var timeDomainString = "1day";
var gantt = d3.gantt().taskTypes(taskNames).taskStatus(taskStatus).tickFormat(format).height(450).width(800);
gantt.timeDomainMode("fixed");
changeTimeDomain(timeDomainString);
gantt(tasks);
function changeTimeDomain(timeDomainString) {
this.timeDomainString = timeDomainString;
switch (timeDomainString) {
case "1hr":
format = "%H:%M:%S";
gantt.timeDomain([ d3.time.hour.offset(new Date(getEndDate()), -1), getEndDate() ]);
break;
case "3hr":
format = "%H:%M";
gantt.timeDomain([ d3.time.hour.offset(new Date(getEndDate()), -3), getEndDate() ]);
break;
case "6hr":
format = "%H:%M";
gantt.timeDomain([ d3.time.hour.offset(new Date(getEndDate()), -6), getEndDate() ]);
break;
case "1day":
format = "%H:%M";
gantt.timeDomain([ d3.time.day.offset(new Date(getEndDate()), -1), getEndDate() ]);
break;
case "1week":
format = "%a %H:%M";
gantt.timeDomain([ d3.time.day.offset(new Date(getEndDate()), -7), getEndDate() ]);
break;
default:
format = "%H:%M"
}
gantt.tickFormat(format);
gantt.redraw(tasks);
}
function getEndDate() {
var lastEndDate = Date.now();
if (tasks.length > 0) {
lastEndDate = tasks[tasks.length - 1].endDate.getTime();
}
return lastEndDate;
}
}
The bit where i get the error is:
var gantt = d3.gantt().taskTypes(taskNames).taskStatus(taskStatus).tickFormat(format).height(450).width(800);
It says Property 'gantt' does not exist on type 'typeof d3'
I import my d3 as follows
import * as d3 from 'd3';
I dont have any errors anywhere else and i am struggling to track down the issue.
Any ideas?
EDIT
Also as a test to make sure d3 is working i implement a simple circle as follows:
d3.select("#scheduleDiv").append("svg").attr("width",50).attr("height", 50).append("circle").attr("cx", 25).attr("cy", 25).attr("r", 25).style("fill", "purple");
This works fine but the .gantt() does not
You are having that error because gantt() method is not part of the d3 library. It is imported from
<script type="text/javascript" src="http://static.mentful.com/gantt-chart-d3v2.js">
</script‌​> in your example.
If you can find the definition file of the gantt library you can add it. If not, you have to create a custom one like:
declare module d3 {
export function gantt(input:any, input2:any): any;
}

Using the same key for different if statements in the keypressed function - processing

I'm actually using Processing to check for entered values from the keyboard and take actions. Now the problem is that i would like to use the number "1" on the keyboard to take the two different action depending on an IF statement but the second condition doesn't seem to work. Pls, help me peruse this code as i don't know where i may be going wrong
void keyPressed() {
if(page=="buttons")
{
if(key == '1') {
text("This is the button page1", 30, 200);
}
if(key == '2') {
text("This is the button page2", 30, 200);
}
else if(page=="options")
{
if (key == '1') {
text("This is the options page", 100, 200);
}
}
There's a missing } before the else if. Also string comparison should be done with .equals instead of ==. Here's the fixed one
void keyPressed() {
if(page.equals("buttons")) {
if(key == '1') {
text("This is the button page1", 30, 200);
} else if(key == '2') {
text("This is the button page2", 30, 200);
}
} else if(page.equals("options")) {
if (key == '1') {
text("This is the options page", 100, 200);
}
}
}

Resources