Multiplot and change line color depending on colum

2019-07-16 20:31发布

问题:

Background information:

I want to port a gnuplot graph to Zingchart. I include the gnuplot source to better explain my objective:

reset
set autoscale
set term canvas rounded solid butt size 1000,600 enhanced fsize 10 mousing lw 1 fontscale 1 jsdir "/home/eballes/Work/js"
set output 'html/data.html'
set grid
set yr [0:39]
set title 'State'
set xdata time
set xlabel "Time"
set ylabel "Element ID"
set timefmt "%s"
set format x "%d %H:%M"
set pointsize .25
set palette model RGB maxcolors 7
set palette model RGB defined (1 "#0000FF", 2 "#0000FF", 2 "#00FFFF", 3 "#00FFFF", 3 "#FF7F50", 4 "#FF7F50", 4 "#FFFF00", 5 "#FFFF00", 5 "#EE82EE", 6 "#EE82EE", 6 "#00FF00", 7 "#00FF00", 7 "#FF0000", 8 "#FF0000")
set cbrange [1:8]
plot "data.dat" u 1:2:3 notitle w points pt 5 ps .1 palette

The data file I am plotting is the following, being the first column the unix timestamp, the second column the ID of the element and the third column the status:

1446246146  22  6
1446246146  20  1
1446246146  11  6
1446246146  24  1
1446246146  30  1
1446246146  14  1
1446246146  18  1
1446246147  22  6
1446246147  20  1
1446246147  11  6
1446246147  24  1
1446246147  30  1
1446246147  14  1
1446246147  18  1
1446246148  22  6
1446246148  20  1
1446246148  11  6
1446246148  24  1
1446246148  30  1
1446246148  14  1
1446246148  18  1
1446246149  22  6
1446246149  20  1
1446246149  11  6

And the result will plot the value of the ID (which is constant, so it's a line) and the color will depend on the third column and is according to the palette defined. It will look like this:

As you can see the result is satisfactory but the format of the input data is very inefficient and the plot itself is sort of a hack. I bet there are better ways to get something similar in gnuplot too.


Problem:

I want a similar (better) plot made with Zingchart.

Now, I have freedom to modify the CSV input at will and my first attempt was to try starting from the stacked bar pattern to plot the duration of a given status. However, I couldn't figure out how to plot the time in the Y-Axis correctly (not starting at 0) or how to change the color of the bar depending of a value in a different column instead of assigning a style class as done in the JavaScript example of the documentation:

            {
                "values":[null,3,null,null,null],
                "class":"green"
            },

So at last I've attempted to recreate my old gnuplot approach directly to Zingchart and I'm also lost. I don't know how to avoid Zingchart from plotting every column or to change the line color depending on values of different columns.


Question:

Assuming that this is not an XY Problem...

In Zingchart, given a CSV file, how can I plot one column depending on/modified by a second one which is not to be plotted?

回答1:

Full Disclosure, I'm a member of the ZingChart team. It sounds like what you need to do with ZingChart is leverage our rules. Adding the rules attribute to our plot object will check every node against these defined set of rules. Here's a small snippet of code that will change the backgroundColor of your bars based on the value of that node.

 plot:{
  rules:[
    {
      //if value is between 5 and 7 change background color
      rule:'%v > 5 && %v < 7',
      backgroundColor:'#69F0AE' // bright green
    }
  ]
}...

Based on your question we want to check each bar against a certain value, not necessarily the value of that bar. You can do this by creating custom tokens which are created in the series object with a starting prefix 'data-' to define the token. You can name the token anything you want. You can pass the custom token an array that is the same length as the values you passed in, which in your case will be column two of your csv file. Check it out.

series : [
    {
        values : [
        [1451692800000,5],
        [1451779200000,10],
        [1451865600000,3],
        [1451952000000,1]
        ],
    },
    {
        values : [
        [1451692800000,2],
        [1451779200000,5],
        [1451865600000,4],
        [1451952000000,9]
        ],
    },
    {
        values : [
        [1451692800000,3],
        [1451779200000,6],
        [1451865600000,9],
        [1451952000000,1]
        ],
        'data-customValue':[1,6,3,4,6] //custom made tokens can be accessed in the rules above. This token only applies to this series, you would have to add it to the others for it to be defined
    }]

Once you have defined your token you can access that token in your rules and adjust the bar color based on that custom token value. I have made a full demo which incorporates a stacked bar chart, plotted with timestamp values and adjust some of the bar colors based on value and custom token values. If I didn't answer your question in the correct way please email us directly for support help: support@zingchart.com. You can check out our help center or come to our site and try and reach us through the chat. Thanks for your time!

var myConfig = {
 	type: "bar",
 	utc:true,
 	title: {
 	  text: 'Stacked Timestamp With Custom Values And Rules'
 	},
 	scaleX:{
 	  transform:{
 	    type:'date',
 	    all:'%D, %d %M %Y'
 	  },
 	  minValue:1451606400000, // Jan 1
 	  step:'day'
 	},
 	plot:{
 	  stacked:true,
 	  barWidth:40,
 	  rules:[
 	    {
 	      //if value is between 5 and 7 change background color
 	      rule:'%v > 5 && %v < 7',
 	      backgroundColor:'#69F0AE' // bright green
 	    },
 	    {
 	      //if custom token value is less than 5 change background color
 	      rule:'%data-customValue <= 5',
 	      backgroundColor:'#E040FB' // bright purple
 	    }
 	  ]
 	},
	series : [
		{
			values : [
  			[1451692800000,5],  //Jan 2
  			[1451779200000,10], //Jan 3
  			[1451865600000,3],  //Jan 4
  			[1451952000000,1]   //Jan 5
			],
		},
		{
			values : [
  			[1451692800000,2],
  			[1451779200000,5],
  			[1451865600000,4],
  			[1451952000000,9]
			],
		},
		{
			values : [
  			[1451692800000,3],
  			[1451779200000,6],
  			[1451865600000,9],
  			[1451952000000,1]
			],
			'data-customValue':[1,6,3,4,6] //custom made tokens can be accessed in the rules above. This token only applies to this series, you would have to add it to the others for it to be defined
		},
	]
};

zingchart.render({ 
	id : 'myChart', 
	data : myConfig, 
	height: 400, 
	width: '100%' 
});
<!DOCTYPE html>
<html>
	<head>
	<!--Assets will be injected here on compile. Use the assets button above-->
		<script src= "https://cdn.zingchart.com/zingchart.min.js"></script>

	<!--Inject End-->
	</head>
	<body>
		<div id='myChart'></div>
	</body>
</html>