Simple barchart issue with dc.js d3.js and crossfilter

Hi I am trying to graph a simple set of data which shows funding for states of the United States. I would like to group by states and graph each states total funding.

Here is my attempt,

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF8">
  <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="../static/css/dc.css" media="screen" />
</head>

<body>
  <div>
    <h2>Bar Chart</h2></div>
  <div id="barchart"></div>
  <script>
    var data = [{
      state: "NJ",
      fund: 2811.59
    }, {
      state: "NC",
      fund: 449.98
    }, {
      state: "NY",
      fund: 174.53
    }, {
      state: "NC",
      fund: 500.32
    }, {
      state: "MD",
      fund: 420.87
    }, {
      state: "OR",
      fund: 2300.71
    }, {
      state: "PA",
      fund: 360.59
    }, {
      state: "NY",
      fund: 508.91
    }, {
      state: "PA",
      fund: 454.91
    }, {
      state: "PA",
      fund: 357.85
    }];

    var fundingBarChart = dc.barChart("#barchart");
    var ndx = crossfilter(data),
    stateDim = ndx.dimension(function(d) {
      return d.state;
    }),
    state_funds = stateDim.group().reduceSum(function(d) {
      return d.fund;
    });

    fundingBarChart
      .width(500).height(200)
      .dimension(stateDim)
      .x(d3.scale.linear().domain([0, data.length + 1]))
      .dimension(stateDim)
      .group(state_funds)
      .brushOn(false)
      .legend(dc.legend().x(50).y(10).itemHeight(13).gap(5))
      .yAxisLabel("Funding by State")
      .xAxisLabel("State")
      .elasticX(true);
    
    // dc.renderAll();
    fundingBarChart.render();

  </script>
</body>
</html>

Any help would be greatly appreciated.

Thanks,

I got to work by changing the data a little to,

var data = [{
  run: 1,
  state: "NJ",
  fund: 2811.59
}, {
  run: 2,
  state: "NC",
  fund: 449.98
}, {
  run: 3,
  state: "NY",
  fund: 174.53
}, {
  run: 2,
  state: "NC",
  fund: 500.32
}, {
  run: 4,
  state: "MD",
  fund: 420.87
}, {
  run: 5,
  state: "OR",
  fund: 2300.71
}, {
  run: 6,
  state: "PA",
  fund: 360.59
}, {
  run: 3,
  state: "NY",
  fund: 508.91
}, {
  run: 6,
  state: "PA",
  fund: 454.91
}, {
  run: 6,
  state: "PA",
  fund: 357.85
}];

and adding

  stateDim = ndx.dimension(function(d) {
    // return d.state;
    return d.run;
  }),
1 Like

Here is my attempt :wink:

<?php 
  $bars = 
  [ "0NJ" => 2811.59,
    "1NC" =>  449.98,
    "2NY" => 174.53,
    "3NC" =>  500.32,
    "4MD" =>  420.87,
    "5OR" =>  2300.71,
    "6PA" =>  360.59,
    "7NY" =>  508.91,
    "8PA" => 454.91,
    "9PA" => 357.85,
  ];

  $xy    = 555;
  $base  = 20 + 0.9  * $xy ;
  $space = $xy / count($bars);

  $i2  = 0;
  $col = '';
  foreach($bars as $state => $bar):
    $x    = intval($i2 * $space);
    $x1   = $x  + 20;
    $y2   = intval($base - $bar / 6);
    $col .= "\n" 
        .'<line '
        .'x1="' .$x1 .'" '
        .'y1="'. $base.'" '
        .'x2="' .$x1 .'" '
        .'y2="' .$y2 .'" '  
        .'/>'
        ."\n"
        .'<text x="'.$x1 .'" y="'.$y2   .'">' .$bar .'</text>'
        ."\n"
        .'<text x="'.$x1 .'" y="535">'  .substr($state,1) .'</text>'
        ."\n"
        ;
    $i2++; 
  endforeach;

  $svg = <<< ____SVG
    <svg  viewBox="0 0 $xy $xy"
      style="stroke:red; font-size:10px; stroke-width:1; stroke:blue; stroke-width:1; border:solid 1px red;"
      >
      $col
      <path d="M  10 555 V 555" stroke="red" stroke-width="3" fill="red"/>
      <path d="M  0 520 H 555"/>
    </svg>
____SVG;


?><!DOCTYPE html>
<html  lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>untitled document</title>
<style type="text/css">
div {width:50%; margin:auto;}
</style>
</head>
<body>
  <h2>Bar Chart</h2>
  <div>
    <?= $svg ?>
  </div>
</body>
</html>

Hi,

I see you are using php. I am using Javascript and the DC.js library.

I see you are pretty much doing it from scratch.

Thanks for your reply but I am happy with the way I got to work now, which is shown above.

Thanks,

1 Like

My JavaScript knowledge is very limited which is the reason I used PHP to read the data and output to SVG.

I checked the JavaScript file sizes:

 151,726   <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
  151,726  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    9.561  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crossfilter/1.3.12/crossfilter.min.js"></script>
   51,885  <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/dc/1.7.5/dc.min.js"></script>
  295,282  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js" type="text/javascript"></script>
*/

One library loaded twice and the total to download is well over half a Meg. Regardles of CDN’s it takes a very long time when using mobiles.

JavaScript is only required to read, loop through the results, apply a scale factor, append to a string then display the string inside the SVG block:

 <div>
   <svg  viewBox="0 0 555 555"
      style="stroke:red; font-size:10px; stroke-width:1; stroke:blue; stroke-width:1; border:solid 1px red;"
    >
      
  <line x1="20" y1="519.5" x2="20" y2="50" />
  <text x="20" y="50">2811.59</text>
  <text x="20" y="535">NJ</text>

  <line x1="75" y1="519.5" x2="75" y2="444" />
  <text x="75" y="444">449.98</text>
  <text x="75" y="535">NC</text>

  <line x1="131" y1="519.5" x2="131" y2="490" />
  <text x="131" y="490">174.53</text>
  <text x="131" y="535">NY</text>

  <line x1="186" y1="519.5" x2="186" y2="436" />
  <text x="186" y="436">500.32</text>
  <text x="186" y="535">NC</text>

  <line x1="242" y1="519.5" x2="242" y2="449" />
  <text x="242" y="449">420.87</text>
  <text x="242" y="535">MD</text>

  <line x1="297" y1="519.5" x2="297" y2="136" />
  <text x="297" y="136">2300.71</text>
  <text x="297" y="535">OR</text>

  <line x1="353" y1="519.5" x2="353" y2="459" />
  <text x="353" y="459">360.59</text>
  <text x="353" y="535">PA</text>

  <line x1="408" y1="519.5" x2="408" y2="434" />
  <text x="408" y="434">508.91</text>
  <text x="408" y="535">NY</text>

  <line x1="464" y1="519.5" x2="464" y2="443" />
  <text x="464" y="443">454.91</text>
  <text x="464" y="535">PA</text>

  <line x1="519" y1="519.5" x2="519" y2="459" />
  <text x="519" y="459">357.85</text>
  <text x="519" y="535">PA</text>

  <path d="M  10 555 V 555" stroke="red" stroke-width="3" fill="red"/>
  <path d="M  0 520 H 555"/>
</svg>
</div>

The SVG block resizes to the parent DIV dimensions or saved as an SVG file and rendered as a HTM image.

SVG filesize: 1,422 Kb before optimisation :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.