codesuki / react-d3-components

D3 Components for React
http://codesuki.github.io/react-d3-components/example.html
MIT License
1.63k stars 206 forks source link

Multiple colored bars in Bar Chart #84

Closed csakis closed 8 years ago

csakis commented 8 years ago

Is it possible to set different fill colors in one Bar Chart for each bar? I am not talking about Bar Groups, just a simple Bar chart

codesuki commented 8 years ago

Should be possible. Let me check and come back to you. Sorry for the late reply!

codesuki commented 8 years ago

Could you give me more info about your data format? What are your X and Y values like? At the moment the code looks like fill={colorScale(label(stack))} so the color is decided by the label. That means if you change your data format that each has it's own label it would work out of the box. That might be troublesome to do though, so maybe, we could add a simpler way.

csakis commented 8 years ago

I usually have 4 columns. The data is like this {"Developer":4,"Admin":2,"Manager":0,"Other":3}

At the moment I render it like this:

barGraphData(results) {
        return Object.keys(results).map(function(choice) {
            return {
                label: choice,
                value: results[choice]
            };
        });
    },

<BarChart data={this.barGraphData(this.props.results)}
        title={this.props.currentQuestion.q}
        height={window.innerHeight * 0.6}
        width={window.innerWidth * 0.9}
                                />
codesuki commented 8 years ago

So you already did what I wrote above right :) Good, so basically what you would need is the color scale to correspond to x values instead of the label. I will see to make a small patch to support this. I guess it's useful for a lot of people.

csakis commented 8 years ago

If you could combine it with something like this d3.scaleCategory10() or d3.scaleCategory20() that would be awesome.

codesuki commented 8 years ago

The color scale you can pass yourself. The default one is one of those two. I will only adjust which key is used for the color.

codesuki commented 8 years ago

I added a new property to the BarChart called colorByLabel. If you set it to false it will use the X values in the color scale which will give you the required effect.

<BarChart colorByLabel={false} /> 

I checked again, the default colors cale in use is Category20, which you noted above. If you want you can use your own color scale by passing it.

<BarChart colorByLabel={false} colorScale={your d3 color scale} />

Hope this helps!

csakis commented 8 years ago

Thank you for your quick help. I tried to use it, but I get errors. Here is my bar chart code

var React = require('react');
var Display = require('./parts/Display');
var BarChart = require('react-d3').BarChart;
var Board = React.createClass({
    barGraphData(results) {
        return Object.keys(results).map(function(choice) {
            return {
                label: choice,
                value: results[choice]
            };
        });
    },
    render() {
        return (
            <div id="scoreboard">
                <Display if={this.props.status === 'connected' && this.props.currentQuestion}>
                    <BarChart data={this.barGraphData(this.props.results)}
                                colorByLabel={false}
                              title={this.props.currentQuestion.q}
                              height={window.innerHeight * 0.6}
                              width={window.innerWidth * 0.9}
                                />
                </Display>
                <Display if={this.props.status === 'connected' && !this.props.currentQuestion}>
                    <h3>Awaiting a Question...</h3>
                </Display>

            </div>
        );
    }
});
module.exports = Board;

I get these errors: Uncaught TypeError: Cannot read property 'values' of undefined Uncaught TypeError: Cannot read property '_currentElement' of null

I might have some errors in my package.json. These are my dependencies:

"dependencies": {
    "babel-core": "^5.8.12",
    "babel-loader": "^5.3.2",
    "bootstrap": "^3.3.5",
    "express": "^4.13.1",
    "react": "^0.14.6",
    "react-d3": "^0.4.0",
    "react-d3-components": "^0.6.2",
    "react-dom": "^0.14.6",
    "react-router": "^0.13.3",
    "socket.io": "^1.3.6",
    "socket.io-client": "^1.3.6",
    "underscore": "^1.8.3",
    "webpack": "^1.10.5"
  }

Could you please help? A full code example would be very nice Your example page seems to be down, too. http://codesuki.github.io/react-d3-components/example.html

Thanks again for the help.

codesuki commented 8 years ago

Most likely a problem with your data format. I'll whip up a sample. For me the example page works. Could you check again?

codesuki commented 8 years ago
screen shot 2016-01-20 at 2 45 14 pm
data = {
    label: "salaries",
    values: [{x: "Developer", y: 4},{x: "Admin", y:2},{x:"Manager", y:0},{x: "Other", y:3}]
};

ReactDOM.render(
<BarChart
    data={data}
    width={800}
    height={400}
    margin={{top: 10, bottom: 50, left: 50, right: 10}}
    colorByLabel={false}
/>,
document.getElementById('barchart'));

This uses the default fields, label, values, x,y. values should be an array of objects. You can provide custom getters in case you rename the fields like work instead of x or hours instead of y. Then you would make functions like this

var myXAccessor = function(element) { return element.work };
var myYAccessor = function(element) { return element.hours };

and then pass them to the chart via

<BarChart
x={myXAccessor}
y={myYAccessor}
/>

Hope that helps. More about the accessors is in the readme. Feel free to ask here though.

csakis commented 8 years ago

Your example page looks like this in my browser http://codesuki.github.io/react-d3-components/example.html

d3

csakis commented 8 years ago

I had to use

var BarChart = require('d3-components).BarChart;

Now it works very nicely. Thanks

codesuki commented 8 years ago

Oh yeah I didn't realize the import is wrong :) Somehow your browser can't download the react libraries from Facebook when loading the example page. Did you block the fb.me URL or something? No idea sorry. But glad it works now!