I'm trying to figure out how to set the markers to be a certain colour depending on what the value of the point is. So for example, if a point has a value between 0.1 and 1, I want the marker colour to be red.
This is how I'm initializing my chart:
this.chart = Anychart.line()
let dataSet = Anychart.data.set(this.graphData.data)
let mapping = dataSet.mapAs({x: "day", value: "risk"})
this.series = this.chart.line(mapping)
How do I apply individual marker styles to points that belong to the same series?
Mockup of what I mean:
Series markers don't support conditional filling via the function. There are two available solutions:
Create additional marker series. It supports conditional coloring via a function, for details check the live sample.
Use line series markers, but apply individual marker setting in the data. This approach is demonstrated in the live sample.
Related
In LightningchartJS Pie chart can we change the logic for value redistribution. For example, consider the chart in image 1. If I hide a certain region say Planning, then the percentage of values is equally distributed in all the other regions see image 2. Is there a way in which I can customise this distribution of values?
You can customize the labels by using the .setLabelFormatter() method.
You can check the Slice LabelFormatter from the LightningChart JS API documentation for an example on how to use a custom implementation.
Distributing values of hidden slices
If you want to instead redistribute the value of a hidden slice, it is possible but trickier as Pie Chart does not have this feature natively.
This can be done by adding the desired functionality to the legendBox's buttons instead.
After creating the legendBox, you can add specific slices instead of adding the whole PieChart, then modify the behavior when clicking on each entry.
// Add a legendBox UI element
const legendBox = chart.addLegendBox()
// Add the slices to the legendBox separately, so we can use custom behavior when clicking on the entries
const entry = legendBox.add( slice1 )
entry.onSwitch((_, state) => {
// If the entry's state is true after clicking, restore everything to normal
if(state) {
slice1.restore()
slice2.setValue(120)
// Else, hide the slice the entry is linked to, and distribute its value to another slice
} else {
slice1.dispose()
slice2.setValue(160)
}
}
I would like to create a d3-based plot which graphs a plot within a tooltip. Unfortunately, I haven't found any examples on the web. Here is a sample JSON file.
[{"x":[0.4],
"y":[0.2],
"scatter.x":[0.54,0.9297,0.6024,-1.9224,2.2819],
"scatter.y":[0.4139,1.1298,-0.1119,2.3624,-1.1947]},
{"x":[0.1],
"y":[0.9],
"scatter.x":[-0.8566,-0.5806,-0.9326,0.8329,-0.5792],
"scatter.y":[-0.5462,-0.7054,1.0264,-3.4874,-1.0431]}]
The idea is to have a scatter plot for (x,y) coordinates first. However, when one mouses over a point, a different scatter plot within a tooltip appears based on [scatter.x, scatter.y] coordinates for that respective point.
I can do the scatter plots separately but have been struggling to put them together. Could anyone shed some light on this and/or provide a minimal example?
This was too long for a comment but I'm not certain if it's the answer you were looking for. One of the issues you might find is that your nested data is formatted differently-- one uses JSON objects with x and y, while the other uses two arrays of points.
My solution to this would be to create an extensible function:
function makeScatterPlot(elem, width, height, data, fill)
elem, width, height, and data are the core parameters: which element to attach the chart to, the size of the chart, and the data for the chart (in the JSON object format).
This function would generate all necessary items for the chart and add the chart to the provided element.
Then you want to bind to mouseover of your main chart, and in that function you'll have to do a bit of data modification to re-organize the two arrays into the JSON object structure.
function mainMouseover(d){
var newData = [];
for (var i = 0; i < d["scatter.x"].length; i++){
var t = {x: [0], y: [0]};
t.x[0] = d["scatter.x"][i];
t.y[0] = d["scatter.y"][i];
newData.push(t);
}
var newG = mainG.append("g").attr("transform", "translate(200,200)");
makeScatterPlot(newG, 100,100, newData, "red");
}
Of course, you would modify the translate to match wherever you want your tooltip to be.
Putting this all together you get the following (very crude) fiddle. Hover over either of the black dots to see the sub-chart. Obviously this needs quite a bit of work to be a solid example (i.e. remove the sub-chart on mouseout), but hopefully it will set you in the right direction.
If the tooltip chart is significantly different styling-wise compared to your main chart it may not be the best idea to use an extensible function, and you could just create another custom function instead.
I'm having issues setting pie slice colors using a d3.pieChart. Documentation and examples I've seen use the colors method in combination with an array of hex colors. However, setting this results in my pie chart being colored white (invisible) and every item in the legend becoming black.
I've tried using .colors with an array of five and an array of six colors but the issue persists. Could this be due to some issue with the slicesCap?
Code snippet below, but category10 burns my eyes so any advice on implementing a custom color set would be appreciated!
pie
.slicesCap(5)
.legend(dc.legend().gap(3))
.colors(d3.scale.category10())
Just passing an array of colour values doesn't work because the .colors() function is expecting a color scale like the one created by d3.scale.category10(). Scales are functions which take input data and return a value; in this case, the returned value is one of 10 colours.
For starters, you could try one of the other d3 built-in colour scales, which don't have as extreme contrast:
https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-category20
If none of those suit, you can make your own scale function with
var colorScale = d3.scale.ordinal().range([/*array of hex values */]);
pie.colors(colorScale);
You can create the array yourself or use one of the colorBrewer functions.
If you want to specify particular colours for particular values (instead of just assigning the colours to values in the order they appear) you'll need to (a) specify the domain of the scale as an array of values that matches the order of the range array, and (b) create a helper function that passes in the correct property from your data:
var colorScale = d3.scale.ordinal().domain(["banana", "cherry", "blueberry"])
.range(["#eeff00", "#ff0022", "#2200ff"]);
pie.colors(function(d){ return colorScale(d.fruitType); });
You can assign colors to particular values like this.
var colorScale = d3.scale.ordinal()
.domain(["banana", "cherry", "blueberry"])
.range(["#eeff00", "#ff0022", "#2200ff"]);
pie.colors(colorScale.range())
.colorAccessor(function(d){ return colorScale.domain().indexOf(d.fruitType); });
This solution is a little bit hacky, but I couldn't get it to work using only chart.colorDomain, and calling a function in chart.colors seems to be throwing errors now.
Riffing off Tayden's answer, there is slightly different syntax for newer versions of d3 (i.e. "scaleOrdinal")
var colorScale = d3.scaleOrdinal()
.domain(["banana", "cherry", "blueberry"])
.range(["#eeff00", "#ff0022", "#2200ff"]);
I have a scatter series with two points that have the same coordinates. Each point has different data associated with it (for example weight and height of different people - two different people can have exactly the same height and weight):
series: [ {
data: [{x:193.5, y:80.7, name:'danny'},
{x:193.7, y:90.7, name:'oren'},
{x:193.7, y:90.7, name:'josef'},
{x:195.5, y:80.3, name:'thomas'}]
}]
Full example at jsfiddle.
When viewing the tooltips of the chart, the tooltip of the second point shows:
Oren: 193.7,90.7
Making the data of josef inaccessible.
I would like to make the data of both josef and oren accessible, for example by putting them inside of the same tooltip.
Oren: 193.7,90.7
Josef: 193.7,90.7
How would you achieve this effect?
assume a very large data set - iteration over the entire series each time is not an option.
You could use the Tooltip formatter ( http://api.highcharts.com/highcharts#tooltip ) to manually format your tooltips.
In the formatter compare x and y value of all other points in the series(this.series) If the values are the same, add the name of these points to the tooltip.
I'm trying to use jvectormap to create a map of the US with markers. I want these markers to either be red or blue and I would like to specify which color goes to which marker manually (not using any sort of scale or overly complicated data visualization function). Is there a way to do this? The new jvectormap's API is way too abstract for me to easily implement this.
I've tried using the old jvectormap but it appears it is buggy and doesn't show the markers in the correct locations.
Here is an example of two different types of markers based on a third element in the list of markers called type. I essentially created another array called colors used for the values in the data series representation. The loop right before the map is created iterates through the list of markers and pulls out the type and decides what the color value should be based on the type.
for (var i = 0; i < markers.length; i++) {
if (markers[i].type == 'call-center') {
colors[i] = 0;
}
else {
colors[i] = 1;
};
};
Similar setups can be achieved for different types if you add additional if statements.