1
votes

sorry if there is already another question that can help me but I didn`t find it.

I have a database with persons in which the columns are id, name, gender, height and weight.

id,name,gender,height,weight
1,Kinsley,Male,168,90
2,Dimitry,Male,177,61
3,Martica,Female,152,76
4,Brittni,Female,156,88
5,Phillip,Male,161,78
6,Sofie,Female,161,71
7,Avril,Female,163,55
8,Allistir,Male,161,75
9,Emelda,Female,154,66
10,Camella,Female,153,52
11,Baudoin,Male,168,55
12,Ava,Female,180,52
13,Candida,Female,153,56
14,Curtis,Male,161,63
15,Mozelle,Female,167,59
16,Hermina,Female,180,90
17,Pammy,Female,159,55
18,Zechariah,Male,178,95
19,Kerwin,Male,150,69
20,John,Male,179,70
21,Shayne,Male,176,57
22,Hewie,Male,171,55
23,Murray,Male,179,54
24,Jarret,Male,158,76
25,Archer,Male,174,53
26,Emmy,Female,168,85

Here is how I fetch the data.

 d3.csv("/local-test-data/people_hw.csv",
      data => <IDataFromCsv>{
        id: +data["id"],
        gender: data["gender"],
        name: data["name"],
        height: +data["height"],
        weight: +data["weight"],
      }
    )
      .then((data: IDataFromCsv[]) => {
        this.sourceDataWDays = data;
        this.sourceDataWDays.forEach(d => {
          if (d.gender === "Male") {
            d.newData = 1;
          } else {
            d.newData = 2;
          }
        });
        return this.sourceDataWDays;
      })
      .then((data) => this.loadCharts(data))

  };

sourceDataWDays: IDataFromCsv[];

export interface IDataFromCsv {
  id: number,
  name: string,
  gender: string,
  height: number,
  weight: number,
  newData: number,
}

I`m using dc.js, d3.js, and crossfilter to create this dashboard and angular & typescript to create the web app.

I created 2 charts using, one bar chart that shows how many persons by gender I have in the database and another is a series chart (with 2 lines) that shows the weight of the persons. (x-axis the weight and y-axis for Male or Female) Everything fine until now. the bar chart

the line chart

What I want?

I want to overlap the charts. I want the second to be hidden if the first has no filter. If the first has 1 filter I want the bar one to get opacity for the bars (opacity: 01), hide the axis, and instead of its axis, I want the second one`s axis and the lines to pe over the bars.

Something like this but with the axis:

Something like this but with the axis

enter image description here

Here is my code so far:

  loadCharts(data: IDataFromCsv[]): void {

    let ndx: Crossfilter<IDataFromCsv> = crossfilter(data);

    this.loadWeightChart(ndx);
    this.loadGenderChart(ndx);

    dc.renderAll();
  };

  loadGenderChart(ndx: Crossfilter<IDataFromCsv>): void {

    this.genderChart = dc.barChart("#genderChart");

    let gDimension: any = ndx.dimension(d => d.gender);
    let gGroup: any = gDimension.group().reduceCount();

    this.genderChart
      .width(768)
      .height(480)
      .dimension(gDimension)
      .group(gGroup)
      .x(d3.scaleOrdinal())
      .colorAccessor((d, i) => i)
      .xUnits(dc.units.ordinal)
      .on("filtered.monitor", genderChart => {
        if (genderChart.filters().length === 1) {
          d3.select("#genderChart").selectAll("svg").style("opacity", "0.2");
          d3.select("#genderChart").selectAll("g .axis").style("visibility", "hidden");
          dc.redrawAll();
        } else {
          d3.select("#genderChart").selectAll("svg").style("opacity", "1");
          d3.select("#genderChart").selectAll("g .axis").style("visibility", "visible");
        }
      })
      .brushOn(false)
      .yAxisLabel("Count")
      .xAxisLabel("Gender")
  };

  loadWeightChart(ndx: Crossfilter<IDataFromCsv>): void {

    this.weightChart = dc.seriesChart("#weightChart");

    let wdDimension: any = ndx.dimension(data => { return [data.gender, data.weight] });
    let wdGroup: any = wdDimension.group().reduceCount();

    this.weightChart
      .width(800)
      .height(500)
      .chart(c => {
        return dc.lineChart(c)
      })
      .dimension(wdDimension)
      .group(wdGroup)
      .xAxisLabel("Weight")
      .yAxisLabel("Count")
      .elasticY(true)
      .brushOn(false)
      .x(d3.scaleLinear().domain([50, 100]))
      .seriesAccessor(d => d.key[0])
      .keyAccessor(d => +d.key[1])
      .valueAccessor(d => +d.value)
  };

and HTML

<div class="col-md-12">
  <div class="row">
    <div class="col-md-12" id="genderChart">
      <div class="forReset" style="margin:10px 0 -10px 0;">
        <a class="reset" (click)="resetGenderChart();" style="display: none;"><i class="fa fa-refresh"></i></a>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-md-12" id="weightChart">

    </div>
  </div>
</div>

Can I do it starting from what I did? how?

I don't care what kind of chart I'm using as long as I got what I need (the bar chart with the lines overlying). I`m beginner in dc.js & d3.js & cross filter. Thank you a lot!

1
I’m having some trouble visualizing what you are trying to do. One problem is that you keep referring to “bars” but these are line charts, so I guess you mean “lines”? Also, you say you want to “overlap” the charts, but you also say you want to hide one when the other is shown, so I guess you mean that you want to “replace” a chart and display another one in the same place? Finally, I don’t know what “opacity 01” means; this is usually percentage or a number from 0 to 1. Please edit your question and clarify it. - Gordon
Hi @Gordon, I'll try to make it simpler. I have 2 charts. One bar chart and the second one line chart. I want to overlap the charts: When I click on one of the bars from the bar chart to look like this or this. In the last 2 imgs I don`t have the axis because I set the bar chart axis to hidden because I want instead of them the line char axis. About the imgs from my post, you were right...I put there a line chart instead of a bar chart. - Cinc

1 Answers

0
votes

Drawing lines and bars in the same chart is achieved with the composite chart.

composite chart screenshot

If the bars have a different scale from the lines, you could use the right axis feature to draw both of them filling the height of the chart.

right axis screenshot

If needed, you could hide the right axis with CSS

.dc-chart g.axis.yr {
    visibility: hidden;
}