I created a simple static network with D3plus. I want to have a working hyperlink in tooltip/legend which depends on the name of selected node?
So if the node name is "Berlin" I want a link to "https://en.wikipedia.org/wiki/Berlin"
How to do that?
Thanks
Using this example as a starting point for creating a large tooltip with clickable content, the "html" key can be passed a function which will get passed the id of the clicked data point:
var sample_data = [
{"value": 100, "name": "Berlin"},
{"value": 70, "name": "London"},
{"value": 40, "name": "Paris"}
]
function htmlContent(id) {
return "<a href='https://en.wikipedia.org/wiki/" + id + "'>Click Here</a>";
}
var visualization = d3plus.viz()
.container("#viz")
.data(sample_data)
.id("name")
.size("value")
.tooltip({"html": htmlContent})
.type("tree_map")
.draw();
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<div id="viz"></div>
Related
I've been working with few charts of amCharts 4, and everytime I struggled to subscribe to the event that returns the "selected/clicked" element. I don't know what I've been missing from the doc, but for example, I need to retrieve the selected item from "hit" event but i can't find anywhere (here is a simple i'd like to try this on https://codepen.io/team/amcharts/pen/erojQb)
var chart = am4core.create("chartdiv", am4charts.TreeMap);
chart.data = [{
"name": "First",
"value": 190
}, {
"name": "Second",
"value": 289
}, {
"name": "Third",
"value": 635
}, {
"name": "Fourth",
"value": 732
}, {
"name": "Fifth",
"value": 835
}];
/* Set color step */
chart.colors.step = 2;
/* Define data fields */
chart.dataFields.value = "value";
chart.dataFields.name = "name";
I tried this:
chart.seriesTemplates.template.columns.events.on('hit', function(ev) {
console.log('mlkmlz');
});
but not called, and this:
chart.seriesContainer.events.on('hit', function(ev) {
console.log(ev.target.dataItem)
});
but no dataItem attached
OK, so it's a bit more complicated than that. To attach events, you'll need to to actually create series for the specific level, then attach events on its column template:
var series = chart.seriesTemplates.create("0");
series.columns.template.events.on('hit', function(ev) {
console.log(ev.target.dataItem);
});
I'm trying to render SVG images at the back-end using d3 on PhantomJS. PhantomJS only returns a portion of the SVG (just the header).
What I've tried so far:
I ran the same script in the browser console and noticed that if I try to do alert(d3.select("#pieChart").html()) (see code below) immediately after running svgDrawer, it shows the exact partial SVG. But then the pie gets rendered on to the HTML, and running alert(d3.select("#pieChart").html()) again gives me the complete SVG.
Thinking that the rendering wasn't complete while I returned the value in PhantomJS, I split my method into two - svgDrawer and svgGrabber. But even then, svgGrabber returns partial SVG data when called from PhantomJS. Note that the same two methods, run serially in browser console, now shows the complete SVG
Please help. Thanks in advance.
Here is my boilerplate HTML code:
<!DOCTYPE html>
<html>
<head>
<script src="d3.min.js"></script>
<script src="d3pie.js"></script>
<meta charset="utf-8">
</head>
<body>
<div id="pieChart"></div>
</body>
</html>
and here is the javascript:
var fs = require('fs');
var page = require('webpage').create();
var url = 'file://' + fs.absolute('./d3.html');
var svgDrawer = function() {
var pie = new d3pie("pieChart", {
"header": {
"title": {
"text": "My pieChart"
}
},
"data": {
"content": [
{
"label": "slice 1",
"value": 60.9,
"color": "#8fbc8f"
},
{
"label": "slice 2",
"value": 8.7,
"color": "#dadde0"
},
{
"label": "slice 3",
"value": 30.4,
"color": "#c1d82f"
}
]
}
})
};
var svgGrabber = function() {
return d3.select("#pieChart").html()
};
page.open(url, function (status) {
page.evaluate(svgDrawer)
console.log(page.evaluate(svgGrabber));
phantom.exit();
});
and here is the command I use to generate the final SVG:
phantomjs d3_pie.js > d3_pie.svg
When I select any particular field in the bar graph, all the graphs changes accordingly.
I want to introduce a heading above the graphs which should show which data is currently displayed in the graphs and the count.
So what changes should I make in my code?
var data = [{
"city": "New York",
"neighborhood": "N/A",
"hits": 200
}, {
"city": "New York",
"neighborhood": "Brooklyn",
"hits": 225
}, {
"city": "New York",
"neighborhood": "Queens",
"hits": 1
}, {
"city": "San Francisco",
"neighborhood": "Chinatown",
"hits": 268
}, {
"city": "San Francisco",
"neighborhood": "Downtown",
"hits": 22
}, {
"city": "Seattle",
"neighborhood": "N/A",
"hits": 2
}, {
"city": "Seattle",
"neighborhood": "Freemont",
"hits": 25
}];
var pieChart = dc.pieChart("#pieChart"),
rowChart = dc.rowChart("#rowChart");
var ndx = crossfilter(data),
cityDimension = ndx.dimension(function (d) {
return d.city;
}),
cityGroup = cityDimension.group().reduceSum(function (d) {
return d.hits;
}),
neighborhoodDimension = ndx.dimension(function (d) {
return d.neighborhood;
}),
neighborhoodGroup = neighborhoodDimension.group().reduceSum(function (d) {
return d.hits;
});
pieChart.width(200)
.height(200)
.slicesCap(4)
.dimension(cityDimension)
.group(cityGroup);
pieChart.filter = function() {};
rowChart.width(500)
.height(500)
.dimension(neighborhoodDimension)
.group(neighborhoodGroup);
dc.renderAll();
<div id="pieChart"> </div>
<div id="rowChart"> </div>
For displaying the current filters, you can use spans with class='reset' andclass='filter'` within the charts, as demonstrated in the annotated stock example
For displaying the counts of records filtered, you can use the dataCount widget or the numberDisplay widget.
Anything else, you'll have to implement the display itself, probably hooking the filtered event to determine when the filters have changed, and changing your own div using e.g. d3 or jQuery.
I am working with Coldfusion and jqgrid.
Is there a way to populate the colModel editoptions dynamically from query results?
If you need to set dynamically the options like 1:female;2:male, then I suppose that you fill grid with data which contains 1 or 2 in the specified column. So you have to use formatter: "select" (see the documentation). Thus you should be able to set the properties like below
{name: "sex", formatter: "select", editoptions: { value: "1:female;2:male" }}
If you need to set such options dynamically, that you want to load the information about editoptions.value from the server.
The most native callback which you can use for it is beforeProcessing. The callback will be processed before the data returned from the server will be displayed using the formatter. So one can make any changes of formatoptions or editoptions.
If the server response looks now like
{
"rows": [
{"id": 123, "name": "John", "sex": "2"},
{"id": 456, "name": "Mary", "sex": "1"}
]
}
then you can extend the data of the server response to the following
{
"rows": [
{"id": 123, "name": "John", "sex": "2"},
{"id": 456, "name": "Mary", "sex": "1"}
],
"colModelExtentions": {
"sex": {"formatter": "select", "editoptions": {"value": "1:female;2:male"}}
}
}
In the way you specify some changes of specific items of the colModel directly inside of the server response. The implementation of the beforeProcessing callback which process such data can looks like
beforeProcessing: function (data) {
var cmName, cmExt = data.colModelExtentions, $self = $(this),
p = $self.jqGrid("getGridParam");
for (cmName in cmExt) {
// enumerate properties of colModelExtentions like sex
if (cmExt.hasOwnProperties(cmName)) {
$self.jqGrid("setColProp", cmName, cmExt[cmName]);
}
}
}
and to define the "sex" columns in colModel like
{name: "sex", width: 50}
You will find more details about the scenario in the answer and this one. You can extend the information which return the server. In the case you can need to call setColWidth or setLabel additionally to apply dynamically the column width and the text of the column header.
Can we use a kendo Template in the shapeDefaults Content template part in below code?
$("#diagram").kendoDiagram({
dataSource: [{
"name" : "Telerik",
"items": [
{"name": "Kendo", "items": [{"name": "Kendo", "items":[{"name":"abc"}]}]}
],
}],
shapeDefaults: {
content:{template: "#=item.name#"}, //Need to use a kendo template here
editable: true
}
});
Your code is correct but there is a bug in the Kendo code; the content visual is not added on redraw when using templates.
You can wait for next release or simply add it in the redrawVisual method, it should be;
redrawVisual: function() {
this.visual.clear();
this.shapeVisual = Shape.createShapeVisual(this.options);
this.visual.append(this.shapeVisual);
this.visual.append(this._contentVisual);
this.updateBounds();
}