nvd3-community: Series colors when individual bars not colored in multiBarHorizontalChart - nvd3.js

Using (roughly if not exactly) the same code that worked when I used it with Novus' original nvd3.js, I'm unable to get bars in a multiBarHorizontalChart to use the colors I specify for the series. (The series are the groups indicated by the circles at the top right just above the chart.) Only when I specify the colors of individual bars can I get them to be colored something other than a shade of grey. Has the API changed or is nvd3.js broken in this respect?
I used both the novus-community zip download and a clone of the project yesterday.

This sounds like the bug fixed from this pull request.
Try the latest development branch build and see if that fixes your issue.

I skimmed the Github comment thread liquidpele referenced. It sounds like I now need to call chart.color(), even though the color is being provided via datum(), as below:
var chart0;
nv.addGraph(function() {
var chart0 = nv.models.multiBarHorizontalChart()
.height(123)
.margin({top: 0, right: 20, bottom: 50, left: 175})
.x(function(d) { return d.label })
.y(function(d) { return d.value })
.stacked(true);
chart0.yAxis
.axisLabel("ylabel")
.tickFormat(d3.format(',.2f'));
d3.select("svg")
.datum([{"color": "#133353", "values": [{"value": 1.0, "label": "mydatalabel"}], "key": "mydatakey"}])
.call(chart0)
.style({ 'height': 123 });
chart0.color();
nv.utils.windowResize(chart0.update);
return chart0;
});

Related

Placing Markers on Harp-GL globe

I try to build a globe with markers (like the markers on google maps) with HERE and harp.gl. These markers are SVG-Images and need to be loaded from their file.
They also need to be clickable with some metadata attached like an ID.
So my questions are:
what is the best way to display these markers?
how can I make them clickable? (raycasting?)
is there a way to attach some metadata?
thanks in advance!
Edit:
To clarify, the Markers are SVG-Images stored in SVG-Files which need to be loaded and displayed as Markers.
The Data is provided by an API and therefore I tried adding it as Point of it's own like the Cube-Example and also tried to translate it to GeoJSON and FeatureSets:
const geojsonPoints: {type: "FeatureCollection", features: Feature[]} = { type: "FeatureCollection",
features: [
]
};
for(let i = 0; i < locationdata.length; i++) {
geojsonPoints.features.push({
type: "Feature",
id: i.toString(),
geometry: {
type: "Point",
coordinates: [locationdata[i]["lonlat"][1], locationdata[i]["lonlat"][0]]
},
properties: locationdata[i]
})
}
const features: MapViewFeature[] = [];
for(let i = 0; i < locationdata.length; i++) {
features.push(new MapViewPointFeature([locationdata[i]["lonlat"][1], locationdata[i]["lonlat"][0]], locationdata[i]))
}
When I try adding a GeoJSON-Layer I get an error that the decoder.min.js couldn't be loaded but I configured it like that:
const mapView = new MapView({
canvas: this.canvas,
projection: sphereProjection,
theme: {
extends: pluginpath + "/js/harp.gl-example/dist/resources/berlin_tilezen_base_globe.json",
styles: {
geojson: this.getStyleSet()
}
},
decoderUrl: pluginpath + "/js/harp.gl-example/dist/decoder.bundle.js"
});
pluginpath is a variable containing prefix since the js-folder isn't directly in the root-directory like in all the examples.
To sum it all up:
I need to display the data provided by the API as markers. The markers should be the SVG-Images mentioned earlier and these markers should be clickable.
Edit 2:
I tried modifying this example to display the SVG-Markers.
The first step worked where I just displayed the cubes from the example at the needed locations, but I couldn't replace the cube with markers. I used these two documentations from three.js website but they didn't work for me:
https://threejs.org/docs/#examples/en/renderers/SVGRenderer
https://threejs.org/docs/#examples/en/loaders/SVGLoader
I didn't get any error the SVGs just didn't show up.
Just a quick note that in general, it's better to ask one question at a time. I'm going to focus on your first one about adding markers. Our tutorial has a section on adding markers, https://developer.here.com/tutorials/harpgl/#add-data. In the example, it assumes GeoJSON data. You didn't mention what kind of file you had so I don't know if it's GeoJSON or not.
I'd say - begin by describing what kind of file you have, how the data looks. Then look at the example I linked to in terms of adding markers. Then - share with us what you tried.
Loading SVGs directly is not supported but you could use base64 encoded svg images, e.g.:
const imageString =
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHdpZHRoPSI0OHB4IiBoZWlnaHQ9IjQ4cHgiIHZlcnNpb249IjEuMSIgaWQ9Imx1aS1pY29uLWRlc3RpbmF0aW9ucGluLW9uZGFyay1zb2xpZC1sYXJnZSIKCSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ4IDQ4IgoJIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQ4IDQ4IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPGc+Cgk8ZyBpZD0ibHVpLWljb24tZGVzdGluYXRpb25waW4tb25kYXJrLXNvbGlkLWxhcmdlLWJvdW5kaW5nLWJveCIgb3BhY2l0eT0iMCI+CgkJPHBhdGggZmlsbD0iI2ZmZmZmZiIgZD0iTTQ3LDF2NDZIMVYxSDQ3IE00OCwwSDB2NDhoNDhWMEw0OCwweiIvPgoJPC9nPgoJPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNmZmZmZmYiIGQ9Ik0yNCwyQzEzLjg3MDgsMiw1LjY2NjcsMTAuMTU4NCw1LjY2NjcsMjAuMjIzMwoJCWMwLDUuMDMyNSwyLjA1MzMsOS41ODg0LDUuMzcxNywxMi44ODgzTDI0LDQ2bDEyLjk2MTctMTIuODg4M2MzLjMxODMtMy4zLDUuMzcxNy03Ljg1NTgsNS4zNzE3LTEyLjg4ODMKCQlDNDIuMzMzMywxMC4xNTg0LDM0LjEyOTIsMiwyNCwyeiBNMjQsMjVjLTIuNzY1LDAtNS0yLjIzNS01LTVzMi4yMzUtNSw1LTVzNSwyLjIzNSw1LDVTMjYuNzY1LDI1LDI0LDI1eiIvPgo8L2c+Cjwvc3ZnPgo=";
This image can then be used in the style definition like this:
styles: {
geojson: [
{
when: ["==", ["geometry-type"], "Point"],
technique: "labeled-icon",
attr: {
text: ["get", "text"],
textMayOverlap: true,
size: 14,
imageTexture: "custom-icon",
screenHeight: 32,
iconScale: 0.5,
distanceScale: 1,
iconYOffset: 20
}
}
]
},
images: {
"custom-icon": {
url: imageString,
preload: true
}
},
imageTextures: [
{
name: "custom-icon",
image: "custom-icon"
}
]

How to add milestones in amCharts using dataLoader

Is there a way to implement new milestones via data feed from database? I checked the example below but couldn't figure out
https://www.amcharts.com/kbase/time-line-chart-date-based-milestones/
I use "dataLoader" to feed the values into graphs I can just create a new column in my table for the milestones question is how to update it?
The milestones in that example are guides, so they don't normally get updated in any process that modifies the chart's dataProvider. You can use the complete callback to create/update your chart guides:
AmCharts.makeChart("chartdiv", {
// ...
dataLoader: {
url: "...",
complete: function(chart) {
//add/modify guide objects through chart.valueAxes[0].guides or
//directly to the chart object through chart.guides
chart.valueAxes[0].guides = [{
"value": new Date(2016, 2, 5),
"label": "MILESTONE #1",
"position": "top",
"fontSize": 15,
"tickLength": 15
},
// .. etc
];
chart.validateData(); //redraw chart
}
},
// ...
});

How to set C3JS tooltip content

I have a situation similar to the example shown in http://c3js.org/samples/data_json.html My simple intention is to get the name of the row (i.e. 'www.site1.com') into the tooltip header. My problem: I cannot find it in the d-values.
Can anyone help?
You cannot find it in d-values, because it's not a value actually - it's a category.
Have a look at Category Axis example, maybe it helps you:
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250, 50, 100, 250]
]
},
axis: {
x: {
type: 'category',
categories: ['cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6', 'cat7', 'cat8', 'cat9']
}
}
});
I solved it by using the d-value to address the right category of my JSON, or rather the array in my JSON. (Seemed more complicated since I load the data after I create the chart.)

Arrow overlaps connection

I use JsPlumb to connect various div. The options i use for connection is as follows,
var option = {
anchors: ["RightMiddle", "Bottom"],
connectorStyle: { strokeWidth: 0.5, stroke: "#243CA8"},
connector: ["Flowchart", { stub: [35, 70], midpoint: 0, cornerRadius: 1 }],
paintStyle: { stroke: "#243CA8", strokeWidth: 30},
overlays: [["Arrow", { location: 1, width: 65, length: 32 }]]
};
But the arrow overlaps on connector and output is not looking good.
I also tried setting overlay options 'location:-1' but still does not make any difference and also tried setting 'gap:10' for connector but it applies for both arrow overlay and connector by which the problem is still same but with space between element and connector. I cannot find anyother solution. Can anyone please suggest a solution. Thanks!
I was trying different options and accidentally came across the solution which is mentioned nowhere.
I just changed the 'location: 1' option of overlays to 'location: [0,1]' and it worked. Had no idea it was possible and it is mentioned nowhere. This is to help those who are struggling with the same issue!

Do zoomable graphs need different data sets for every zoom level?

Say you have a bar chart graphing the number of page views based on the day of the month it was viewed. You could represent the data like so:
var data = [ { date: '05-05-2011', count: 6 }, { date: '05-06-2011', count: 10 } ... ]
The bar chart might look something like this: http://i.imgur.com/kj2IPWH.png
Now say you want to "zoom out" of this chart and see views by month. The chart might look like this: http://i.imgur.com/uwoLLBG.png
My question: does the data need to change such that it would be like
var data = [ { date: '05-2011', count: 100 }, { date: '06-2011', count: 131 } ... ]
or does d3 have some capability to scale the bars based on the more fine-grained data?
Check out the example here: http://bl.ocks.org/mbostock/1667367
The code that does the re-sampling is in this section:
function brushed() {
x.domain(brush.empty() ? x2.domain() : brush.extent());
focus.select("path").attr("d", area);
focus.select(".x.axis").call(xAxis);
}
Apologies if this is not exactly what you was looking for!

Resources